Joda Time/Noda Time

Czyli co jest nie tak z wbudowanymi typami do obsługi daty i czasu w Javie i C# i jak to naprawić

Andrzej Stencel
andrzej.stencel@docile.pl | @devhunger

To miało być proste

1 rok != 365 dni

1 doba != 24 godziny

1 godzina != 60 minut

1 minuta != 60 sekund

Ciekawostki

Data i czas w Javie (JDK < 8)

Arytmetyka daty i czasu


Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 1);
            

Data i czas w Javie (JDK < 8)

Obliczanie różnicy między dwoma datami


Calendar cal1 = Calendar.getInstance();
cal1.set(2015, Calendar.DECEMBER, 31);
Calendar cal2 = Calendar.getInstance();
cal2.set(2014, Calendar.DECEMBER, 31);
long diff = cal2.getTime().getTime() - cal1.getTime().getTime();
            

Data i czas w Javie (JDK < 8)

Wyciągnięcie samej daty


Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
            

Data i czas w Javie (JDK < 8)

Calendar class | Date class

Why is the Java date API such a mess?

What's wrong with Java Date & Time API?

Data i czas w .NET (aż do dziś)

Arytmetyka daty i czasu


DateTime before = new DateTime(2015, 3, 28, 2, 30, 0);
DateTime after = dt.AddDays(1);
            

BŁĄD!

Data i czas w .NET (aż do dziś)

Arytmetyka daty i czasu (poprawnie)


TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
DateTime localTime = new DateTime(2015, 03, 28, 02, 30, 00);
DateTimeOffset before = new DateTimeOffset(localTime, timeZone.GetUtcOffset(localTime));
DateTimeOffset beforeUtc = before.ToUniversalTime();
DateTimeOffset afterUtc = beforeUtc.AddDays(1);
DateTimeOffset after = TimeZoneInfo.ConvertTime(afterUtc, timeZone);
            

Performing Arithmetic Operations with Dates and Times

Data i czas w .NET (aż do dziś)

Obliczanie różnicy między dwoma datami


DateTime dt1 = new DateTime(2015, 10, 22);
DateTime dt2 = new DateTime(2015, 10, 28);
TimeSpan ts = dt2 - dt1;
bool areEqual = dt1 + ts;
            

Why doesn't Java offer operator overloading?

Data i czas w .NET (aż do dziś)

Wyciągnięcie samej daty


DateTime today = DateTime.Today;
DateTime someOtherDay = new DateTime(2015, 10, 28);
            

DateTime structure | TimeSpan structure | DateTimeOffset structure | TimeZoneInfo class

Arytmetyka daty i czasu w .NET ignoruje strefy czasowe

What's wrong with DateTime anyway?

Joda Time to the rescue

  • Instant - Ilość milisekund od 1970-01-01 00:00:00
  • LocalDateTime - Data i czas bez strefy czasowej
  • LocalDate - Data bez czasu i bez strefy czasowej
  • LocalTime - Czas bez daty i bez strefy czasowej
  • DateTime - Data ze strefą czasową
  • Duration - Pewna ilość milisekund
  • Period - Pewna ilość lat, miesięcy i dni
  • Interval - Przedział czasu między dwiema datami

Joda Time to the rescue

Arytmetyka daty i czasu


DateTime before = new DateTime(2015, 03, 28, 02, 30, 00, DateTimeZone.forID("Europe/Warsaw"));
DateTime after = before.plusDays(1);
            

Joda Time to the rescue

Obliczanie różnicy między dwoma datami


DateTime dt1 = new DateTime(2015, 10, 25, 0, 0);
DateTime dt2 = new DateTime(2015, 10, 26, 0, 1);
Duration duration = new Duration(dt1, dt2);
System.out.println(duration.getStandardDays());
System.out.println(duration.getStandardHours());
System.out.println(duration.toPeriod());
            

Joda Time to the rescue

Wyciągnięcie samej daty


LocalDate localDate = new LocalDate(2015, 10, 28);
            

java.time (JDK 8)

  • Instant - Ilość sekund od 1970-01-01 00:00:00 oraz nanosekund
  • LocalDateTime - Data i czas bez strefy czasowej
  • LocalDate - Data bez czasu i bez strefy czasowej
  • LocalTime - Czas bez daty i bez strefy czasowej
  • ZonedDateTime - Data i czas ze strefą czasową
  • Duration - Pewna ilość sekund i nanosekund
  • Period - Pewna ilość lat, miesięcy i dni

Joda Time vs. java.time (JSR-310)

Differences between Java 8 Date Time API (java.time) and Joda-Time