JavaRush /จาวาบล็อก /Random-TH /ในที่สุดไลบรารี่ที่ใช้งานง่ายและมีประสิทธิภาพสำหรับการทำง...
theGrass
ระดับ
Саратов

ในที่สุดไลบรารี่ที่ใช้งานง่ายและมีประสิทธิภาพสำหรับการทำงานกับเวลาและวันที่ก็พร้อมใช้งานแล้วใน Java (ตอนที่ 2)

เผยแพร่ในกลุ่ม
เวลาของวัน
    เรามาต่อกันดีกว่า เอนทิตีถัด ไปหลังจาก date คือเวลาของวัน ซึ่งแสดงโดย คลาส LocalTime ตัวอย่างคลาสสิกจะแสดงเวลาเปิดทำการของร้านค้า เช่น ตั้งแต่เวลา 7.00 น. ถึง 23.00 น. ร้านค้าที่เปิดในเวลานี้ทั่วประเทศ แต่เวลาจริงจะแตกต่างกันไปขึ้นอยู่กับเขตเวลา     LocalTimeเป็นคลาสค่าที่เก็บเฉพาะเวลา โดยไม่มีวันที่หรือเขตเวลาที่เกี่ยวข้อง เมื่อบวกหรือลบระยะเวลาจะตัดเวลาเที่ยงคืน นั่นคือ 20:00 น. บวก 6 ชั่วโมงคือ 2:00 น. การใช้LocalTimeนั้นคล้ายคลึงกับLocalDate : LocalTime time = LocalTime.of(20, 30); int hour = date.getHour(); // 20 int minute = date.getMinute(); // 30 time = time.withSecond(6); // 20:30:06 time = time.plusMinutes(3); // 20:33:06     ตัวดัดแปลงสามารถทำงานร่วมกับLocalTimeได้ แต่โดยปกติแล้วการดำเนินการด้านเวลาจะไม่ซับซ้อนจนจำเป็นต้องมีตัวดัดแปลง
ผสมผสานวันที่และเวลา
    คลาสต่อไปที่เราจะดูคือ LocalDateTime คลาสค่า นี้เป็นการรวมกันของ LocalDateและ LocalTime แสดงถึงทั้งวันที่และเวลาโดยไม่มีเขตเวลา      LocalDateTimeสามารถสร้างได้โดยตรงหรือโดยการรวมวันที่และเวลา: LocalDateTime dt1 = LocalDateTime.of(2014, Month.JUNE, 10, 20, 30); LocalDateTime dt2 = LocalDateTime.of(date, time); LocalDateTime dt3 = date.atTime(20, 30); LocalDateTime dt4 = date.atTime(time);     ตัวเลือกที่สามและสี่ใช้ เมธอด atTime()ซึ่งให้วิธีที่ยืดหยุ่นในการรวมวันที่และเวลา คลาสของระบบวันที่และเวลาส่วนใหญ่มีเมธอด "at" ที่สามารถใช้เพื่อรวมอ็อบเจ็กต์ของคุณเข้ากับคลาสอื่นเพื่อสร้างคลาสที่ซับซ้อนมากขึ้น วิธีการอื่นๆ ของคลาส LocalDateTimeนั้นคล้ายคลึงกับวิธีการของ LocalDateและ LocalTime รูปแบบการตั้งชื่อวิธีการที่คล้ายกันทำให้ APIเรียนรู้ได้ง่ายขึ้น ตารางนี้แสดงรายการคำนำหน้าวิธีการที่เกี่ยวข้องทั้งหมด: ในที่สุดไลบรารี่ที่ใช้งานง่ายและมีประสิทธิภาพสำหรับการทำงานกับเวลาและวันที่ก็พร้อมใช้งานแล้วใน Java (ตอนที่ 2)  - 1
ทันที
    เมื่อเราจัดการกับวันที่และเวลา เรามักจะทำงานกับปี เดือน วัน ชั่วโมง นาที วินาที อย่างไรก็ตาม นี่เป็นเพียงรูปแบบหนึ่งของเวลาที่สามารถเรียกได้ว่าเป็น "มนุษย์" แบบที่สองที่ใช้กันทั่วไปคือเวลา "เครื่องจักร" หรือ "ต่อเนื่อง" ในแบบจำลองนี้ จุดบนแกนเวลาจะแสดงด้วยตัวเลขขนาดใหญ่ตัวเดียว วิธีการนี้ทำให้อัลกอริทึมการคำนวณง่ายขึ้น และใช้เพื่อจัดเก็บเวลาใน ระบบปฏิบัติการ Unixโดยที่เวลาจะแสดงด้วยจำนวนวินาทีที่ผ่านไปตั้งแต่วันที่ 1 มกราคม 1970 ในทำนองเดียวกันใน Javaเวลาจะถูกจัดเก็บเป็นจำนวนมิลลิวินาทีที่ผ่านไปตั้งแต่วันที่ 1 มกราคม 1970 วิธีการคำนวณเวลาของเครื่องในjava.time API จัดทำโดยคลาส Instant value โดยให้ความสามารถในการแสดงจุดบนแกนเวลาโดยไม่ต้องมีข้อมูลประกอบทั้งหมด เช่น เขตเวลา ที่จริงแล้ว คลาสนี้ประกอบด้วยจำนวนนาโนวินาทีที่ผ่านไปตั้งแต่เที่ยงคืนของวันที่ 1 มกราคม 1970 Instant start = Instant.now(); // произведем вычисления Instant end = Instant.now(); assert end.isAfter(start); //машина времени не сработала     โดยทั่วไปแล้ว คลาส Instantจะใช้ในการจัดเก็บและเปรียบเทียบคะแนนในเวลาที่คุณต้องการจัดเก็บเมื่อมีเหตุการณ์บางอย่างเกิดขึ้น แต่คุณไม่สนใจเขตเวลาที่เหตุการณ์นั้นเกิดขึ้น ในกรณีส่วนใหญ่ สิ่งที่น่าสนใจกว่าสิ่งที่เราทำกับ คลาส Instant ไม่ได้ มากกว่าสิ่งที่เราสามารถทำได้ ตัวอย่างเช่น บรรทัดของโค้ดต่อไปนี้จะเกิดข้อยกเว้น: instant.get(ChronoField.MONTH_OF_YEAR); instant.plus(6, ChronoUnit.YEARS);     ข้อยกเว้นเกิดขึ้นเนื่องจาก วัตถุ ทันทีเก็บเฉพาะจำนวนนาโนวินาที และไม่ได้ให้ความสามารถในการทำงานกับหน่วยเวลาที่เป็นประโยชน์ต่อมนุษย์มากกว่า หากต้องการใช้หน่วยวัดอื่น อย่างน้อยคุณต้องระบุเขตเวลา
โซนเวลา
    หลักการของเขตเวลาได้รับการพัฒนาในประเทศอังกฤษ เมื่อมีการประดิษฐ์ทางรถไฟและการปรับปรุงวิธีการสื่อสารอื่นๆ ทำให้ผู้คนสามารถเดินทางในระยะทางที่เพียงพอเพื่อให้เห็นความแตกต่างของเวลาสุริยะได้ จนถึงขณะนี้ แต่ละหมู่บ้านและเมืองต่างใช้ชีวิตตามเวลาของตนเอง ซึ่งส่วนใหญ่มักวัดด้วยนาฬิกาแดด รูปภาพนี้แสดงตัวอย่างความยากลำบากที่นำไปสู่สิ่งนี้ - เข็มสีแดงบนนาฬิกาแสดงเวลากรีนิช และเข็มสีดำแสดงเวลาท้องถิ่น ซึ่งต่างกัน 10 นาที: ระบบโซนเวลาที่พัฒนาขึ้นมาแทนที่เวลาสุริยะใน ในที่สุดไลบรารี่ที่ใช้งานง่ายและมีประสิทธิภาพสำหรับการทำงานกับเวลาและวันที่ก็พร้อมใช้งานแล้วใน Java (ตอนที่ 2)  - 2     ท้องถิ่น แต่ข้อเท็จจริงที่สำคัญก็คือเขตเวลาถูกสร้างขึ้นโดยนักการเมือง และมักจะใช้เพื่อแสดงให้เห็นถึงการควบคุมทางการเมืองเหนือพื้นที่หนึ่งๆ เช่นเดียวกับนโยบายอื่นๆ กฎที่เกี่ยวข้องกับเขตเวลามักจะท้าทายตรรกะ นอกจากนี้ กฎเหล่านี้สามารถเปลี่ยนแปลงได้และมักจะเปลี่ยนแปลงโดยไม่มีการเตือนล่วงหน้า กฎเขตเวลารวบรวมโดยกลุ่มระหว่างประเทศที่เผยแพร่ ฐาน ข้อมูล เขตเวลา IANA ประกอบด้วยตัวระบุของแต่ละภูมิภาคของโลก และประวัติของเขตเวลาจะเปลี่ยนแปลงไป ตัวระบุมีลักษณะเป็น "ยุโรป/ลอนดอน"หรือ" อเมริกา/นิวยอร์ก" ก่อนที่ java.time API จะออก คลาส TimeZoneจะถูกนำมาใช้เพื่อแสดงเขตเวลา ตอนนี้ ใช้ ZoneIdแทน มีความแตกต่างที่สำคัญสองประการระหว่างพวกเขา ประการแรก ZoneIdจะไม่เปลี่ยนรูป ซึ่งทำให้สามารถจัดเก็บอ็อบเจ็กต์ของคลาสนี้เป็นตัวแปรคงที่ได้ และอื่นๆ อีกมากมาย ประการที่สอง ตัวกฎจะถูกจัดเก็บไว้ใน คลาส ZoneRulesไม่ใช่ใน ZoneIdเองและเพื่อให้ได้กฎนั้น คุณจะต้องเรียกใช้ เมธอด getRules() บน อ็อบเจ็กต์คลาส ZoneId คุณลักษณะทั่วไปของเขตเวลาทั้งหมดคือการชดเชยคงที่จาก UTC/ Greenwich ส่วนใหญ่คุณมักจะใช้คำนี้เมื่อพูดถึงความแตกต่างของเวลาระหว่างเมืองต่างๆ เช่น "นิวยอร์กช้ากว่าลอนดอน 5 ชั่วโมง" คลาส ZoneOffsetซึ่งเป็นคลาสสืบทอดของ ZoneIdแสดงถึงความแตกต่างของเวลากับเส้นลมปราณสำคัญที่ผ่านกรีนิชในลอนดอน จากมุมมองของนักพัฒนา จะเป็นการดีที่ไม่ต้องจัดการกับเขตเวลาและความซับซ้อนของเขตเวลา java.time APIช่วยให้คุณดำเนินการนี้ได้ตราบเท่าที่เป็นไปได้ หากเป็นไปได้ ให้ใช้ คลาส LocalDate, LocalTime, LocalDateTime และ Instant ในกรณีที่คุณไม่สามารถทำได้ โดยไม่มีเขตเวลา ให้ใช้ คลาส ZonedDateTime คลาส ZonedDateTimeช่วยให้คุณสามารถแปลงวันที่และเวลาจากหน่วยการวัดของมนุษย์ซึ่งเราเห็นในปฏิทินและนาฬิกาเป็นหน่วยเครื่องจักร ด้วยเหตุนี้ คุณสามารถสร้าง ZonedTimeDateจาก คลาส Localหรือจาก คลาส Instant : ZoneId zone = ZoneId.of("Europe/Paris"); LocalDate date = LocalDate.of(2014, Month.JUNE, 10); ZonedDateTime zdt1 = date.atStartOfDay(zone); Instant instant = Instant.now(); ZonedDateTime zdt2 = instant.atZone(zone);     หนึ่งในคุณสมบัติที่ไม่พึงประสงค์ที่สุดของเขตเวลาคือสิ่งที่เรียกว่าเวลาออมแสง เมื่อเวลาออมแสงสลับไปและกลับจากกรีนิช ความแตกต่างของเขตเวลาของคุณกับกรีนิชจะเปลี่ยนสองครั้ง (หรือมากกว่า) ต่อปี โดยปกติจะเพิ่มขึ้นในฤดูใบไม้ผลิและลดลงในฤดูใบไม้ร่วง เมื่อสิ่งนี้เกิดขึ้นเราต้องเปลี่ยนนาฬิกาทั้งหมดในบ้านของเรา ใน คลาส java.timeข้อมูลออฟเซ็ตจะแสดงเป็น" การแปลงออฟเซ็ต" ในฤดูใบไม้ผลิ สิ่งนี้ทำให้เกิด "ช่องว่าง" ของเวลา เมื่อค่าของเวลาบางค่าเป็นไปไม่ได้ และในฤดูใบไม้ร่วง ในทางกลับกัน ค่าของเวลาบางค่าจะเกิดขึ้นสองครั้ง ทั้งหมดนี้ได้รับการสนับสนุนโดย คลาส ZonedDateTimeผ่านวิธีการจากโรงงานและวิธีการแปลง ตัวอย่างเช่น การเพิ่มหนึ่งวันจะเพิ่มวันตามตรรกะ ซึ่งสามารถแสดงได้มากหรือน้อยกว่า 24 ชั่วโมงหากเราสลับไปเป็นเวลาออมแสงหรือย้อนกลับ ใน ทำนอง เดียวกัน เมธอด atStartOfDay()ได้รับการตั้งชื่อเช่นนั้น เนื่องจากเราไม่สามารถรับประกันได้ว่าวันนั้นจะเริ่มตอนเที่ยงคืนพอดี เราต้องคำนึงถึงช่องว่างของเวลาเมื่อเปลี่ยนมาใช้การปรับเวลาตามฤดูกาล และเคล็ดลับสุดท้ายประการหนึ่งเกี่ยวกับเวลาออมแสง หากคุณต้องการแสดงให้เห็นว่าคุณได้คำนึงถึงเวลาที่ทับซ้อนกันระหว่างการเปลี่ยนจากฤดูร้อนเป็นฤดูหนาว (เมื่อค่าเวลาเดียวกันปรากฏขึ้นสองครั้ง) คุณสามารถใช้หนึ่งในสองวิธีพิเศษที่ออกแบบมาสำหรับสถานการณ์ดังกล่าว: วิธีการเหล่านี้จะส่งกลับก่อนหน้านี้หรือหลังจากนั้น zdt = zdt.withEarlierOffsetAtOverlap(); zdt = zdt.withLaterOffsetAtOverlap();     ค่า หากวัตถุติดอยู่ในการทับซ้อนกันระหว่างการเปลี่ยนจากฤดูร้อนเป็นเวลาฤดูหนาว ในสถานการณ์อื่นๆ ทั้งหมด ค่าที่ส่งคืนจะเหมือนกัน
ช่วงเวลา
    ชั้นเรียนทั้งหมดที่เราพูดคุยกันก่อนหน้านี้เป็นประเด็นในไทม์ไลน์ จำเป็นต้องมีคลาสค่าเพิ่มเติมสองคลาสเพื่อแสดงช่วงเวลา คลาส Durationแสดงถึงระยะเวลา โดยมีหน่วยเป็นวินาทีและนาโนวินาที เช่น “23.6 วินาที” คลาส Periodแสดงถึงช่วงเวลาที่วัดเป็นปี เดือน และวัน ตัวอย่างเช่น - “3 ปี 2 เดือน 6 ​​วัน” สามารถเพิ่มหรือลบช่วงเวลาเหล่านี้ออกจากวันที่หรือเวลาได้: Period sixMonths = Period.ofMonths(6); LocalDate date = LocalDate.now(); LocalDate future = date.plus(sixMonths);
การจัดรูปแบบและการแยกวิเคราะห์
    แพคเกจทั้งหมดได้รับการออกแบบมาเพื่อจัดรูปแบบและแสดงวันที่และเวลา- java.time.format แพ็คเกจหมุนรอบ คลาส DateTimeFormatterและโรงงาน DateTimeFormatterBuilder วิธีทั่วไปในการสร้างฟอร์แมตเตอร์คือการใช้วิธีสแตติกและค่าคงที่ใน DateTimeFormatterได้แก่:
  • ค่าคงที่สำหรับรูปแบบทั่วไปที่อธิบายไว้ใน ISO เช่น ISO_LOCAL_DATE
  • รูปแบบที่ระบุด้วยตัวอักษร เช่น ofPattern("dd/MM/uuuu")
  • สไตล์ที่แปลแล้ว เช่น ofLocalizedDate(FormatStyle.MEDIUM)
    เมื่อคุณสร้างฟอร์แมตเตอร์แล้ว โดยทั่วไปคุณจะใช้มันโดยส่งต่อไปยังเมธอดคลาสวันที่ที่เหมาะสม: DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/uuuu"); LocalDate date = LocalDate.parse("24/06/2014", f); String str = date.format(f);     ด้วยวิธีนี้ โค้ดที่รับผิดชอบในการจัดรูปแบบเอาต์พุตวันที่จะถูกแยกออกเป็นคลาสที่แยกจากกัน หากคุณต้องการระบุภาษาแยกต่างหากสำหรับการจัดรูปแบบวันที่ ให้ใช้เมธอด ตัวจัดรูปแบบ withLocale(Locale) คลาสที่รับผิดชอบเกี่ยวกับปฏิทิน เขตเวลา และอินพุต/เอาท์พุตของตัวเลขเศษส่วนมีวิธีการที่คล้ายกัน หากคุณต้องการตัวเลือกการปรับแต่งเพิ่มเติม โปรดดูเอกสารประกอบสำหรับ คลาส DateTimeFormatterBuilderซึ่งช่วยให้คุณสร้างตัวจัดรูปแบบที่ซับซ้อนทีละขั้นตอน นอกจากนี้ยังช่วยให้คุณตั้งค่าการแยกวิเคราะห์ข้อความที่ไม่คำนึงถึงขนาดตัวพิมพ์ ละเว้นข้อผิดพลาดในการแยกวิเคราะห์ ตั้งค่าออฟเซ็ต และองค์ประกอบเสริม
บรรทัดล่าง
     java.time APIเป็นโมเดลที่ครอบคลุมใหม่สำหรับการทำงานกับวันที่และเวลาในJava SE 8 นำแนวคิดและการนำไปปฏิบัติจาก Joda-Timeไปสู่อีกระดับ และในที่สุดช่วยให้นักพัฒนาหลีกเลี่ยงการใช้ java.util.Dateและ Calendar ตอนนี้การทำงานตามวันที่และเวลาเป็นเรื่องสนุก!      บทความต้นฉบับ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION