System.currentTimeMillis () ส่งคืนเวลา UTC หรือไม่


93

ฉันต้องการรับเวลา UTC ปัจจุบันเป็นมิลลิวินาที ฉันค้นหา google และได้รับคำตอบว่า System.currentTimeMillis () ส่งคืนเวลา UTC แต่มันไม่ หากฉันทำตาม:

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

ทั้งสามครั้งเกือบจะเท่ากัน (ความแตกต่างเป็นมิลลิวินาทีเนื่องจากการโทร)

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

และเวลานี้ไม่ใช่เวลา UTC แต่เป็นเวลาเขตเวลาของฉัน ฉันจะรับเวลา UTC ปัจจุบันใน Android ได้อย่างไร


5
ส่งคืนเวลาของระบบปัจจุบันเป็นมิลลิวินาทีตั้งแต่วันที่ 1 มกราคม 1970 00:00:00 UTC
Blackbelt


3
t3 ยาว = Calendar.getInstance (TimeZone.getTimeZone ("UTC")) getTimeInMillis ();
Blackbelt

3
ลิงก์ด้านบนระบุว่า "ดูคำอธิบายของวันที่ของชั้นเรียนสำหรับการอภิปรายเกี่ยวกับความคลาดเคลื่อนเล็กน้อยที่อาจเกิดขึ้นระหว่าง" เวลาคอมพิวเตอร์ "และเวลาสากลเชิงพิกัด (UTC)" และในเอกสาร java.util.Date คุณจะพบ: "แม้ว่าคลาส Date จะมีจุดมุ่งหมายเพื่อแสดงเวลาสากลเชิงพิกัด (UTC) แต่ก็อาจไม่เป็นเช่นนั้นอย่างแน่นอนทั้งนี้ขึ้นอยู่กับสภาพแวดล้อมโฮสต์ของ Java Virtual Machine" -> ดังนั้นจึงอาจ เป็นไปได้ว่าเครื่องของคุณส่งคืนเวลาที่ไม่ใช่ UTC
Marco Forberg

4
@ g.revolution: เป็น "จำนวนมิลลิวินาทีตั้งแต่วันที่ 1 มกราคม 1970 00:00:00 UTC" คุณคาดหวังว่าจะปรับเปลี่ยนตามเขตเวลาได้อย่างไร เขตเวลาท้องถิ่นของคุณไม่มีผลต่อจำนวนมิลลิวินาทีที่เกิดขึ้นนับตั้งแต่ยุคนั้น
Jon Skeet

คำตอบ:


134

ทั้งสามบรรทัดที่คุณแสดงจะให้จำนวนมิลลิวินาทีนับตั้งแต่ยุคยูนิกซ์ซึ่งเป็นจุดกำหนดเวลาที่กำหนดโดยไม่ได้รับผลกระทบจากเขตเวลาท้องถิ่นของคุณ

คุณพูดว่า "เวลานี้ไม่ใช่เวลา UTC" - ฉันสงสัยว่าคุณวินิจฉัยไม่ถูกต้องจริงๆ ฉันขอแนะนำให้ใช้epochconverter.comสำหรับสิ่งนี้ ตัวอย่างเช่นในตัวอย่างของคุณ:

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

เราไม่ทราบว่าคุณสร้างค่านั้นขึ้นเมื่อใด แต่เว้นแต่ว่าจะเป็นเวลา 8:01 น. UTC จริงปัญหาของนาฬิการะบบ

ทั้งSystem.currentTimeMillisค่าภายในDateตัวเองจะไม่ได้รับผลกระทบจากเขตเวลา แต่คุณควรจะตระหนักว่าDate.toString() ไม่ใช้โซนเวลาท้องถิ่นซึ่งเข้าใจผิดนักพัฒนาจำนวนมากในการคิดว่าDateมีความเกี่ยวข้องโดยเนื้อแท้กับโซนเวลา - มันไม่ได้เป็นเพียงทันทีในเวลาโดยไม่ต้องมีโซนเวลาที่เกี่ยวข้องหรือระบบปฏิทินแม้กระทั่ง


6
โดยพื้นฐานแล้วกล่าวคือฟังก์ชันนี้จะคืนค่าเดียวกันหากเรียกในเวลาเดียวกันจากภายในเขตเวลาที่ต่างกันโดยไม่คำนึงถึงนาฬิกาของโฮสต์ถูกต้องหรือไม่?
Phillip

15
ผู้ชายคนนี้ทำให้ฉันหวังว่าโลกจะ (สามารถ) ใช้เขตเวลาเดียว ใครจะสนใจว่าตัวเลขบนนาฬิกาคือ 00:00 น. หรือ 08:00 น. เมื่อสิ่งสว่างขนาดใหญ่ปรากฏบนท้องฟ้า ชั่วโมงนับไม่ถ้วนของเวลาการผลิตเป็นอย่างอื่นเสียในที่ระลึกทางประวัติศาสตร์นี้จะทำให้เลือดเดือดของฉัน ...
corsiKa

ที่เกี่ยวข้องโปรดทราบว่าการเรียกใช้ฟังก์ชันนาฬิกาของระบบปฏิบัติการมีเอกสาร "ล่องลอย" เป็นเวลาหลายมิลลิวินาที Java มี 'ตัวจับเวลาประสิทธิภาพสูง' หากตั้งใจจะให้ได้ระยะเวลาที่แม่นยำสูงของการดำเนินการ (กำหนดเวลาเมื่องานเริ่มต้นและเสร็จสิ้นเดลต้าคือระยะเวลาที่ผ่านไป) ดู: docs.oracle.com/javase/7/docs/api/java/lang/…
Darrell Teague

@JonSkeet ถ้า toString () ใช้เขตเวลาภายในฉันจะสร้างสตริงจากมันโดยไม่มีเขตเวลาได้อย่างไร อันที่จริงฉันกำลังสร้างไฟล์ในเซิร์ฟเวอร์ REST ซึ่งมีชื่อไฟล์ตรงกับค่าเวลาเที่ยงคืนเช่น "1551139200.json" (26 กุมภาพันธ์ 2019 00:00:00 น.) และจำเป็นต้องเข้าถึงจากแอป Android เมื่ออุปกรณ์ System.currentTimeMillis () ส่งคืนเวลาที่แน่นอน
kiranking

@kiranking: ใช้Date.getTime()เพื่อค้นหาเวลามิลลิวินาทีตั้งแต่ Unix-epoch หารด้วย 1,000 (เนื่องจากชื่อไฟล์นั้นเป็นวินาทีนับตั้งแต่ยุค Unix) และจัดรูปแบบจำนวนเต็มนั้นเป็นสตริง
Jon Skeet

2

ฉันยืนยันได้ว่าการโทรทั้งสามครั้งอาจขึ้นอยู่กับเวลาท้องถิ่นโดยพิจารณาจากยุคสมัยไม่ใช่Date.toString()หรือวิธีการใด ๆ ที่คล้ายกัน ฉันเคยเห็นมันขึ้นอยู่กับเวลาท้องถิ่นในอุปกรณ์ที่ใช้ Android 2.3 ฉันยังไม่ได้ทดสอบกับอุปกรณ์อื่น ๆ และเวอร์ชัน Android ในกรณีนี้เวลาท้องถิ่นถูกตั้งค่าด้วยตนเอง

วิธีเดียวที่เชื่อถือได้ในการรับเวลา UTC อิสระคือการขอการอัปเดตตำแหน่งโดยใช้ไฟล์GPS_PROVIDER. getTime()ค่าของสถานที่ตั้งที่ดึงมาจากNETWORK_PROVIDERยังขึ้นอยู่กับเวลาท้องถิ่น อีกทางเลือกหนึ่งคือ ping เซิร์ฟเวอร์ที่ส่งคืนการประทับเวลา UTC เช่น

ดังนั้นสิ่งที่ฉันทำมีดังต่อไปนี้:

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 () ส่งคืนค่าตาม UTC ในส่วนของ 'ความแม่นยำ' หรือความแม่นยำของนาฬิการะบบปฏิบัติการนั้นเกี่ยวข้องในขณะที่สิ่งนี้ส่งผลกระทบต่อผลลัพธ์อย่างแน่นอน แต่ก็ไม่เกี่ยวข้องกับค่าโซนเวลาของระบบหรือสภาพแวดล้อม Java แต่อย่างใด
Darrell Teague

@DarrellTeague ฉันยืนยันฉันเห็นค่าที่แตกต่างกันในอุปกรณ์ Huawei บางเครื่อง ดังนั้นไม่มันจะไม่ส่งคืนเวลา UTC ที่ถูกต้องเสมอไป (ทิ้งความแตกต่างของความแม่นยำ)
jlhonora

คำถามของ OP เกี่ยวกับการใช้เขตเวลาคลาส Java สิ่งนี้ไม่เกี่ยวกับฮาร์ดแวร์หรือความถูกต้องของค่าเวลาที่ส่งคืน พูดง่ายๆคือ JVM ได้เวลาจาก "นาฬิการะบบ" ปฏิบัติการ (นามธรรม) (ซึ่งแตกต่างกันไปตามระบบปฏิบัติการในแง่ของการทำงานของมัน) ดูเพิ่มเติมที่: drdobbs.com/embedded-systems/…และการใช้งาน "C" บนระบบปฏิบัติการchemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.