Date, Calendar And Joda-Time
Very early developers found out that Java’s Date
class is bad and it is not possible to improve it. Because of this, most methods of Java’s Date
class are deprecated now and early the class Calendar
has been added.
But soon after adding Calendar
, people realized that Calendar
is not very good as well. Then development of the successor API Joda-Time started.
Joda-Time is available from Java SE 8 on. It is located in the namespace java.time
and contains the main classes LocalDate, LocalTime
and LocalDateTime
. Joda-Time contains full support of timezones with classes ZoneId, ZonedDateTime, OffsetTime, OffsetDateTime
and ZoneOffset
. The older class java.util.TimeZone
is deprecated.
Joda-Time supports periods of time with the classes Period
and Duration
. Both are similar to C#’s TimeSpan
. Period
and Duration
deal with different precisions.
// 3 years, 2 months, 1 day
Period period = Period.of(3, 2, 1);
// You can modify the values of dates using periods
LocalDate newDate = oldDate.plus(period);
// Components of a Period are represented by ChronoUnit values
assertEquals(1, period.get(ChronoUnit.DAYS));
// A duration of 3 seconds and 5 nanoseconds
Duration duration = Duration.ofSeconds(3, 5);
As expected, you can add and subtract durations and you can modify date values with durations.
Joda-Time also contains
Chronolgy
and associated classes to represent calendars different from the Gregorian calendar.MonthDay
to represent a birthday.YearMonth
to represent a credit card expiration date.
From Java SE 8 on all three date-time systems (Date
, Calendar
and Joda-Time) exist in Java in parallel.
Date Formatting
Locale Specific
It is easy to format a Date
in a localized way.
DateFormat daf = DateFormat.getDateInstance(DateFormat.SHORT,
Locale.German);
Date now = new Date(); // new Date() is now.
String s = daf.format(now); // "15.05.14" for 15th of May 2014
DateFormat tif = DateFormat.getTimeInstance(DateFormat.SHORT,
Locale.German);
String z = tif.format(now); // "09:54" for 9:54 AM
// uses the current locale
DateFormat.getDateInstance(DateFormat.SHORT);
// long date and short time combined
DateFormat dtf = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.SHORT, Locale.GERMAN);
String a = dtf.format(now); // "15. Mai 2014 09:54"
These are the available style constants and the resulting output for 15th of May 2014, 09:51:17 o’clock with locale ENGLISH
.
Style | Date | Time |
---|---|---|
DateFormat.SHORT |
5/15/14 | 9:51 AM |
DateFormat.MEDIUM |
May 15, 2014 | 9:51:17 AM |
DateFormat.LONG |
May 15, 2014 | 9:51:17 AM CEST |
DateFormat.FULL |
Thursday, May 15, 2014 | 9:51:17 AM CEST |
Extended Date Formatting
You have full control over your date format with the class SimpleDateFormat
and format placeholder strings.
now = new Date(114, 0, 17, 14, 15, 16);
daf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(daf.format(now)); // 2014-01-17 14:15:16
daf = new SimpleDateFormat("dd. MMM yy HH:mm");
System.out.println(daf.format(now)); // 17. Jan 14 14:15
Gotcha: The format strings in Java are quite similar to those used in C#, but not identical. Look there for details:
http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html.
Date Oddities
If you are using Java’s Date
, be aware of its oddities.
getMonth()
is zero-based.getDay()
returns the day of week, not the day of month.getDate()
returns the day of month, 1-based.getYear()
returns the gregorian year minus 1900.
If today was Tuesday, 13th of May 2014…
Date d = new Date();
String z = String.format("%04d-%02d-%02d",
d.getYear(), d.getMonth(), d.getDay());
System.out.println(z);
Gotcha: this would print 0114-04-02
. Not one of the three numbers is what I would have expected before having studied the intricacies of Date
.
Stopwatch
There’s nothing like C#’s Stopwatch
in plain Java. There are stopwatches available in org.apache.commons.lang.time.StopWatch
and one in com.google.common.base.Stopwatch
.
If you don’t want to pull in these packages, you can use
System.currentTimeMillis()
or System.nanoTime()
to imitate a simple stopwatch.
Function | Returns |
---|---|
System.currentTimeMillis() |
Returns the current time in milliseconds. Date d = new Date(System.currentTimeMillis()) will represent the current time. |
System.nanoTime() |
Returns nanoseconds since some fixed but arbitrary origin time which even may vary between different instances of Java VMs. Only use nanoTime() for profiling. |