วิธีการแยก / จัดรูปแบบวันที่ด้วย LocalDateTime (Java 8)


341

Java 8 เพิ่มjava.timeใหม่ APIสำหรับการทำงานกับวันที่และเวลา ( JSR 310 )

ฉันมีวันที่และเวลาเป็นสตริง (เช่น"2014-04-08 12:30") ฉันจะได้รับLocalDateTimeอินสแตนซ์จากสตริงที่กำหนดได้อย่างไร

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


11
FYI คนส่วนใหญ่ใช้เวลาส่วนใหญ่จะต้องการมากกว่าZonedDateTime LocalDateTimeชื่อนี้ใช้ง่าย Localหมายใด ๆท้องที่ทั่วไปมากกว่าโซนเวลาที่เฉพาะเจาะจง ดังนั้นLocalDateTimeวัตถุจะไม่ผูกติดกับเส้นเวลา เพื่อให้มีความหมายในการรับช่วงเวลาที่ระบุในเส้นเวลาคุณต้องใช้เขตเวลา
Basil Bourque

ดูคำตอบของฉันสำหรับคำอธิบายของLocalDateTimevs. ZonedDateTimevs. OffsetDateTimevs. Instantvs. LocalDatevs. LocalTimeวิธีสงบสติเกี่ยวกับสาเหตุที่ซับซ้อนและวิธีทำขวาตั้งแต่แรกนัด
Ondra Žižka

1
ถ้ามันไม่ได้ impractically ยาวอาจจะได้รับการตั้งชื่อLocalDateTime ZonelessOffsetlessDateTime
Ondra Žižka

คำตอบ:


534

แยกวันที่และเวลา

เพื่อสร้างLocalDateTimeวัตถุจากสตริงคุณสามารถใช้LocalDateTime.parse()วิธีการคงที่ มันต้องใช้สตริงและDateTimeFormatterพารามิเตอร์ DateTimeFormatterถูกใช้เพื่อระบุรูปแบบวันที่ / เวลา

String str = "1986-04-08 12:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);

การจัดรูปแบบวันที่และเวลา

ในการสร้างสตริงที่จัดรูปแบบจากLocalDateTimeวัตถุคุณสามารถใช้format()วิธีการ

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.of(1986, Month.APRIL, 8, 12, 30);
String formattedDateTime = dateTime.format(formatter); // "1986-04-08 12:30"

โปรดทราบว่ามีรูปแบบวันที่ / เวลาที่ใช้กันทั่วไปที่กำหนดไว้ล่วงหน้าเป็นค่าคงที่DateTimeFormatterมา ตัวอย่างเช่น: การใช้DateTimeFormatter.ISO_DATE_TIMEเพื่อจัดรูปแบบLocalDateTimeอินสแตนซ์จากด้านบนจะส่งผลให้สตริง"1986-04-08T12:30:00"เช่นจากข้างต้นจะส่งผลให้ในสตริง

parse()และformat()วิธีการที่ใช้ได้สำหรับทุกวัตถุ / เวลาที่เกี่ยวข้องกับวัน (เช่นLocalDateหรือZonedDateTime)


77
เพียงเพื่อให้ทราบว่า DateTimeFormatter นั้นไม่เปลี่ยนรูปและปลอดภัยต่อเธรดและดังนั้นวิธีที่แนะนำคือการจัดเก็บไว้ในค่าคงที่ที่เป็นไปได้
JodaStephen

@micha ถ้าฉันมี "2016-12-31T07: 59: 00.000Z" จะมีการกำหนดวันที่นี้หรือไม่?
Dawood Ahmed

14
@DawoodAbbasi ลองDateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
Ray Hulha

1
@ Phoenix อาจเป็นเพราะคุณกำลังพยายามโทรหาformat()LocalDateTime class แทนที่จะเป็นอินสแตนซ์ใช่ไหม? อย่างน้อยนั่นคือสิ่งที่ผมทำผมสับสนDateTimeกับdateTimeในตัวอย่างข้างต้น
glaed

2
อย่าลืมตัวพิมพ์ใหญ่ใน MM
Wesos de Queso

159

นอกจากนี้คุณยังสามารถใช้LocalDate.parse()หรือLocalDateTime.parse()ทำเครื่องหมายStringโดยไม่ระบุรูปแบบหากStringอยู่ในรูปแบบ ISO-8601รูปแบบ

ตัวอย่างเช่น,

String strDate = "2015-08-04";
LocalDate aLD = LocalDate.parse(strDate);
System.out.println("Date: " + aLD);

String strDatewithTime = "2015-08-04T10:11:30";
LocalDateTime aLDT = LocalDateTime.parse(strDatewithTime);
System.out.println("Date with Time: " + aLDT);

เอาท์พุท ,

Date: 2015-08-04
Date with Time: 2015-08-04T10:11:30

และใช้DateTimeFormatterเฉพาะเมื่อคุณต้องจัดการกับรูปแบบวันที่อื่น ๆ

ตัวอย่างเช่นในตัวอย่างต่อไปนี้dd MMM uuuuหมายถึงวันของเดือน (ตัวเลขสองหลัก) ตัวอักษรสามตัวของชื่อของเดือน (ม.ค. , ก.พ. , มี.ค. , มี.ค. , ... ) และปีสี่หลัก:

DateTimeFormatter dTF = DateTimeFormatter.ofPattern("dd MMM uuuu");
String anotherDate = "04 Aug 2015";
LocalDate lds = LocalDate.parse(anotherDate, dTF);
System.out.println(anotherDate + " parses to " + lds);

เอาท์พุต

04 Aug 2015 parses to 2015-08-04

ยังจำได้ว่าDateTimeFormatterวัตถุนั้นเป็นแบบสองทิศทาง มันสามารถแยกวิเคราะห์อินพุตและรูปแบบเอาท์พุท

String strDate = "2015-08-04";
LocalDate aLD = LocalDate.parse(strDate);
DateTimeFormatter dTF = DateTimeFormatter.ofPattern("dd MMM uuuu");
System.out.println(aLD + " formats as " + dTF.format(aLD));

เอาท์พุต

2015-08-04 formats as 04 Aug 2015

(ดูรายการรูปแบบที่สมบูรณ์สำหรับการจัดรูปแบบและการแยกวิเคราะห์ DateFormatter )

  Symbol  Meaning                     Presentation      Examples
  ------  -------                     ------------      -------
   G       era                         text              AD; Anno Domini; A
   u       year                        year              2004; 04
   y       year-of-era                 year              2004; 04
   D       day-of-year                 number            189
   M/L     month-of-year               number/text       7; 07; Jul; July; J
   d       day-of-month                number            10

   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
   Y       week-based-year             year              1996; 96
   w       week-of-week-based-year     number            27
   W       week-of-month               number            4
   E       day-of-week                 text              Tue; Tuesday; T
   e/c     localized day-of-week       number/text       2; 02; Tue; Tuesday; T
   F       week-of-month               number            3

   a       am-pm-of-day                text              PM
   h       clock-hour-of-am-pm (1-12)  number            12
   K       hour-of-am-pm (0-11)        number            0
   k       clock-hour-of-am-pm (1-24)  number            0

   H       hour-of-day (0-23)          number            0
   m       minute-of-hour              number            30
   s       second-of-minute            number            55
   S       fraction-of-second          fraction          978
   A       milli-of-day                number            1234
   n       nano-of-second              number            987654321
   N       nano-of-day                 number            1234000000

   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
   z       time-zone name              zone-name         Pacific Standard Time; PST
   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;

   p       pad next                    pad modifier      1

   '       escape for text             delimiter
   ''      single quote                literal           '
   [       optional section start
   ]       optional section end
   #       reserved for future use
   {       reserved for future use
   }       reserved for future use

11
คำตอบนี้สัมผัสกับเรื่องที่สำคัญ: ใช้ฟอร์แมตที่กำหนดไว้ล่วงหน้าทุกที่ที่ทำได้เช่นไม่สร้างฟอร์แมตเตอร์เป็น "yyyy-MM-dd" ใช้ DateTimeFormatter.OO_LOCAL_DATE แทน มันจะทำให้โค้ดของคุณดูสะอาดตากว่าเดิมมาก นอกจากนี้พยายามเพิ่มการใช้รูปแบบ ISO8061 ให้สูงสุดมันจะจ่ายเงินปันผลในระยะยาว
Christopher Yang

ฉันต้องการแยกวันที่สำหรับการตรวจสอบเช่น2018-08-09 12:00:08แต่เมื่อฉันแยกวิเคราะห์ฉันเห็นการTเพิ่มซึ่งฉันไม่ต้องการ มีวิธีทำหรือไม่?
Raghuveer

@Raghuveer ตัว T เป็นเพียงตัวคั่น ISO-8061 ระหว่างวันที่และเวลา หากคุณมีช่องว่างในรูปแบบของคุณแทนคุณสามารถใช้รูปแบบyyyy-MM-dd hh:mm:ssในการแยกวิเคราะห์และจัดรูปแบบ T จะแสดงในรูปแบบเริ่มต้น (ISO-8061) เสมอ แต่คุณสามารถใช้รูปแบบของคุณเอง
Egor Hans

39

คำตอบทั้งสองข้างต้นอธิบายคำถามเกี่ยวกับรูปแบบสตริงได้ดีมาก อย่างไรก็ตามในกรณีที่คุณทำงานกับISO 8601 คุณไม่จำเป็นต้องสมัครDateTimeFormatterเนื่องจาก LocalDateTime ได้เตรียมไว้แล้ว:

แปลง LocalDateTime เป็น Time Zone ISO8601 String

LocalDateTime ldt = LocalDateTime.now(); 
ZonedDateTime zdt = ldt.atZone(ZoneOffset.UTC); //you might use a different zone
String iso8601 = zdt.toString();

แปลงจากสตริง ISO8601 กลับเป็น LocalDateTime

String iso8601 = "2016-02-14T18:32:04.150Z";
ZonedDateTime zdt = ZonedDateTime.parse(iso8601);
LocalDateTime ldt = zdt.toLocalDateTime();

20

การแยกสตริงที่มีวันที่และเวลาเป็นช่วงเวลาใดเวลาหนึ่ง (Java เรียกว่า " Instant") ค่อนข้างซับซ้อน Java ได้แก้ปัญหานี้ในการทำซ้ำหลาย ๆ ล่าสุดjava.timeและjava.time.chronoครอบคลุมเกือบทุกความต้องการ (ยกเว้นการขยายเวลา) :))

อย่างไรก็ตามความซับซ้อนนั้นทำให้เกิดความสับสนมากมาย

กุญแจสำคัญในการทำความเข้าใจการแยกวันที่คือ:

ทำไม Java มีหลายวิธีในการวิเคราะห์วันที่

  1. มีหลายระบบในการวัดเวลา ยกตัวอย่างเช่นปฏิทินประวัติศาสตร์ของญี่ปุ่นได้รับมาจากช่วงเวลาของรัชสมัยของจักรพรรดิหรือราชวงศ์ จากนั้นก็มีเช่นการประทับเวลา UNIX โชคดีที่โลกทั้งโลก (ธุรกิจ) สามารถใช้งานได้เหมือนกัน
  2. ในอดีตระบบถูกเปลี่ยนจาก / เป็นด้วยเหตุผลต่างๆเหตุผลต่างๆเช่นจากปฏิทิน Julian ถึงปฏิทิน Gregorian ในปี 1582 ดังนั้นวันที่ 'ตะวันตก' ก่อนหน้านั้นจะต้องได้รับการปฏิบัติแตกต่างกัน
  3. และแน่นอนการเปลี่ยนแปลงไม่ได้เกิดขึ้นพร้อมกัน เนื่องจากปฏิทินดังกล่าวมาจากสำนักงานใหญ่ของศาสนาและส่วนอื่น ๆ ของยุโรปที่เชื่อในการควบคุมอาหารอื่น ๆ เช่นเยอรมนีไม่ได้เปลี่ยนจนกระทั่งปี 1700

... และทำไมจึงเป็นLocalDateTimeเช่นZonedDateTimeนั้น ซับซ้อนมาก

  1. มีโซนเวลา เขตเวลานั้นโดยทั่วไปจะเป็น "แถบ" * [1]ของพื้นผิวโลกซึ่งเจ้าหน้าที่ปฏิบัติตามกฎเดียวกันว่าจะมีการชดเชยเวลาเมื่อใด ซึ่งรวมถึงกฎเวลาฤดูร้อน
    เขตเวลาเปลี่ยนแปลงไปตามกาลเวลาสำหรับพื้นที่ต่างๆโดยส่วนใหญ่ขึ้นอยู่กับว่าใครจะเป็นใคร และกฎของเขตเวลาหนึ่งก็เปลี่ยนไปตามกาลเวลาเช่นกัน

  2. มีการชดเชยเวลา ไม่เหมือนกับเขตเวลาเนื่องจากเขตเวลาอาจเป็นเช่น "ปราก" แต่มีการชดเชยเวลาฤดูร้อนและชดเชยเวลาฤดูหนาว
    หากคุณได้รับการประทับเวลาที่มีเขตเวลาการชดเชยอาจแตกต่างกันไปขึ้นอยู่กับส่วนของปีที่อยู่ในช่วงเวลากระโดดชั่วโมงการประทับเวลาอาจหมายถึง 2 ครั้งที่แตกต่างกันดังนั้นจึงไม่มีข้อมูลเพิ่มเติม แปลง
    หมายเหตุ: ตามการประทับเวลาฉันหมายถึง "สตริงที่มีวันที่และ / หรือเวลาเลือกที่จะมีเขตเวลาและ / หรือเวลาชดเชย"

  3. หลายเขตเวลาอาจใช้เวลาเดียวกันร่วมกันในบางช่วงเวลา ตัวอย่างเช่นเขตเวลา GMT / UTC เหมือนกับเขตเวลา "ลอนดอน" เมื่อการชดเชยเวลาฤดูร้อนไม่มีผล

หากต้องการทำให้ซับซ้อนขึ้นเล็กน้อย (แต่นั่นไม่สำคัญสำหรับกรณีการใช้งานของคุณ):

  1. นักวิทยาศาสตร์สังเกตการเปลี่ยนแปลงของโลกซึ่งเปลี่ยนแปลงตลอดเวลา ขึ้นอยู่กับว่าพวกเขาเพิ่มวินาทีในตอนท้ายของแต่ละปี (ดังนั้น2040-12-31 24:00:00อาจเป็นวันที่และเวลาที่ถูกต้อง) สิ่งนี้ต้องการการปรับปรุงข้อมูลเมตาเป็นประจำที่ระบบใช้เพื่อให้การแปลงวันที่ถูกต้อง เช่นบน Linux คุณจะได้รับการอัปเดตเป็นประจำสำหรับแพ็คเกจ Java รวมถึงข้อมูลใหม่เหล่านี้
  2. การปรับปรุงไม่ได้เก็บพฤติกรรมก่อนหน้านี้ไว้เสมอสำหรับทั้งการบันทึกเวลาในอดีตและในอนาคต ดังนั้นอาจเกิดขึ้นได้เมื่อวิเคราะห์การประทับเวลาสองครั้งรอบ ๆ การเปลี่ยนแปลงของเขตเวลาเมื่อเปรียบเทียบกับการเปลี่ยนแปลงเหล่านั้นอาจให้ผลลัพธ์ที่แตกต่างกันเมื่อทำงานกับซอฟต์แวร์รุ่นต่าง ๆ ซึ่งยังใช้กับการเปรียบเทียบระหว่างเขตเวลาที่ได้รับผลกระทบกับเขตเวลาอื่น

    ควรเหตุนี้ข้อผิดพลาดในซอฟต์แวร์ของคุณให้พิจารณาใช้การประทับเวลาบางส่วนที่ไม่ได้มีกฎระเบียบที่ซับซ้อนดังกล่าวเช่นUNIX ประทับเวลา

  3. เนื่องจาก 7 สำหรับวันที่ในอนาคตเราไม่สามารถแปลงวันที่อย่างแน่นอนด้วยความแน่นอน ตัวอย่างเช่นการวิเคราะห์คำในปัจจุบัน8524-02-17 12:00:00อาจไม่กี่วินาทีจากการวิเคราะห์คำในอนาคต

API ของ JDK สำหรับสิ่งนี้ได้รับการพัฒนาตามความต้องการร่วมสมัย

  • Java รุ่นแรกนั้นjava.util.Dateมีวิธีการที่ไร้เดียงสาเพียงเล็กน้อยโดยสมมติว่ามีเพียงปีเดือนวันและเวลา เรื่องนี้ไม่เร็วพอ
  • นอกจากนี้ความต้องการของฐานข้อมูลก็มีความแตกต่างกันดังนั้นจึงมีการเริ่มใช้งานเร็วมากjava.sql.Dateด้วยข้อ จำกัด ของตัวเอง
  • เนื่องจากไม่ครอบคลุมทั้งปฏิทินและเขตเวลาที่แตกต่างกันCalendarจึงมีการแนะนำ API
  • สิ่งนี้ยังไม่ครอบคลุมความซับซ้อนของเขตเวลา และถึงกระนั้นการผสมผสานของ API ข้างต้นก็เป็นความเจ็บปวดที่จะทำงานด้วย ดังนั้นเมื่อนักพัฒนา Java เริ่มทำงานกับเว็บแอพพลิเคชั่นทั่วโลกห้องสมุดที่ตั้งเป้าหมายการใช้งานส่วนใหญ่เช่น JodaTime จะได้รับความนิยมอย่างรวดเร็ว JodaTime เป็นมาตรฐานจริงประมาณสิบปี
  • แต่ JDK ไม่ได้รวมกับ JodaTime ดังนั้นการทำงานกับมันจึงค่อนข้างยุ่งยาก ดังนั้นหลังจากการพูดคุยกันนานมากเกี่ยวกับวิธีการเข้าถึงเรื่องนี้JSR-310จึงถูกสร้างขึ้นตาม JodaTime เป็นหลัก

วิธีจัดการกับมันในภาษาจาวา java.time

กำหนดประเภทที่จะแยกวิเคราะห์เวลา

เมื่อคุณใช้สตริงการประทับเวลาคุณจำเป็นต้องทราบข้อมูลที่มีอยู่ นี่คือจุดสำคัญ หากคุณไม่ได้รับสิทธินี้คุณจะพบกับข้อยกเว้นที่เป็นความลับเช่น "ไม่สามารถสร้างได้ทันที" หรือ "โซนออฟเซ็ตหายไป" หรือ "รหัสโซนที่ไม่รู้จัก" เป็นต้น

มันมีวันที่และเวลาหรือไม่?

  1. มันมีเวลาชดเชยหรือไม่?
    การชดเชยเวลาเป็น+hh:mmส่วนหนึ่ง บางครั้ง+00:00อาจถูกแทนที่ด้วยZ'เวลาซูลู' UTCตามเวลาสากลเชิงพิกัดหรือGMTเวลามาตรฐานกรีนิช สิ่งเหล่านี้ยังตั้งค่าเขตเวลา สำหรับการประทับเวลาเหล่านี้คุณใช้
    OffsetDateTime

  2. มีเขตเวลาหรือไม่? สำหรับการประทับเวลาเหล่านี้คุณใช้
    โซนจะถูกระบุด้วยZonedDateTime

    • ชื่อ ("ปราก", "เวลามาตรฐานแปซิฟิก", "PST") หรือ
    • "เขต ID" ( "อเมริกา / Los_Angeles", "ยุโรป / ลอนดอน") แสดงโดยjava.time.ZoneId

    รายการของเขตเวลาจะถูกรวบรวมโดย"ฐานข้อมูล TZ"ซึ่งได้รับการสนับสนุนโดย ICAAN

    ตามZoneIdjavadoc ของ id โซนยังสามารถระบุเป็นZและชดเชย ฉันไม่แน่ใจว่าแผนที่นี้เป็นโซนจริงได้อย่างไร หากการประทับเวลาซึ่งมีเพียง TZ เท่านั้นที่ตกอยู่ในการเปลี่ยนแปลงออฟเซ็ตของการกระโดดข้ามเวลาแสดงว่ามันไม่ชัดเจนและการตีความนั้นเป็นเรื่องของResolverStyleดูด้านล่าง

  3. ถ้ามันไม่มีทั้งบริบทที่หายไปจะถือว่าหรือละเลย และผู้บริโภคจะต้องตัดสินใจ ดังนั้นจึงต้องมีการแยกวิเคราะห์LocalDateTimeและแปลงเป็นOffsetDateTimeโดยการเพิ่มข้อมูลที่ขาดหายไป:

    • คุณสามารถสันนิษฐานได้ว่ามันเป็นเวลา UTC เพิ่ม UTC ออฟเซ็ต 0 ชั่วโมง
    • คุณสามารถสันนิษฐานได้ว่ามันเป็นช่วงเวลาของสถานที่ที่เกิดการแปลงเกิดขึ้น แปลงโดยเพิ่มเขตเวลาของระบบ
    • คุณสามารถละเลยและใช้มันได้ตามที่เป็นอยู่ สิ่งนี้มีประโยชน์เช่นการเปรียบเทียบหรือย่อส่วนสองครั้ง (ดูDuration) หรือเมื่อคุณไม่รู้และไม่สำคัญ (เช่นตารางรถบัสท้องถิ่น)

ข้อมูลเวลาบางส่วน

  • จากสิ่งที่ประทับเวลามีคุณสามารถใช้LocalDate, LocalTime, OffsetTime, MonthDay, YearหรือYearMonthออกจากมัน

หากคุณมีข้อมูลที่ครบถ้วน, java.time.Instantคุณจะได้รับ นี้จะใช้ภายในการแปลงระหว่างและOffsetDateTimeZonedDateTime

คิดวิธีการแยกมัน

มีเอกสารมากมายDateTimeFormatterที่สามารถแยกสตริงเวลาประทับและรูปแบบเป็นสตริงได้

ก่อนสร้างDateTimeFormattersควรจะครอบคลุมเพิ่มเติมน้อยลงทุกรูปแบบการประทับเวลามาตรฐาน ยกตัวอย่างเช่นสามารถแยกISO_INSTANT2011-12-03T10:15:30.123457Z

หากคุณมีรูปแบบพิเศษบางอย่างคุณสามารถสร้าง DateTimeFormatter ของคุณเอง (ซึ่งเป็นตัวแยกวิเคราะห์)

private static final DateTimeFormatter TIMESTAMP_PARSER = new DateTimeFormatterBuilder()
   .parseCaseInsensitive()
   .append(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SX"))
   .toFormatter();

ผมขอแนะนำให้ไปดูที่รหัสที่มาของและได้รับแรงบันดาลใจในการสร้างโดยใช้DateTimeFormatter DateTimeFormatterBuilderในขณะที่คุณอยู่ที่นั่นให้ดูที่ResolverStyleการควบคุมว่าตัวแยกวิเคราะห์เป็น LENIENT, SMART หรือ STRICT สำหรับรูปแบบและข้อมูลที่คลุมเครือ

TemporalAccessor

TemporalAccessorตอนนี้ความผิดพลาดที่พบบ่อยคือเข้าไปในความซับซ้อนของ SimpleDateFormatter.parse(String)นี้มาจากวิธีการที่นักพัฒนาที่ถูกนำมาใช้ในการทำงานกับ ขวาช่วยให้คุณDateTimeFormatter.parse("...")TemporalAccessor

// No need for this!
TemporalAccessor ta = TIMESTAMP_PARSER.parse("2011-... etc");

แต่พร้อมกับความรู้จากส่วนก่อนหน้าคุณสามารถแยกประเภทที่คุณต้องการ:

OffsetDateTime myTimestamp = OffsetDateTime.parse("2011-12-03T10:15:30.123457Z", TIMESTAMP_PARSER);

คุณไม่จำเป็นต้องจริงไปDateTimeFormatterอย่างใดอย่างหนึ่ง ประเภทที่คุณต้องการแยกวิเคราะห์มีparse(String)วิธีการ

OffsetDateTime myTimestamp = OffsetDateTime.parse("2011-12-03T10:15:30.123457Z");

เกี่ยวกับTemporalAccessorคุณสามารถใช้งานได้หากคุณมีความคิดที่คลุมเครือเกี่ยวกับข้อมูลที่มีอยู่ในสตริงและต้องการตัดสินใจใช้งานจริง

ฉันหวังว่าฉันจะเข้าใจถึงความรู้สึกของคุณ :)

หมายเหตุ: มีการย้ายกลับของเป็นjava.time: ชวา 6 และ 7 ThreeTen-ย้ายกลับ สำหรับ Android มันมีThreeTenABP

[1]ไม่ใช่แค่ว่าพวกเขาไม่ใช่ลายทาง แต่ยังมีความสุดขั้วอีกด้วย ตัวอย่างเช่นบางเกาะแปซิฟิกที่อยู่ใกล้เคียงมีเขตเวลา +14: 00 และ -11: 00 หมายความว่าขณะที่อยู่บนเกาะหนึ่งมี 1 พฤษภาคม 15:00 บนเกาะอื่นไม่ไกลมันยังคงเป็น 30 เมษายน 12 น. (หากฉันนับถูกต้อง :)


3

รับเวลา UTC ปัจจุบันในรูปแบบที่จำเป็น

// Current UTC time
        OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);

        // GET LocalDateTime 
        LocalDateTime localDateTime = utc.toLocalDateTime();
        System.out.println("*************" + localDateTime);

        // formated UTC time
        DateTimeFormatter dTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        System.out.println(" formats as " + dTF.format(localDateTime));

        //GET UTC time for current date
        Date now= new Date();
        LocalDateTime utcDateTimeForCurrentDateTime = Instant.ofEpochMilli(now.getTime()).atZone(ZoneId.of("UTC")).toLocalDateTime();
        DateTimeFormatter dTF2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        System.out.println(" formats as " + dTF2.format(utcDateTimeForCurrentDateTime));

0

ฉันพบว่ามันวิเศษมากที่จะครอบคลุมรูปแบบวันที่หลายรูปแบบเช่นนี้:

final DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
dtfb.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSS"))
    .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
    .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS"))
    .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0);

1
`` `สาธารณะสุดท้ายคง DateTimeFormatter TIMESTAMP_XX = ใหม่ DateTimeFormatterBuilder (). appendPattern (" [[uuuu] [- MM] [- dd]] [[HH] [: mm] [: SS] parseDefaulting (ChronoField.YEAR, 2020) .ParseDefaulting (ChronoField.MONTH_OOF_YEUTE_Defaulting (ChronoField.CONDONDONFOFDY), ARDDDFORTER (ChronoField.CONDONFONDY) , 0) .parseDefaulting (ChronoField.NANO_OF_SECOND, 0) .toFormatter (); `` `
อลันสจ๊วต
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.