+ All Categories
Home > Documents > Joda-Time & JSR-310 as an alternative to Java Date...

Joda-Time & JSR-310 as an alternative to Java Date...

Date post: 09-Jun-2020
Category:
Upload: others
View: 25 times
Download: 0 times
Share this document with a friend
31
Joda-Time & JSR-310 as an alternative to Java Date API Fevzi Anifieiev ([email protected]) Kyiv, Epam Systems
Transcript
Page 1: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time & JSR-310 as an alternative to Java Date API

Fevzi Anifieiev ([email protected])

Kyiv, Epam Systems

Page 2: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Agenda

• JDK Date API Pitfalls

• Joda-Time

• A bit of JSR-310

Page 3: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

JDK 1.6 and prior Date & Time API • Date and its subclasses :

• java.util.Date • java.sql.Date • java.sql.Timestamp • java.sql.Time

• The calendar and time zone classes : • java.util.Calendar • java.util.GregorianCalendar • java.util.TimeZone • java.util.SimpleTimeZone (for use with the Gregorian

calendar only) • The formatting and parsing classes :

• java.text.DateFormat • java.text.SimpleDateFormat

Page 4: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Date, Calendar & DateFormat

• Mutable

• Jan is 0, Dec is 11

• Date is not actually date

• Date uses years from 1900

• Calendar cannot be formatted

• DateFormat is not thread-safe

• Broken equals() symmetric contract for Date and Timestamp

Page 5: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Date, Calendar & DateFormat in action • Mutable Map<Date, String> map = new HashMap<Date, String>();

• February is 1, December is 11

Calendar.getInstance().get(Calendar.MONTH); //returns 1 (it is FEB)

• Date is not actually date Represents date and time

• Date uses years from 1900 new Date(2013, 1, 23); //Sun Feb 23 00:00:00 EET 3913

• Calendar cannot be formatted Calendar calendar = Calendar.getInstance();

new SimpleDateFormat("dd-MM-yyyy").format(calendar.getTime());

• Broken equals() symmetric contract Date date = new Date(); Timestamp timestamp = new Timestamp(date.getTime()); date.equals(timestamp) //true timestamp.equals(date) //false - equals symmetric violation

Page 6: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

DateFormat demo • DateFormat is not thread-safe

public final class DateUtils {

private DateUtils(){

} private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd"); public static Date parse (String s) throws ParseException { return DATE_FORMAT.parse(s);

} } TimeZone Pitfalls TimeZone.getTimeZone("WRONG_TIME_ZONE") // GMT

Page 7: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

How to overcome all the problems with current JDK Date & Time API?

• Understand all the pitfalls of the API to better write quality code, but still….

• Use Alternative Date & Time library

Page 8: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Moving to better alternatives

• JodaTime library

• JSR-310 (JDK8)

Page 9: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time to rescue • Immutable & Threadsafe No changes after creation

Classes and fields are final

• Easy to Use Has straightforward field accessors such as getYear() or getDayOfWeek()

• Comprehensive Feature Set Almost everything you need is there for date manipulations

• Up-to-date Time Zone calculations Based on the public Olson time zone database http://www.iana.org/time-zones

• Calendar support ISO8601, Buddhist, Coptic, Ethiopic, Gregorian, GregorianJulian, Islamic, Julian

• Open Source

Page 10: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time API Overview • Instant

Milliseconds from 1970-01-01T00:00Z

• Partial Only partially represent a date or time in the datetime continuum.

• Interval Time between two instants (TimeZone aware)

• Duration No TimeZone aware or Chronology, just millis

• Period No TimeZone aware or Chronology, defined in terms of fields, for ex: 1 day 5 hrs

Differs from Duration in that it is inexact in terms of millis.

• Chronology Pluggable chronologies. A Chronology is obtained and used in Joda-Time as a singleton

• TimeZone Bazed on TZ(Olson). Frquently updatable. You can also update whenever required.

Page 11: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time Instant • Instant

Interface: ReadableInstant

Common classes: Instant , DateTime , DateMidnight, MutableDateTime import static org.joda.time .DateTimeFieldType.year; import static org.joda.time .DateTimeFieldType.monthOfYear;

... public void showInstants() {

Instant instant = Instant.now();

instant.get(year())); //2013

instant.plus(1000L * 60 * 60 * 24).get(monthOfYear())); //

DateTime dateTime = DateTime.now();

dateTime.getYear(); //2013

dateTime.plusDays(1).getMonthOfYear(); //2 (it is Feb)

}

Page 12: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time Partial • Partial

Interface: ReadablePartial Common classes: LocalDate, LocalTime, LocalDateTime, YearMonth, MonthDay, Partial import static org.joda.time .DateTimeFieldType.dayOfMonth; import static org.joda.time .DateTimeFieldType.dayOfWeek;

… private static void showPartials() {

LocalDate.now(); // 2013-02-21

LocalTime.now()); // 21:16:16.965

LocalDateTime.now()); // 2013-02-21T21:16:16.971 YearMonth.now()); // 2013-02 MonthDay.now()); // --02-21

LocalDate locDate = LocalDate.now();

//DayOfMonthDayOfWeek

Partial partial = new Partial( //--02-22

new DateTimeFieldType[] { dayOfMonth(), dayOfWeek() }, //static import

new int[] {locDate .dayOfMonth().get(), locDate .dayOfWeek().get()}));

}

Page 13: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time Interval • Interval

Interface: ReadableInterval Common classes: Interval, MutableInterval DateTime today = new DateTime(DateTimeZone.UTC);

Interval workBeforeLunch = new Interval( new LocalTime(10, 0).toDateTime(today), new LocalTime(13, 0).toDateTime(today)); Interval lunch = new Interval( new LocalTime(12, 30).toDateTime(today), new LocalTime(14, 0).toDateTime(today)); Interval workAfterLunch= new Interval( new LocalTime(14, 0).toDateTime(today), new LocalTime(19, 0).toDateTime(today)); workBeforeLunch.overlaps(lunch));//true workAfterLunch.overlaps(lunch)); //false

Page 14: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time Duration

• Duration Interface: ReadableDuration Common classes: Duration private static void showDurations() {

DateTime from = DateTime.now();

DateTime to = from.plusMonths(3);

Duration probabDurationInEpam = new Duration(from, to);

probabDurationInEpam.getStandardDays());

}

Page 15: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time Period • Period

Interface: ReadablePeriod Common classes: Period, MutablePeriod, Years, Months, Weeks, Days, Hours, Minutes, Seconds private static void showPeriods() {

DateMidnight firstOfFebruary = new DateMidnight(2012, 2, 1);

DateMidnight firstOfMarch = new DateMidnight(2012, 3, 1);

DateTimeFormatter fmt =ISODateTimeFormat.yearMonthDay();

fmt.print(firstOfFebruary.plus(Months.ONE)); // 2012-03-01

fmt.print(firstOfMarch.plus(Weeks.ONE)); // 2012-03-08

}

Page 16: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time Chronology • Chronology

The default chronology in Joda-Time is ISO Abstarct class: Chronology Common Classes: BuddhistChronology, CopticChronology, EthiopicChronology, GJChronology, GregorianChronology, IslamicChronology, ISOChronology, JulianChronology private static void showChronologies() {

Set<? extends Chronology> chronos = ImmutableSet.of( ISOChronology.getInstance(), CopticChronology.getInstance(), IslamicChronology.getInstance(), GregorianChronology.getInstance()); for(Chronology chrono: chronos) { DateTime dt = DateTime.now(chrono); "Current year in " + chrono+ ": " + dt.getYear());

} } RESULT:

Current year in ISOChronology[Europe/Helsinki]: 2013 Current year in CopticChronology[Europe/Helsinki]: 1729 Current year in IslamicChronology[Europe/Helsinki]: 1434 Current year in GregorianChronology[Europe/Helsinki]: 2013

Page 17: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time Time Zone • Time Zones

Abstract class: DateTimeZone Common classes: CachedDateTimeZone, FixedDateTimeZone private static void showTimeZones() {

DateTimeZone kievZone = DateTimeZone.forID("Europe/Kiev");

kievZone);

DateTimeZone invalidZone = DateTimeZone.forID("WRONG_TIME_ZONE");

//IllegalArgumentException

invalidZone);

}

Page 18: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Joda-Time Date Formatting • DateTimeFormatter(thread safe)

Common classes: DateTimeFormat, DateTimeFormatter, DateTimeFormatterBuilder DateTimeFormatter ddMMyyyyFormat = DateTimeFormat.forPattern("dd-MM-yyyy"); DateTime dt = ddMMyyyyFormat.parseDateTime("23-02-2013"));

• DateTimeFormatterBuilder DateTimeFormatter formatter = new DateTimeFormatterBuilder()

.appendDayOfWeekShortText().appendLiteral(", ") .appendDayOfMonth(2).appendLiteral('-') .appendMonthOfYearShortText().appendLiteral('-') .appendYear(4, 4).appendLiteral(", ").appendEraText() .toFormatter();

formatter.print(DateTime.now()); // Fri, 22-Feb-2013, AD

Page 19: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Examples(Days to NewYear) public static int daysToNewYearJDK(Date fromDate) {

Calendar calendar = Calendar.getInstance();

calendar.setTime(fromDate);

calendar.add(Calendar.YEAR, 1);

calendar.set(Calendar.DAY_OF_YEAR, 1);

return (int)(Math.abs((calendar.getTimeInMillis()

- fromDate.getTime()) / (24 * 60 * 60 * 1000L)));

}

public int daysToNewYearJoda(Date fromDate) {

LocalDate localDate = LocalDate.fromDateFields(fromDate);

LocalDate newYear = localDate.plusYears(1).withDayOfYear(1);

return Days.daysBetween(localDate, newYear).getDays();

}

Page 20: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Examples(adding days)

• public static Date addDaysUsingCalendar(Date fromDate,int days) {

Calendar cal = Calendar.getInstance();

cal.setTime(fromDate);

cal.add(Calendar.DATE, days);

return cal.getTime();

}

• public static Date addDaysUsingJoda(Date fromDate, int days) {

return new LocalDate(fromDate).plusDays(days).toDate();

}

Page 21: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Examples(formatting)

• Date formatting directly import static org.joda.time.format.DateTimeFormat.forPattern;

…..

DateTime dt = DateTime.now();

dt.toString();

dt.toString("hh:mm:ss a");

dt.toString(forPattern("dd-MM-yyyy")); dt.toString(ISODateTimeFormat.yearMonthDay()); dt.toString(ISODateTimeFormat. hourMinute());

Page 22: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Examples (formatting & parsing) • import static org.joda.time.format.DateTimeFormat.forPattern; • … • private static String fromJdkDate(Date jdkDate) { return new DateTime(jdkDate).toString("dd-MM-yyyyy"); } • private static String fromJdkCalendar(Calendar jdkCalendar) {

return new DateTime(jdkCalendar).toString("dd-MM-yyyyy"); } • private static Date fromStringDate(String dateAsString,

String datePattern) { DateTimeFormatter fmt = forPattern(datePattern); return DateTime.parse(dateAsString, fmt).toDate(); }

Page 23: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Design flaws of Joda-Time and why is not JSR-310 RI • Human/Machine timelines

Two principle views of the timeline - Human and Machine. DateTime is a human-timeline view of the world, not a machine-timeline view and should not implement ReadableInstant as it now does.

• Pluggable chronology Each date/time class in Joda-Time has a pluggable chronology. A better solution would be to keep the date/time classes restricted to a single calendar system.

• Nulls Joda-Time defines a null instant as the current time.

• When a method is defined as taking a ReadableInstant, • passing null in will be the same as passing in an instant set to the

current time.

• Nevertheless Joda-Time isn't broken and is currently the best alternative!

Page 24: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

JSR-310 RI(ThreeTen) to the rescue

Page 25: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

JSR-310 Design Principles • Well designed, based on immutable classes

• Thread safe

• Two models of time: “machine” and “human”

• Construction typically by factory method

• ‘with’ methods instead of ‘set’

• Enums for Months, Weeks, Era, ChronoFields, etc

• ISO based model by default

• Possibility to create date and time for different chronogies

Page 26: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

JSR-310 Machine time • Machine time - Instant

An instantaneous point on the time-line, starting from EPOCH, representing epoch-seconds and nanos-of-second

- Duration

Difference in seconds and nanos-of-second between two instants

Page 27: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

JSR-310 Human time • Human time LocalDate – just date w/o tz, e.g. 2013-02-22

LocalTime – just time w/o tz, e.g. 10:15:30

LocalDateTime – date and time w/o offset,

e.g. 2013-02-22 T10:15:30

ZoneOffset – offset against UTC (positive or negative),

e.g. +05:00, +01:00, -02:00, +04:30, Z, CEST, UTC, GMT

OffsetDate – date w/o time but with offset,

e.g. 2013-12-03+02:00

OffsetTime – time w/o date but with offset,

e.g. 10:15:30+02:00

OffsetDateTime – date with time and offset,

e.g. 2013-12-03T10:15:30+02:00

Page 28: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Examples of date & time

• Date without time component - e.g. 1 Mar 2012

LocalDate firstMarch2012 = LocalDate.of(2012, 03, 01);

LocalDate firstMarch2012 = LocalDate.parse("2012-03-01");

• Time without date component - e.g. 11:00

LocalTime elevenAm= LocalTime.of(11, 00);

LocalTime elevenAm = LocalTime.parse("11:00");

• Time with vs time without offset, e.g. 11:00 vs 11:00 CEST

LocalTime local = LocalTime.of(11, 0);

OffsetTime cest1 = OffsetTime.of(local, ZoneOffset.ofHours(2));

OffsetTime cest2 = OffsetTime.of(local, ZoneOffset.of("+02:00"));

Page 29: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

JSR-310 RI(ThreeTen) & Joda-Time Comparison

• Joda-Time is mature and stable, recommended for production usage.

• ThreeTen is not yet stable enough.

Page 30: Joda-Time & JSR-310 as an alternative to Java Date APIjug.ua/wp-content/uploads/2013/02/JODAjsr310.pdf · Joda-Time API Overview •Instant Milliseconds from 1970-01-01T00:00Z •Partial

Questions


Recommended