Java SimpleDateFormat (“ yyyy-MM-dd'T'HH: mm: ss'Z '”) ให้เขตเวลาเป็น IST


148

ฉันมีตัวสร้าง SimpleDateFormat เป็น

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

และฉันแยกสตริง "2013-09-29T18:46:19Z".

ฉันได้อ่านแล้วว่าที่นี่ Z หมายถึงGMT/UTCเขตเวลา แต่เมื่อฉันพิมพ์วันที่นี้บนคอนโซลมันจะพิมพ์เวลา IST สำหรับวันที่ส่งคืน

ตอนนี้คำถามของฉันคือว่าผลลัพธ์ของฉันถูกหรือผิด?


3
ใช่นั่นคือความหมายของ 'Z' Z- เขตเวลา
วู้ดดี้

5
Z = เวลาซูลู => GMT + 0 เห็นได้ชัดว่าคุณไม่ได้ให้บริการในประเทศของคุณ;)
MushyPeas

คำตอบ:


251

คุณยังไม่ได้ตั้งค่าเขตเวลาเพียงเพิ่ม a Zไปที่ส่วนท้ายของวันที่ / เวลาดังนั้นมันจะดูเหมือนวันที่ / เวลา GMT แต่จะไม่เปลี่ยนค่า

ตั้งค่าเขตเวลาเป็น GMT และจะถูกต้อง

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

3
หากคุณมีวันที่พูด 2012-12-06T06: 00: 00 โดยไม่มี Z นั่นแสดงถึง GMT หรือไม่
binarygiant

3
@binarygiant คุณจะต้องถามคนที่ส่งมัน อาจเป็นเวลาท้องถิ่นของผู้ส่ง
Peter Lawrey

2
เขตเวลาสามารถตั้งค่าเป็น "UTC"
Prashanth

2
แทนที่จะตั้งค่าเขตเวลาในหลาย ๆ ที่สำหรับห้องสมุดที่แตกต่างกันและหลีกเลี่ยงความขัดแย้งกับเครื่อง / แล็ปท็อปของคุณคุณควรตั้งค่าเขตเวลาเริ่มต้นของ JVM โดยการตั้งค่าคุณสมบัติระบบ user.timezone: java -Duser.timezone = GMT ...
kisna

100

'T'และ'Z'ได้รับการพิจารณาว่าเป็นค่าคงที่ คุณต้องผ่านZโดยไม่ต้องพูด ยิ่งไปกว่านั้นคุณจะต้องระบุเขตเวลาในสตริงอินพุต

ตัวอย่าง: 2013-09-29T18:46:19-0700 และรูปแบบเป็น"yyyy-MM-dd'T'HH:mm:ssZ"


Subir ขอบคุณสำหรับคำตอบของคุณ แต่สิ่งที่ "0700" ผนวกเข้ากับสายป้อน?
Pradip Borde

-0700คือเขตเวลาคือ -7: 00 น.
Subir Kumar Sao

12
สำหรับ -07: 00 ชั่วโมงและไม่ใช่ -0700 จะเป็นดังต่อไปนี้: yyyy-MM-dd'T'HH: mm: ss.SSSXXX
Tastybrownies

48

จากสตริง ISO 8601 ไปจนถึงวัตถุวันที่ของ Java

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf.parse("2013-09-29T18:46:19Z"); //prints-> Mon Sep 30 02:46:19 CST 2013

หากคุณไม่ได้ตั้งค่าTimeZone.getTimeZone("GMT")มันจะส่งออกSun Sep 29 18:46:19 CST 2013

จาก Java Date Object ไปยัง ISO 8601 String

และการแปลงDateวัตถุเป็น ISO 8601 Standard ( yyyy-MM-dd'T'HH:mm:ss'Z') ให้ใช้รหัสต่อไปนี้

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));           
System.out.println(sdf.format(new Date())); //-prints-> 2015-01-22T03:23:26Z

โปรดทราบด้วยว่าหากไม่พิมพ์ที่' 'Zyyyy-MM-dd'T'HH:mm:ssZ2015-01-22T03:41:02+0000


2
มันให้ฉัน java.text.ParseException: วันที่ที่ไม่สามารถหาได้: "2018-05-01T18: 30: 00.000Z" @AZ_
Mansuu ....

41

ถ้าคุณต้องการที่จะจัดการกับ ' มาตรฐาน ' ตัวแทน JSON "yyyy-MM-dd'T'HH:mm:ssX"วันนั้นดีกว่าการใช้รูปแบบนี้:

แจ้งให้ทราบXเกี่ยวกับในตอนท้าย มันจะจัดการเขตเวลาในมาตรฐาน ISO 8601และ ISO 8601 เป็นสิ่งที่สร้างคำสั่งนี้ใน Javascriptnew Date().toJSON()

เปรียบเทียบกับคำตอบอื่น ๆ มันมีประโยชน์บางอย่าง:

  1. คุณไม่จำเป็นต้องให้ลูกค้าส่งวันที่ในรูปแบบ GMT
  2. คุณไม่จำเป็นต้องแปลงอ็อบเจกต์ Date เป็น GMT โดยใช้สิ่งนี้: sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

1
ฉันกำลังใช้playการผูกฟอร์มอัตโนมัติและใช้@Format.DateTimeคำอธิบายประกอบ ใช้รูปแบบเริ่มต้นด้วยZเมื่อสิ้นสุดดูเหมือนว่าไม่ถูกต้อง หลังจากเปลี่ยนเป็นXใช้งานได้ ขอบคุณมาก
transang

หากวันที่ของคุณระบุเขตเวลาในรูปแบบที่สอดคล้องกับ RFC822 เช่น "-0500" สิ่งนี้จะทำงานได้ดี แต่สำหรับวันเช่น "2013-07-15T10: 22: 17-05: 00" (เช่น ISO8601 TZ ที่ถูกต้อง) ตัวแบ่งนี้ ในกรณีนี้คุณต้องใช้ "yyyy-MM-dd'T'HH: mm: ssXXX"
Lambart

23

TL; DR

คำตอบอื่น ๆ ล้าสมัยไปแล้วของ Java 8

Instant                           // Represent a moment in UTC. 
.parse( "2013-09-29T18:46:19Z" )  // Parse text in standard ISO 8601 format where the `Z` means UTC, pronounces “Zulu”.
.atZone(                          // Adjust from UTC to a time zone. 
    ZoneId.of( "Asia/Kolkata" )
)                                 // Returns a `ZonedDateTime` object. 

ISO 8601

รูปแบบสตริงของคุณเกิดขึ้นเพื่อให้สอดคล้องกับมาตรฐาน ISO 8601มาตรฐาน มาตรฐานนี้กำหนดรูปแบบที่เหมาะสมสำหรับการแสดงค่าวันที่และเวลาต่าง ๆ เป็นข้อความ

java.time

คลาสเก่าjava.util.Date/ .Calendarและjava.text.SimpleDateFormatคลาสได้รับการแทนที่ด้วยเฟรมเวิร์ก java.time ที่สร้างขึ้นใน Java 8 และใหม่กว่า ดูการสอน หลีกเลี่ยงคลาสเก่าเนื่องจากพวกเขาพิสูจน์แล้วว่าได้รับการออกแบบไม่ดีสับสนและลำบาก

ส่วนหนึ่งของการออกแบบที่ไม่ดีในชั้นเรียนเก่าได้กัดคุณโดยที่toStringวิธีการนี้ใช้เขตเวลาเริ่มต้นปัจจุบันของ JVM เมื่อสร้างการแสดงข้อความของค่าวันที่และเวลาใน UTC (GMT) เจตนาดี แต่สับสน

คลาส java.time ใช้รูปแบบ ISO 8601 โดยค่าเริ่มต้นเมื่อแยกวิเคราะห์ / สร้างข้อความที่เป็นตัวแทนของค่าวันที่และเวลา ดังนั้นไม่จำเป็นต้องระบุรูปแบบการแยกวิเคราะห์

Instantเป็นช่วงเวลาบนไทม์ไลน์ในส่วนUTC

Instant instant = Instant.parse( "2013-09-29T18:46:19Z" );

คุณสามารถใช้เขตเวลาตามต้องการเพื่อสร้างZonedDateTimeวัตถุ

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

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


22

และถ้าคุณไม่มีตัวเลือกที่จะใช้ java8 ดีกว่าให้ใช้ 'yyyy-MM-dd'T'HH: mm: ssX XX ' เพราะนี่จะได้รับการวิเคราะห์อย่างถูกต้องอีกครั้ง (ในขณะที่มีเพียงหนึ่ง X นี้อาจไม่เป็นกรณี .. ขึ้นอยู่กับฟังก์ชันการวิเคราะห์คำของคุณ)

X สร้าง: +01

XXX สร้าง: +01: 00


0

สำหรับ Java 8: คุณสามารถใช้ inbuilt java.time.format.DateTimeFormatterเพื่อลดโอกาสในการพิมพ์ผิดเช่น

DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;

ISO_ZONED_DATE_TIME หมายถึง2011-12-03T10:15:30+01:00[Europe/Paris]หนึ่งในรูปแบบ DateTime มาตรฐานที่ให้มาโดยลิงค์ของ Oracle

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