Làm cách nào để chuyển đổi nano giây thành giây bằng enum TimeUnit?


145

Làm cách nào để chuyển đổi giá trị từ nano giây sang giây?

Đây là đoạn mã:

import java.io.*;
import java.util.concurrent.*; 
..

class Stamper { 

public static void main (String[] args) { 
long start = System.nanoTime(); 
//some try with nested loops 
long end = System.nanoTime(); 
long elapsedTime = end - start;

System.out.println("elapsed: " + elapsedTime + "nano seconds\n");

//convert to seconds 
TimeUnit seconds = new TimeUnit(); 
System.out.println("which is " + seconds.toSeconds(elapsedTime) + " seconds"); 
}}

Lỗi là

Stamper.java:16:  enum types may not be instantiated.

Điều đó có nghĩa là gì?


4
Lỗi có nghĩa là bạn không thể khởi tạo loại TimeUtil, vì đó là một enum(liệt kê). Nếu bạn muốn sử dụng TimeUnit, bạn nên sử dụng TimeUnit.NANOSECONDS.toSeconds(elapsedTime)thay thế. Chúc may mắn!
Daniel Kvist

Câu trả lời:


200

Chà, bạn chỉ có thể chia cho 1.000.000.000:

long elapsedTime = end - start;
double seconds = (double)elapsedTime / 1_000_000_000.0;

Nếu bạn sử dụng TimeUnitđể chuyển đổi, bạn sẽ nhận được kết quả của mình trong một thời gian dài, do đó bạn sẽ mất độ chính xác thập phân nhưng duy trì độ chính xác của toàn bộ số.


78
Nhưng nếu số lượng nano giây trong một giây thay đổi thì sao? : P
geofftnz

9
Câu trả lời này bây giờ đã sai - convert()và các toFoo()phương pháp tất cả trở lại longtại s docs.oracle.com/javase/6/docs/api/java/util/concurrent/...
Riking

3
@mbarrows Tuy nhiên câu trả lời này vẫn đúng ở chỗ TimeUnitgiải pháp dẫn đến mất tính đặc hiệu. TimeUnit.SECONDS.convert(500, TimeUnit.MILLISECONDS);sẽ trở lại 0, không 0.5. Nó chỉ đơn giản phụ thuộc vào trường hợp sử dụng của bạn mà trong số này là thích hợp hơn.
Nbrooks

17
Hoàn toàn đồng ý với @nbrooks ở đây. Sử dụng TimeUnit sẽ không xuất ra các phân số của giây, thay vào đó trả về 0. Nếu bạn không muốn sử dụng số có 10 chữ số được mã hóa cứng thì hãy sử dụng cái gì đó như 1E9. Ví dụ: double seconds = ((double) nanoseconds) / 1E9; tôi sẽ làm điều này mỗi lần như một sở thích cá nhân.
TechTrip

3
Sử dụng phương pháp này trên phương thức TimeUnit Enum nếu bạn muốn phân số của một giây. Sử dụng TimeUnit Enum thậm chí không làm tròn đến giây gần nhất, về cơ bản, nó chỉ cắt các phân số của một giây. Vì vậy, 4.9999999, chỉ đơn giản là 4.
Dick Lucas

354

TimeUnit Enum

Biểu thức sau sử dụng TimeUnitenum (Java 5 trở lên) để chuyển đổi từ nano giây sang giây:

TimeUnit.SECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS)

14
Không phải là phương pháp này không bao gồm các phân số của một giây. Vì vậy, 4.9999999, chỉ đơn giản là 4 giây.
Dick Lucas

1
Điều này được ưa thích vì bạn không bao giờ nên viết ra 1 theo sau là toàn bộ số 0 do nó rất dễ bị lỗi.
demongolem

1
bạn có thể viết nó như thế này elapsedTime = (end_time - start_time) / 1e9;
Hasson

1
Nếu tôi ở lại 59 phút và 50 giây thì nó vẫn báo 0h trôi qua ... Điều đó không lý tưởng. Vậy có cách nào để làm cho phương pháp này hoạt động với phân số không?
dùng1156544

58

TimeUnit là một enum, vì vậy bạn không thể tạo một cái mới.

Sau đây sẽ chuyển đổi 1000000000000ns thành giây.

TimeUnit.NANOSECONDS.toSeconds(1000000000000L);

4
Tôi tin rằng đó là 10e + 9 chứ không phải 1e + 12!
Adam Arold

8
Đây là một câu trả lời khá muộn, nhưng số trong ví dụ không phải là số lượng nano trong một giây, nó chỉ là một số để chuyển đổi. Toàn bộ ý tưởng là không phải biết những giá trị đó.
Nick Veys

2
Tôi nghĩ rằng đây nên là câu trả lời được chấp nhận. Sử dụng toXxx () tốt hơn là sử dụng convert () vì với convert () không rõ ràng việc chuyển đổi xảy ra theo hướng nào, trong khi với toXxx () thì đó là.
Klitos Kyriacou

21

Để giảm mức độ chi tiết, bạn có thể sử dụng nhập tĩnh:

import static java.util.concurrent.TimeUnit.NANOSECONDS;

-và từ đó chỉ cần gõ

NANOSECONDS.toSeconds(elapsedTime);

6

Bạn nên viết:

    long startTime = System.nanoTime();        
    long estimatedTime = System.nanoTime() - startTime;

Việc chỉ định endTime trong một biến có thể gây ra vài nano giây. Trong phương pháp này, bạn sẽ có được thời gian trôi qua chính xác.

Và sau đó:

TimeUnit.SECONDS.convert(estimatedTime, TimeUnit.NANOSECONDS)

4

Điều này sẽ chuyển đổi thời gian thành giây ở định dạng kép, chính xác hơn giá trị số nguyên:

double elapsedTimeInSeconds = TimeUnit.MILLISECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS) / 1000.0;

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.