ความแตกต่างระหว่าง Java 8 Date Time API (java.time) และ Joda-Time


264

ฉันรู้ว่ามีคำถามที่เกี่ยวข้องกับjava.util.Dateและ Joda-Time แต่หลังจากการขุดบางอย่างผมไม่สามารถหาหัวข้อเกี่ยวกับความแตกต่างระหว่างที่java.time API (ใหม่ในJava 8กำหนดโดยJSR 310 ) และJoda เวลา

ฉันได้ยินมาว่า java.time API ของ Java 8 นั้นสะอาดกว่าและสามารถทำได้มากกว่า Joda-Time แต่ฉันไม่สามารถหาตัวอย่างเปรียบเทียบทั้งสองได้

  • java.time ทำอะไรได้บ้างที่ Joda-Time ไม่สามารถทำได้?
  • java.time ทำอะไรได้ดีกว่า Joda-Time
  • ประสิทธิภาพดีขึ้นด้วย java.time หรือไม่

8
ไม่ใช่ว่าเกี่ยวข้องกับ Java 7 ไม่ใช่ Java 8 คำตอบสำหรับคำถามนั้นถูกแก้ไขสำหรับ Java 8 ที่มีรายละเอียดน้อยมาก คำถามของฉันโดยเฉพาะคือถามเกี่ยวกับ DateTime API ใหม่ของ Java 8 ไม่ใช่ java.util.Date ของ Java 7 ฉันแค่มองหาคำตอบที่เปรียบเทียบ Java 8 กับ JodaTime
แซค

2
บางทีเอกสาร Oracle นี้สามารถช่วยคุณได้
MarioDS

หากคุณมี Java 7 ให้ใช้ไลบรารีเพิ่มเติมหากคุณมี Java 8 ให้ใช้ไลบรารีในตัว เนื่องจากห้องสมุดทั้งสองได้รับการออกแบบโดยบุคคลเดียวกันโดยทั่วไปฉันไม่แน่ใจว่าความแตกต่างที่สำคัญที่คุณคาดหวังคืออะไร
Peter Lawrey

2
@PeterLawrey: Joda-Time และ Java 8 date and time API นั้นแตกต่างกันมาก
jarnbjo

5
คุณสามารถอ่านโพสต์บล็อกนี้จาก Stephen Colbourne - ผู้เขียนหลักของทั้งสองโครงการ
Matt Johnson-Pint

คำตอบ:


416

คุณสมบัติทั่วไป

a) ห้องสมุดทั้งสองใช้ประเภทที่ไม่เปลี่ยนรูป Joda MutableDateTimeเวลานอกจากนี้ยังมีประเภทที่ไม่แน่นอนเพิ่มเติมเช่น

b) นอกจากนี้: ห้องสมุดทั้งสองได้รับแรงบันดาลใจจากการศึกษาการออกแบบ"TimeAndMoney" จาก Eric EvansหรือแนวคิดจากMartin Fowler เกี่ยวกับรูปแบบการขับเคลื่อนโดเมนดังนั้นพวกเขาจึงมุ่งมั่นมากหรือน้อยสำหรับรูปแบบการเขียนโปรแกรมที่คล่องแคล่ว (แม้ว่าจะไม่สมบูรณ์ ;-))

c) ด้วยไลบรารีทั้งสองเราจะได้รับประเภทวันที่ตามปฏิทินจริง (เรียกว่าLocalDate), ชนิดเวลาตามจริง (เรียกว่าLocalTime) และองค์ประกอบ (เรียกว่าLocalDateTime) นั่นคือการชนะที่ยิ่งใหญ่มากเมื่อเทียบกับเก่าและjava.util.Calendarjava.util.Date

ง) ห้องสมุดทั้งสองใช้วิธีการวิธีการเป็นศูนย์กลางหมายถึงพวกเขาขอแนะนำให้ผู้ใช้สามารถใช้แทนgetDayOfYear() get(DAY_OF_YEAR)สิ่งนี้ทำให้เกิดวิธีการพิเศษมากมายเมื่อเทียบกับjava.util.Calendar(แม้ว่าวิธีหลังจะไม่ปลอดภัยต่อการใช้งานเลยเนื่องจากมีการใช้ ints มากเกินไป)

ประสิทธิภาพ

ดูคำตอบอื่น ๆ โดย @ OO7 ซึ่งชี้ไปที่การวิเคราะห์ของ Mikhail Vorontsov แม้ว่าจุด 3 (การจับข้อยกเว้น) อาจล้าสมัย - ดูข้อผิดพลาด JDKนี้ ประสิทธิภาพที่แตกต่างกัน (ซึ่งเป็นที่โปรดปรานโดยทั่วไปของJSR-310 ) ส่วนใหญ่เป็นเพราะความจริงที่ว่าการดำเนินการภายในของJoda-Timeมักจะใช้เครื่องจักรแบบยาวเหมือนดั่งดั้งเดิม (เป็นมิลลิวินาที)

โมฆะ

Joda-Time มักใช้ NULL เป็นค่าเริ่มต้นสำหรับเขตเวลาของระบบสถานที่ตั้งเริ่มต้นการประทับเวลาปัจจุบันเป็นต้นขณะที่ JSR-310 มักปฏิเสธค่า NULL

ความแม่นยำ

JSR-310 จัดการกับความแม่นยำระดับนาโนวินาทีในขณะที่ Joda-Time ถูก จำกัด ไว้ที่ความแม่นยำระดับมิลลิวินาที

สาขาที่รองรับ:

ภาพรวมเกี่ยวกับเขตการสนับสนุนใน Java-8 (JSR-310) จะได้รับจากการเรียนบางส่วนในชั่วแพคเกจ (ตัวอย่างเช่นChronoFieldและWeekFields ) ในขณะที่ Joda เวลาค่อนข้างอ่อนแอในพื้นที่นี้ - ดูDateTimeFieldType การขาด Joda-Time ที่ใหญ่ที่สุดคือที่นี่ไม่มีสาขาที่เกี่ยวข้องกับการแปลในแต่ละสัปดาห์ คุณลักษณะทั่วไปของการออกแบบการใช้งานทั้งสองฟิลด์นั้นทั้งสองแบบนั้นขึ้นอยู่กับค่าของชนิดยาว (ไม่มีประเภทอื่น ๆ แม้แต่ enums)

enum

JSR-310 ข้อเสนอenumsเหมือนDayOfWeekหรือMonthในขณะที่ Joda เวลาไม่เสนอนี้เพราะมันได้รับการพัฒนาส่วนใหญ่ในปี 2002-2004 ก่อนที่จะJava 5

Zone API

a) JSR-310 มีคุณสมบัติเขตเวลามากกว่า Joda-Time Latter ไม่สามารถให้สิทธิ์การเข้าถึงแบบดั้งเดิมแก่โปรแกรมของประวัติการเปลี่ยนช่วงเวลาของเขตเวลาขณะที่ JSR-310 สามารถทำสิ่งนี้ได้

b) สำหรับข้อมูลของคุณ: JSR-310 ได้ย้ายที่เก็บเขตเวลาภายในไปยังตำแหน่งใหม่และรูปแบบอื่น ไลบรารีโฟลเดอร์เก่า lib / zi ไม่มีอยู่อีกต่อไป

Adjuster vs. Property

JSR-310 ได้แนะนำTemporalAdjuster-interface เป็นวิธีที่เป็นทางการในการจัดทำการคำนวณเชิงเวลาและการจัดการโดยเฉพาะอย่างยิ่งสำหรับห้องสมุดหรือผู้เขียนเฟรมเวิร์กนี่เป็นวิธีที่ง่ายและดีในการฝังส่วนขยายใหม่ของ JSR-310 คลาสสำหรับอดีตjava.util.Date)

สำหรับผู้ใช้ส่วนใหญ่คุณสมบัตินี้มีค่า จำกัด มากเนื่องจากภาระในการเขียนรหัสยังคงอยู่กับผู้ใช้ โซลูชั่นในตัวที่ยึดตามTemporalAdjusterแนวคิดใหม่นั้นมีไม่มากขณะนี้มีเพียงคลาสผู้ช่วยที่TemporalAdjustersมีชุดการ จำกัด ที่ จำกัด (และ enums Monthหรือประเภทชั่วคราวอื่น ๆ )

Joda-Time เสนอแพ็คเกจภาคสนาม แต่การฝึกฝนได้แสดงหลักฐานว่าการติดตั้งภาคสนามใหม่นั้นยากที่จะเขียนโค้ด ในด้านอื่น ๆ ข้อเสนอ Joda เวลาคุณสมบัติที่ทำให้กิจวัตรบางมากขึ้นและสง่างามมากขึ้นกว่าใน JSR-310 ที่เรียกว่ายกตัวอย่างเช่นproperty.withMaximumValue ()

ระบบปฏิทิน

JSR-310 มีระบบปฏิทินเพิ่มเติม 4 ระบบ สิ่งที่น่าสนใจที่สุดคือUmalqura (ใช้ในซาอุดิอาระเบีย) อีกสามคือMinguo (ไต้หวัน), ญี่ปุ่น (เฉพาะปฏิทินที่ทันสมัยตั้งแต่ปี 1871!) และThaiBuddhist (ถูกต้องเฉพาะหลังปี 1940)

Joda-Time เสนอปฏิทินอิสลามตามฐานการคำนวณไม่ใช่ปฏิทินตามการมองเห็นเช่น Umalqura ไทย - พุทธยังให้บริการโดย Joda-Time ในรูปแบบที่คล้ายกัน Minguo และคนญี่ปุ่นไม่ได้ ไม่เช่นนั้น Joda-Time ก็มีปฏิทินคอปติกและชาติพันธุ์ด้วยเช่นกัน (แต่ไม่มีการสนับสนุนสากล)

น่าสนใจยิ่งขึ้นสำหรับชาวยุโรป: Joda-Time ยังมีปฏิทินเกรกอเรียนจูเลียนและมิกซ์เกรโกเรียน - จูเลียน อย่างไรก็ตามค่าในทางปฏิบัติสำหรับการคำนวณทางประวัติศาสตร์ที่แท้จริงนั้นมี จำกัด เนื่องจากคุณสมบัติที่สำคัญเช่นปีที่แตกต่างกันเริ่มต้นในประวัติวันที่ไม่ได้รับการสนับสนุนjava.util.GregorianCalendarเลย

ปฏิทินอื่น ๆ เช่นฮิบรูหรือเปอร์เซียหรือฮินดูหายไปอย่างสมบูรณ์ในห้องสมุดทั้งสอง

วันเวลา

JSR-310 มีชั้นJulianFieldsขณะ Joda เวลา (เวอร์ชั่น 2.0) มีวิธีการช่วยเหลือบางส่วนในชั้นเรียนDateTimeUtils

นาฬิกา

JSR-310 ไม่มีส่วนต่อประสาน (ข้อผิดพลาดในการออกแบบ) แต่เป็นระดับนามธรรมjava.time.Clockซึ่งสามารถใช้สำหรับการฉีดนาฬิกาอ้างอิงใด ๆ Joda-Time เสนออินเตอร์เฟสMillisProviderและวิธีการช่วยเหลือบางอย่างในDateTimeUtilsแทน ดังนั้นวิธีนี้ Joda-Time ก็สามารถรองรับโมเดลทดสอบที่ขับเคลื่อนด้วยนาฬิกาที่แตกต่างกัน (การเยาะเย้ย ฯลฯ )

เลขคณิตระยะเวลา

ห้องสมุดทั้งสองรองรับการคำนวณระยะเวลาในหน่วยชั่วคราวหนึ่งหน่วยหรือมากกว่า อย่างไรก็ตามเมื่อจัดการกับระยะเวลาหนึ่งหน่วยสไตล์ JSR-310 นั้นชัดเจนกว่า (และใช้ระยะยาวแทนที่จะใช้ int):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Time => int days = DAYS.daysBetween(date1, date2).getDays();

การจัดการระยะเวลาหลายหน่วยก็แตกต่างกันเช่นกัน แม้ผลการคำนวณอาจแตกต่างกัน - เห็นนี้ปิดปัญหา Joda เวลา ในขณะที่ JSR-310 ใช้วิธีที่ง่ายและ จำกัด ในการใช้เพียงแค่คลาสPeriod(ระยะเวลาตามปีเดือนและวัน) และDuration(ขึ้นอยู่กับวินาทีและนาโนวินาที) Joda-Time ใช้วิธีที่ซับซ้อนมากขึ้นPeriodTypeในการควบคุมชั้นเรียนเพื่อควบคุม หน่วยเป็นระยะเวลาใด (Joda-Time เรียกมันว่า "Period") ในขณะที่PeriodType-API ค่อนข้างงุ่มง่ามที่จะใช้วิธีที่คล้ายกันโดย JSR-310 ไม่ได้มีให้เลย โดยเฉพาะอย่างยิ่งยังไม่สามารถทำได้ใน JSR-310 เพื่อกำหนดวันที่และเวลาแบบผสม (ตามตัวอย่างเช่นวันและเวลา) ดังนั้นควรได้รับการเตือนหากมีการโยกย้ายจากห้องสมุดหนึ่งไปยังอีกห้องสมุดหนึ่ง ห้องสมุดในการอภิปรายไม่เข้ากัน - แม้จะมีชื่อคลาสเดียวกันบางส่วน

ช่วงเวลา

JSR-310 ไม่รองรับคุณสมบัตินี้ในขณะที่ Joda-Time มีการสนับสนุนที่ จำกัด ดูเพิ่มเติมที่คำตอบนี้

การจัดรูปแบบและการแยกวิเคราะห์

วิธีที่ดีที่สุดในการเปรียบเทียบทั้งสองไลบรารีคือการดูคลาสที่มีชื่อเท่ากันDateTimeFormatterBuilder (JSR-310) และDateTimeFormatterBuilder (Joda-Time) ตัวแปร JSR-310 มีประสิทธิภาพมากกว่าเล็กน้อย (สามารถจัดการได้ทุกประเภทที่TemporalFieldผู้ดำเนินการภาคสนามมีการจัดการโค้ดส่วนขยายบางอย่างเช่นการแก้ไข () ) ความแตกต่างที่สำคัญที่สุดคือ - ในความคิดของฉัน:

JSR-310 สามารถแยกชื่อเขตเวลาได้ดีกว่า (สัญลักษณ์รูปแบบรูปแบบ z) ในขณะที่ Joda-Time ไม่สามารถทำสิ่งนี้ได้ในเวอร์ชั่นก่อนหน้านี้และในเวลานี้มีข้อ จำกัด อย่างมาก

ข้อดีอีกอย่างของ JSR-310 คือรองรับชื่อเดือนแบบสแตนด์อโลนซึ่งมีความสำคัญในภาษาเช่นรัสเซียหรือโปแลนด์เป็นต้น Joda-Time ไม่สามารถเข้าถึงทรัพยากรดังกล่าวได้ - แม้กระทั่งบนแพลตฟอร์ม Java-8

ไวยากรณ์ของรูปแบบใน JSR-310 นั้นมีความยืดหยุ่นมากกว่า Joda-Time ซึ่งอนุญาตให้มีส่วนเพิ่มเติม (ใช้วงเล็บเหลี่ยม) ได้รับการปรับทิศทางให้เข้ากับมาตรฐาน CLDR มากขึ้นและมีช่องว่าง (สัญลักษณ์สัญลักษณ์ p) และฟิลด์อื่น ๆ

มิฉะนั้นก็ควรจะตั้งข้อสังเกตว่า Joda เวลาสามารถจัดรูปแบบโดยใช้ระยะเวลาPeriodFormatter JSR-310 ไม่สามารถทำได้


หวังว่าภาพรวมนี้จะช่วยให้ ข้อมูลที่รวบรวมทั้งหมดส่วนใหญ่เป็นเพราะความพยายามและการตรวจสอบของฉันวิธีการออกแบบและใช้ห้องสมุดวันที่และเวลาที่ดีกว่า (ไม่มีอะไรสมบูรณ์แบบ)

อัปเดตจาก 2015-06-24:

ในขณะเดียวกันฉันได้พบเวลาในการเขียนและเผยแพร่ภาพรวมแบบตารางสำหรับไลบรารีเวลาที่แตกต่างกันใน Java ตารางยังมีการเปรียบเทียบระหว่าง Joda-Time v2.8.1 และ Java-8 (JSR-310) มันมีรายละเอียดมากกว่าโพสต์นี้


12
นี่คือโพสต์ที่โดดเด่น ขอบคุณมากที่แบ่งปันข้อมูลทั้งหมดนี้ หากมีตัวเลือกระหว่าง Joda และ JSR-310 (สำหรับกรณีการใช้วานิลลาเท่านั้น) คุณจะเลือกแบบไหน ฉันกำลังเผชิญกับตัวเลือกนี้อยู่ในขณะนี้ ฉันกำลังพิจารณา JSR-310 เพียงเพราะมันใหม่กว่าและฉันพยายามสนับสนุน "ก้าวไปข้างหน้า" ทุกที่ที่เป็นไปได้
kevinarpe

7
@kevinarpe หากฉันมีเพียงตัวเลือกระหว่าง JSR-310 และ Joda-Time ฉันอาจจะชอบ JSR-310 มากกว่าเพราะ Joda-Time หยุดการพัฒนาต่อไปเกือบหมด (คุณสมบัติขนาดใหญ่ใหม่ไม่สามารถคาดหวังได้ - เพียงแค่แก้ไขข้อผิดพลาดและอัปเดตเล็ก ๆ ) และการออกแบบของ JSR-310 นั้นทันสมัยกว่ามาก (และมีคุณภาพภายในที่ดีกว่า) อย่างไรก็ตามการตัดสินใจที่แท้จริงของฉันค่อนข้างจะชอบห้องสมุดของตัวเอง Time4J - ดูลิงก์ไปยังภาพรวมแบบตารางที่กำหนดที่ด้านล่างของโพสต์ของฉัน มันเป็นการดีเสมอที่จะมีทางเลือกและขึ้นอยู่กับว่าคุณต้องการคุณลักษณะใด
Meno Hochschild

ไม่ใช่ช่วงเวลาของช่วงเวลาของ Java8 หรือไม่
Christian Hujer

1
@ChristianHujer ไม่ไม่java.time.Durationสามารถสอบถามถึงการเริ่มต้นหรือสิ้นสุดในทางตรงกันข้ามกับช่วงเวลาที่ยึดกับไทม์ไลน์ ประเภท JSR-310 นี้เป็นเพียงวินาทีและนาโนวินาทีที่ผ่านไปนับตั้งแต่การเริ่มต้นที่ไม่รู้จัก
Meno Hochschild

42

Java 8 วันที่ / เวลา:

  1. Java 8 คลาสถูกสร้างขึ้นตามเวลาของมนุษย์ มันทำให้พวกเขารวดเร็วสำหรับมนุษย์เลขคณิต / การแปลงวันที่
  2. ตัวรวมวันที่ / เวลาเช่นgetDayOfMonthมีความซับซ้อน O (1) ในการติดตั้ง Java 8
  3. การแยกวิเคราะห์ของOffsetDateTime/ OffsetTime/ ZonedDateTimeช้ามากใน Java 8 ea b121 เนื่องจากมีข้อยกเว้นเกิดขึ้นและถูกจับภายในใน JDK
  4. ชุดของแพคเกจ: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. อินสแตนท์ (การประทับเวลา) วันที่และเวลาตัวแยกวิเคราะห์วันที่และเวลาบางส่วนและเขตเวลาของตัวจัดรูปแบบลำดับเหตุการณ์ที่แตกต่างกัน (ปฏิทิน)
  6. คลาสที่มีอยู่มีปัญหาเช่น Date ไม่รองรับ I18N หรือ L10N พวกเขาไม่แน่นอน!
  7. เรียบง่ายและแข็งแกร่งยิ่งขึ้น
  8. สามารถฉีดนาฬิกาได้
  9. นาฬิกาสามารถสร้างด้วยคุณสมบัติต่าง ๆ - นาฬิกาแบบคงที่, นาฬิกาจำลอง, นาฬิกาความแม่นยำต่ำ (ทั้งวินาที, นาทีทั้งหมด, ฯลฯ )
  10. สามารถสร้างนาฬิกาด้วยเขตเวลาเฉพาะ Clock.system(Zone.of("America/Los_Angeles")).
  11. ทำให้วันที่และเวลาในการจัดการโค้ดสามารถทดสอบได้
  12. ทำให้การทดสอบเป็นอิสระจากเขตเวลา

Joda-Time:

  1. Joda-Time ใช้เวลาเครื่องภายใน การปรับใช้ด้วยตนเองตามค่า int / long จะเร็วขึ้นมาก
  2. Joda-Time getters ต้องการการคำนวณเวลาแบบคอมพิวเตอร์ต่อมนุษย์ในการเรียกใช้ getter ทุกครั้งซึ่งทำให้ Joda-Time เป็นคอขวดในสถานการณ์ดังกล่าว
  3. มันประกอบด้วยชั้นเรียนที่ไม่เปลี่ยนรูปซึ่งจะจัดการ Instants, วันที่และเวลา, Partials, และ Durations มันมีความยืดหยุ่นมันถูกออกแบบมาอย่างดี
  4. แสดงถึงวันที่เป็น instants แต่วันที่และเวลาอาจสอดคล้องกับมากกว่าหนึ่งทันที ชั่วโมงซ้อนทับเมื่อการออมในเวลากลางวันสิ้นสุดลง รวมถึงไม่มีการโต้ตอบใด ๆ ที่สอดคล้องกับมันเลย Gap ชั่วโมงเมื่อเวลากลางวันเริ่ม ต้องทำการคำนวณที่ซับซ้อนเพื่อการทำงานที่ง่าย
  5. ยอมรับค่า Null เป็นค่าที่ถูกต้องในวิธีการส่วนใหญ่ นำไปสู่ข้อบกพร่องที่ลึกซึ้ง

สำหรับการเปรียบเทียบรายละเอียดเพิ่มเติมดู: -

Java 8 วันที่ / เวลาการปฏิบัติงานห้องสมุด (เช่นเดียวกับ Joda เวลา 2.3 และ juCalendar) & ใหม่วันที่ & เวลา API ใน Java 8


เมื่อคุณพูดว่า "ทำให้การทดสอบเป็นอิสระจากเขตเวลา" คุณหมายความว่ายังไงกันแน่?
Zack

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

ฮะ - ฉันคิดว่าคุณพูดว่า joda วิ่งบนเครื่องเวลาภายในแทนที่จะเป็นไทม์แมชชีน ... และฉันจะไม่แปลกใจเลย
Kyranstar

4
@ OO7 คุณหมายถึงอะไร 'เวลาของมนุษย์'? เครื่องจะคำนวณเวลาด้วย
IgorGanapolsky

1

Joda-Time ขณะนี้อยู่ในโหมดบำรุงรักษา

ไม่ใช่คำตอบที่ตรงกับคำถาม แต่โครงการJoda-Timeไม่ได้อยู่ในการพัฒนาอย่างจริงจังอีกต่อไป ทีมแนะนำให้ผู้ใช้ย้ายไปยังjava.time API ที่ใหม่กว่า ดูกวดวิชาโดยออราเคิล

จากหน้าโครงการGitHubอย่างเป็นทางการ:

Joda-time ไม่ได้อยู่ในการพัฒนาที่ใช้งานได้อีกต่อไปยกเว้นเพื่อปรับปรุงข้อมูลเขตเวลาให้ทันสมัย จาก Java SE 8 เป็นต้นไปผู้ใช้จะถูกขอให้ย้ายไปยัง java.time (JSR-310) - ส่วนหลักของ JDK ซึ่งแทนที่โครงการนี้ สำหรับผู้ใช้ Android จะมีการเพิ่ม java.time ใน API 26+ โครงการที่ต้องการสนับสนุนระดับ API ที่ต่ำกว่าสามารถใช้ไลบรารี ThreeTenABP

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