System.currentTimeMillis () có trả về thời gian UTC không?


93

Tôi muốn tính thời gian UTC hiện tại bằng mili giây. Tôi đã tìm kiếm trên google và nhận được một số câu trả lời rằng System.currentTimeMillis () trả về thời gian UTC. Nhưng nó không. Nếu tôi làm như sau:

long t1 = System.currentTimeMillis();
long t2 = new Date().getTime();
long t3 = Calendar.getInstance().getTimeInMillis();

cả ba thời điểm gần như giống nhau (chênh lệch tính bằng mili giây do các cuộc gọi).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

và thời gian này không phải là giờ UTC thay vào đó đây là múi giờ của tôi. Làm cách nào để lấy thời gian UTC hiện tại trong Android?


4
Trả về thời gian hiện tại của hệ thống tính bằng mili giây kể từ ngày 1 tháng 1 năm 1970 00:00:00 UTC
Blackbelt


3
long t3 = Calendar.getInstance (TimeZone.getTimeZone ("UTC")). getTimeInMillis ();
Blackbelt

3
Liên kết trên có nội dung "Xem mô tả về Ngày lớp để thảo luận về sự khác biệt nhỏ có thể phát sinh giữa" giờ máy tính "và giờ quốc tế phối hợp (UTC)." và trong tài liệu java.util.Date, bạn tìm thấy: "Mặc dù lớp Ngày nhằm phản ánh thời gian phối hợp toàn cầu (UTC), nhưng nó có thể không làm như vậy chính xác, tùy thuộc vào môi trường máy chủ của Máy ảo Java" -> vì vậy nó có thể có thể là máy tính của bạn trở lại phi UTC thời gian
Marco Forberg

4
@ g.revolution: Đó là "số mili giây kể từ ngày 1 tháng 1 năm 1970 00:00:00 UTC" - bạn mong đợi điều đó sẽ điều chỉnh cho một múi giờ như thế nào? Múi giờ địa phương của bạn không ảnh hưởng đến số mili giây đã xảy ra kể từ kỷ nguyên đó.
Jon Skeet

Câu trả lời:


132

Tất cả ba dòng bạn đã hiển thị sẽ cung cấp số mili giây kể từ kỷ nguyên unix, là một thời điểm cố định trong thời gian, không bị ảnh hưởng bởi múi giờ địa phương của bạn.

Bạn nói "thời gian này không phải là giờ UTC" - Tôi nghi ngờ rằng bạn đã thực sự chẩn đoán sai. Tôi sẽ đề xuất sử dụng epochconverter.com cho việc này. Ví dụ, trong ví dụ của bạn:

1372060916 = Mon, 24 Jun 2013 08:01:56 GMT

Chúng tôi không biết khi nào bạn tạo giá trị đó, nhưng trừ khi nó thực sự là lúc 8:01 sáng UTC, đó là vấn đề với đồng hồ hệ thống của bạn.

Cả System.currentTimeMillisgiá trị và giá trị trong Datechính nó đều không bị ảnh hưởng bởi múi giờ. Tuy nhiên, bạn nên biết rằng Date.toString() sử dụng múi giờ địa phương, điều này khiến nhiều nhà phát triển hiểu nhầm rằng a Datevốn được liên kết với một múi giờ - không phải vậy, đó chỉ là thời gian tức thì, không có múi giờ liên quan hoặc thậm chí là hệ thống lịch.


6
Vì vậy, về cơ bản, nghĩa là hàm này trả về cùng một giá trị nếu được gọi cùng một lúc từ các múi giờ khác nhau, bất kể đồng hồ của máy chủ, đúng không?
Phillip

14
Điều này khiến tôi ước thế giới sẽ (có thể) áp dụng một múi giờ duy nhất. Ai quan tâm xem con số trên đồng hồ là 00:00 hay 08:00 khi vật sáng lớn xuất hiện trên bầu trời? Giờ không biết bao nhiêu thời gian khác sản xuất lãng phí về di tích lịch sử này làm sôi máu của tôi ...
corsiKa

Liên quan đến điều này, hãy lưu ý rằng lệnh gọi cơ bản đến chức năng đồng hồ hệ điều hành có 'độ lệch' được ghi lại trong vài mili giây. Java có 'bộ đếm thời gian hiệu suất cao' nếu mục đích là để có được thời lượng chính xác cao của một hoạt động (thời gian khi một tác vụ bắt đầu và kết thúc, delta là khoảng thời gian đã trôi qua). Xem: docs.oracle.com/javase/7/docs/api/java/lang/…
Darrell Teague

@JonSkeet nếu toString () sử dụng múi giờ nội bộ, làm cách nào tôi có thể tạo chuỗi từ nó mà không có múi giờ. Trên thực tế, tôi đang tạo tệp trong máy chủ REST có tên tệp chính xác bằng giá trị thời gian nửa đêm, ví dụ: "1551139200.json" (12:00:00 AM ngày 26 tháng 2 năm 2019) và tệp đó cần được truy cập từ ứng dụng Android sau khi System.currentTimeMillis của thiết bị () trả về thời gian chính xác.
kiranking

@kiranking: Sử dụng Date.getTime()để tìm thời gian mili giây kể từ kỷ nguyên Unix, chia cho 1000 (vì tên tệp đó tính bằng giây kể từ kỷ nguyên Unix) và chỉ định dạng số nguyên đó dưới dạng chuỗi.
Jon Skeet

3

Tôi có thể xác nhận rằng tất cả ba cuộc gọi có thể phụ thuộc vào giờ địa phương, xem xét kỷ nguyên, không phảiDate.toString() hoặc bất kỳ phương thức nào tương tự. Tôi đã thấy chúng phụ thuộc vào giờ địa phương trong các thiết bị cụ thể chạy Android 2.3. Tôi chưa thử nghiệm chúng với các thiết bị và phiên bản Android khác. Trong trường hợp này, giờ địa phương được đặt theo cách thủ công.

Cách đáng tin cậy duy nhất để có được thời gian UTC độc lập là yêu cầu cập nhật vị trí bằng cách sử dụng GPS_PROVIDER. Các getTime()giá trị của một vị trí lấy từNETWORK_PROVIDER cũng phụ thuộc vào thời gian địa phương. Một tùy chọn khác là ping một máy chủ trả về dấu thời gian UTC chẳng hạn.

Vì vậy, những gì tôi làm là như sau:

public static String getUTCstring(Location location) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    String date = sdf.format(new Date(location.getTime()));
    // Append the string "UTC" to the date
    if(!date.contains("UTC")) {
        date += " UTC";
    }
    return date;
}

1
System.currentTimeMillis () trả về giá trị dựa trên UTC. Liên quan đến 'độ chính xác' hoặc độ chính xác của đồng hồ hệ điều hành, mặc dù chắc chắn điều này ảnh hưởng đến kết quả, nhưng không liên quan đến hệ thống hoặc giá trị múi giờ của môi trường Java theo bất kỳ cách nào.
Darrell Teague

@DarrellTeague Tôi nhấn mạnh, tôi đã thấy các giá trị khác nhau trong một thiết bị Huawei cụ thể. Vì vậy, không, nó không luôn luôn trả về thời gian tính theo giờ UTC đúng (loại bỏ sự khác biệt chính xác)
jlhonora

Câu hỏi của OP là về việc sử dụng múi giờ của lớp Java. Đây không phải là về phần cứng hay độ chính xác của giá trị thời gian trả về. Nói một cách đơn giản, JVM lấy thời gian của nó từ "đồng hồ hệ thống" hoạt động (trừu tượng) (thay đổi theo hệ điều hành về cách thức hoạt động của nó). Xem thêm: drdobbs.com/embedded-systems/... và "C" triển khai trên hệ điều hành chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague
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.