Java: วันที่จากการประทับเวลา unix


237

ฉันต้องการแปลงเวลาประทับยูนิกซ์เป็นวัตถุวันที่
ฉันลองสิ่งนี้:

java.util.Date time = new java.util.Date(timeStamp);

ค่าการประทับเวลาคือ: 1280512800

วันที่ควรจะเป็น "2010/07/30 - 22:30:00" (ตามที่ผมได้รับมันโดย PHP) Thu Jan 15 23:11:56 IRST 1970แต่แทนที่จะได้รับ

ควรทำอย่างไร?


3
หากคุณใช้ Java 8 หรือใหม่กว่า: ดูคำตอบนี้: stackoverflow.com/a/24703644/1115554
micha

1
FYI คลาสวัน - เวลาเก่าที่ลำบากเช่นjava.util.Dateตอนนี้เป็นมรดกแทนที่ด้วยคลาสjava.time ดูการสอนโดยออราเคิล
Basil Bourque

คำตอบ:


429

สำหรับ1280512800คูณด้วย 1,000 เนื่องจาก java คาดว่าจะมีมิลลิวินาที:

java.util.Date time=new java.util.Date((long)timeStamp*1000);

หากคุณมีมิลลิวินาทีอยู่แล้วเพียง new java.util.Date((long)timeStamp);

จากเอกสาร :

จัดสรรวัตถุวันที่และเริ่มต้นมันเพื่อเป็นตัวแทนของจำนวนมิลลิวินาทีที่ระบุตั้งแต่เวลาฐานมาตรฐานที่รู้จักกันในชื่อ "ยุค" คือ 1 มกราคม 1970, 00:00:00 GMT


40
การส่งไป(long)เป็นสิ่งสำคัญมาก: หากไม่มีจำนวนเต็มมากเกินไป
mneri

2
@TomasK java.util.Dateเป็นชื่อที่มีคุณสมบัติครบถ้วนของชั้นเรียน Dateอาจเป็นสิ่งเดียวกันแน่นอนหากคุณนำเข้าjava.utilแพ็คเกจในชั้นเรียนของคุณ
Pablo Santa Cruz

5
ไม่จำเป็นต้องใช้การร่ายนาน time = new java.util.Date (timeStamp * 1000L) ทำงานได้ดีเช่นกัน (เนื่องจาก 1000L เป็นเวลานานการประทับเวลาจะถูกส่งไปเป็นเวลานานก่อนการคูณ)
Tony BenBrahim

2
โดยส่วนตัวแล้วฉันจะทำ:Date time = new Date(TimeUnit.MILLISECONDS.convert(unixTimestamp, TimeUnit.SECONDS));
Ryan Amaral

3
FYI คลาสวัน - เวลาเก่าที่ลำบากเช่นjava.util.Dateตอนนี้เป็นมรดกแทนที่ด้วยคลาสjava.time ดูการสอนโดยออราเคิล
Basil Bourque

59

java.time

Java 8เปิดตัว API ใหม่สำหรับการทำงานกับวันที่และเวลาที่: แพคเกจ java.time

ด้วย java.time คุณสามารถแยกจำนวนวินาทีทั้งหมดได้ตั้งแต่การอ้างอิงช่วงเวลาแรกของปี 1970 ใน UTC, 1970-01-01T00: 00Z Instantผลที่ได้คือ

Instant instant = Instant.ofEpochSecond( timeStamp );

หากคุณต้องการ a java.util.Dateเพื่อทำงานร่วมกับรหัสเก่าที่ยังไม่ได้อัปเดตสำหรับjava.timeให้แปลง เรียกวิธีการแปลงใหม่ที่เพิ่มในคลาสเก่า

Date date = Date.from( instant );

3
ในขณะที่คำตอบนี้เป็นเทคนิคที่ถูกต้องทราบว่าjava.timejava.util.Dateเรียนแย่งลำบากเก่าชั้นเรียนวันที่เวลาเช่น คลาสเก่าเป็นแบบดั้งเดิมและควรหลีกเลี่ยง ในขณะที่คุณสามารถแปลงเป็น / จากคลาสดั้งเดิมและ java.time ได้ดีที่สุดคือติดกับ java.time ทุกครั้งที่ทำได้
โหระพา Bourque


27

ดูเหมือนว่าปฏิทินเป็นวิธีใหม่ในการไป:

Calendar mydate = Calendar.getInstance();
mydate.setTimeInMillis(timestamp*1000);
out.println(mydate.get(Calendar.DAY_OF_MONTH)+"."+mydate.get(Calendar.MONTH)+"."+mydate.get(Calendar.YEAR));

บรรทัดสุดท้ายเป็นเพียงตัวอย่างวิธีใช้งานบรรทัดนี้จะพิมพ์เช่น "14.06.2012"

หากคุณใช้ System.currentTimeMillis () เพื่อบันทึก Timestamp คุณไม่จำเป็นต้องใช้ส่วน "* 1000"

หากคุณมีการประทับเวลาในสตริงคุณต้องแยกวิเคราะห์มันก่อนเป็นเวลานาน: Long.parseLong (การประทับเวลา)

https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html


8
คำเตือน: ถ้าtimestampเป็นจำนวนเต็มคุณต้องใช้มันเป็น(long)อันดับแรกมิฉะนั้นคุณจะสิ้นสุดด้วยวันที่ผิด mydate.setTimeInMillis((long) timestamp*1000);
svenkapudija

ฉันแก้ไขลิงก์แล้ว
Ricbit

FYI, ลำบากเก่าชั้นเรียนวันที่เวลาเช่นjava.util.Date, java.util.Calendarและjava.text.SimpleDateFormatตอนนี้มรดกแทนที่โดยjava.timeชั้นเรียนที่สร้างขึ้นใน Java 8 และต่อมา ดูการสอนโดยออราเคิล
Basil Bourque

26

TL; DR

Instant.ofEpochSecond( 1_280_512_800L )

2010-07-30T18: 00: 00Z

java.time

เฟรมเวิร์ก java.time ใหม่ที่สร้างขึ้นใน Java 8 และใหม่กว่าคือตัวต่อของ Joda-Time

คลาสใหม่เหล่านี้มีวิธีใช้จากโรงงานที่สะดวกในการแปลงจำนวนวินาทีทั้งหมดจากกาล คุณได้Instantเวลาสักครู่บนเส้นเวลาใน UTC พร้อมความละเอียดสูงสุดเป็นนาโนวินาที

Instant instant = Instant.ofEpochSecond( 1_280_512_800L );

instant.toString (): 2010-07-30T18: 00: 00Z

เห็นว่ารหัสทำงานอยู่ที่ IdeOne.com

ตารางประเภทวันที่ - เวลาใน Java ทั้งทันสมัยและดั้งเดิม

Asia/Kabul หรือ Asia/Tehranเขตเวลา

คุณรายงานการได้รับค่าเวลา 22:30 แทน 18:00 ที่เห็นที่นี่ ฉันสงสัยว่ายูทิลิตี้ PHP ของคุณกำลังใช้เขตเวลาเริ่มต้นในการปรับจาก UTC โดยปริยาย ค่าของฉันที่นี่คือ UTC มีความหมายโดยZ(ย่อมาจากZuluหมายถึง UTC) โอกาสที่ OS เครื่องของคุณหรือ PHP มีการตั้งค่าAsia/KabulหรือAsia/Tehranโซนเวลา? ฉันคิดว่าอย่างนั้นเมื่อคุณรายงานผลงานIRSTของคุณซึ่งหมายถึงเวลาของอิหร่าน ขณะนี้ในปี 2560 โซนเหล่านี้เป็นโซนเดียวที่เปิดให้บริการในช่วงฤดูร้อนซึ่งเป็นเวลาสี่ชั่วโมงครึ่งก่อนเวลา UTC

ระบุชื่อโซนเวลาที่เหมาะสมในรูปแบบของcontinent/regionเช่นAmerica/Montreal, หรือAfrica/Casablanca Pacific/Aucklandอย่าใช้อักษรย่อ 3-4 ตัวอักษรเช่นESTหรือISTหรือIRSTที่พวกเขาจะไม่ได้โซนเวลาจริงไม่ได้มาตรฐานและไม่ได้ไม่ซ้ำกัน (!)

หากคุณต้องการที่จะเห็นช่วงเวลาของคุณผ่านเลนส์ของโซนเวลาภูมิภาคโดยเฉพาะอย่างยิ่งที่ใช้จะได้รับZoneId ZonedDateTimeยังคงเป็นช่วงเวลาที่พร้อมกันเดียวกัน แต่มองว่าเป็นความแตกต่างเวลาผนังนาฬิกา

ZoneId z = ZoneId.of( "Asia/Tehran" ) ;
ZonedDateTime zdt = instant.atZone( z );  // Same moment, same point on timeline, but seen as different wall-clock time.

2010-07-30T22: 30 + 04: 30 [เอเชีย / เตหะราน]

การแปลงจาก java.time เป็นคลาสดั้งเดิม

คุณควรใช้คลาส java.time ใหม่ แต่คุณสามารถเปลี่ยนเป็นเก่าได้ถ้าต้องการ

java.util.Date date = java.util.Date.from( instant );

Joda เวลา

UPDATE: โครงการJoda-Timeอยู่ในโหมดบำรุงรักษาโดยทีมงานจะแนะนำการโยกย้ายไปยังjava.timeคลาส

FYI ตัวสร้างสำหรับJoda-Time DateTimeคล้ายกัน: คูณด้วยหลักพันเพื่อสร้าง a long(ไม่ใช่int!)

DateTime dateTime = new DateTime( ( 1_280_512_800L * 1000_L ), DateTimeZone.forID( "Europe/Paris" ) );

ดีที่สุดเพื่อหลีกเลี่ยงคลาส java.util.Date และ. ปฏิทินที่มีปัญหาฉาวโฉ่ แต่ถ้าคุณต้องใช้วันที่คุณสามารถแปลงจาก Joda-Time

java.util.Date date = dateTime.toDate();

เกี่ยวกับjava.time

java.timeกรอบถูกสร้างขึ้นใน Java 8 และต่อมา ชั้นเรียนเหล่านี้แย่งลำบากเก่ามรดกเรียนวันที่เวลาเช่นjava.util.Date, และCalendarSimpleDateFormat

Joda เวลาโครงการขณะนี้อยู่ในโหมดการบำรุงรักษาให้คำแนะนำแก่การโยกย้ายไปยังjava.timeชั้นเรียน

ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย สเปกJSR 310

คุณสามารถแลกเปลี่ยนวัตถุjava.timeโดยตรงกับฐานข้อมูลของคุณ ใช้ไดรเวอร์ JDBC ที่สอดคล้องกับJDBC 4.2หรือใหม่กว่า ไม่จำเป็นต้องใช้สตริงไม่จำเป็นต้องมีjava.sql.*คลาส

จะรับคลาส java.time ได้ที่ไหน?

  • Java SE 8 , Java SE 9และใหม่กว่า
    • Built-in
    • เป็นส่วนหนึ่งของ Java API มาตรฐานที่มีการใช้งานแบบรวม
    • Java 9 เพิ่มคุณสมบัติและการแก้ไขเล็กน้อย
  • Java SE 6และ Java SE 7
    • มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับ
  • Android
    • การใช้งานชุดบันเดิล Android รุ่นต่อมาของคลาส java.time
    • สำหรับก่อนหน้านี้ Android (<26) ที่ThreeTenABPโครงการปรับThreeTen-ย้ายกลับ (ดังกล่าวข้างต้น) ดูวิธีการใช้ ThreeTenABP … .

โครงการThreeTen-Extraขยาย java.time ด้วยคลาสเพิ่มเติม โครงการนี้เป็นพื้นฐานที่พิสูจน์ได้สำหรับการเพิ่มเติมในอนาคตไปยัง java.time คุณอาจพบว่าการเรียนที่มีประโยชน์บางอย่างที่นี่เช่นInterval, YearWeek, YearQuarterและอื่น ๆ อีกมากมาย


11

ตัวสร้างของวันที่คาดว่าค่า timeStamp จะอยู่ในหน่วยมิลลิวินาที คูณค่าของเวลาประทับของคุณด้วย 1,000 จากนั้นส่งผ่านไปยังตัวสร้าง


7

หากคุณกำลังแปลงค่าการประทับเวลาบนเครื่องอื่นคุณควรตรวจสอบเขตเวลาของเครื่องนั้นด้วย ตัวอย่างเช่น;

Decriptions ด้านบนจะส่งผลให้ค่าวันที่แตกต่างกันหากคุณเรียกใช้ด้วยเขตเวลา EST หรือ UTC

ในการตั้งเขตเวลา aka ถึง UTC คุณสามารถเขียนซ้ำได้ง่าย

    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    java.util.Date time= new java.util.Date((Long.parseLong(timestamp)*1000));

6
ฉันจะไม่แนะนำสิ่งนี้เพราะเป็นการตั้งค่าเขตเวลาสำหรับ jvm ทั้งหมดและไม่ใช่แค่กระบวนการแยกวิเคราะห์!

1

สำหรับ kotlin

fun unixToDate(timeStamp: Long) : String? {
    val time = java.util.Date(timeStamp as Long * 1000)
    val sdf = SimpleDateFormat("yyyy-MM-dd")
    return sdf.format(time)

}

0

บางครั้งคุณต้องทำงานกับการปรับเปลี่ยน

อย่าใช้นักแสดงนาน! ใช้ nanoadjustment

ตัวอย่างเช่นการใช้ Oanda Java API สำหรับการซื้อขายคุณสามารถรับ datetime ในรูปแบบ UNIX

ตัวอย่างเช่น: 1592523410.590566943

    System.out.println("instant with nano = " + Instant.ofEpochSecond(1592523410, 590566943));
    System.out.println("instant = " + Instant.ofEpochSecond(1592523410));

คุณได้รับ:

instant with nano = 2020-06-18T23:36:50.590566943Z
instant = 2020-06-18T23:36:50Z

นอกจากนี้ยังใช้:

 Date date = Date.from( Instant.ofEpochSecond(1592523410, 590566943) );

-4
Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());

3
หากไม่มีข้อความเพิ่มเติมก็ไม่มีความชัดเจนว่าทำไมคำตอบนี้จึงดีกว่าคำถามอื่น ๆ ในคำถามนี้ คุณช่วยอธิบายได้ไหม?
Duncan Jones

สิ่งนี้จะแก้ไขวันที่แทนที่จะทำการแปลง!
backslashN
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.