Local Dates in Java

Now let us turn from absolute time to human time. There are two kinds of human time in the Java API, local date/time and zoned time. Local date/time has a date and/or time of day, but no associated time zone information. An example of a local date is June 14, 1903 (the day on which Alonzo Church,

inventor of the lambda calculus, was born). Since that date has neither a time of day nor time zone information, it does not correspond to a precise instant of time. In contrast, July 16, 1969, 09:32:00 EDT (the launch of Apollo 11) is a zoned date/time, representing a precise instant on the time line.

There are many calculations where time zones are not required, and in some cases they can even be a hindrance. Suppose you schedule a meeting every week at 10:00. If you add 7 days (that is, 7 x 24 x 60 x 60 seconds) to the last zoned time, and you happen to cross the daylight savings time boundary, the meeting will be an hour too early or too late!

For that reason, the API designers recommend that you do not use zoned time unless you really want to represent absolute time instances. Birthdays, holidays, schedule times, and so on are usually best represented as local dates or times.

A LocatDate is a date with a year, month, and day of the month. To construct one, you can use the now or of static methods:

LocatDate today = LocatDate.now(); // Today’s date

LocatDate atonzosBirthday = LocatDate.of(1903, 6, 14);

atonzosBirthday = LocatDate.of(1903, Month.JUNE, 14);

// Uses the Month enumeration

Unlike the irregular conventions in UNIX and java.utit.Date, where months are zero-based and years are counted from 1900, here you supply the usual numbers for the month of year. Alternatively, you can use the Month enumeration.

The API notes at the end of this section show the most useful methods for working with LocatDate objects.

For example, Programmer’s Day is the 256th day of the year. Here is how you can easily compute it:

LocatDate programmersDay = LocatDate.of(2014, 1, 1).ptusDays(255);

// September 13, but in a leap year it would be September 12

Recall that the difference between two time instants is a Duration. The equivalent for local dates is a Period, which expresses a number of elapsed years, months, or days. You can call birthday.ptus(Period.ofYears(1)) to get the birthday next year. Of course, you can also just call birthday.ptusYears(1). But birthday. plus (Period .ofDays(365)) won’t produce the correct result in a leap year.

The untit method yields the difference between two local dates. For example,

independenceDay.untit(christmas)

yields a period of 5 months and 21 days. That is actually not terribly useful because the number of days per month varies. To find the number of days, use

independenceDay.until(christmas, ChronoUnit.DAYS) // 174 days

The getDayOfWeek yields the weekday, as a value of the DayOfWeek enumeration. DayOfWeek.MONDAY has the numerical value 1, and DayOfWeek.SUNDAY has the value 7. For example,

LocalDate.of(1900, 1, 1).getDayOfWeek().getValue()

yields 1. The DayOfWeek enumeration has convenience methods plus and minus to compute weekdays modulo 7. For example, DayOfWeek.SATURDAY.plus(3) yields DayOfWeek.TUESDAY.

Java 9 adds two useful methods datesUntil that yield streams of LocalDate objects.

LocalDate start = LocalDate.of(2000, 1, 1);
LocalDate endExclusive = LocalDate.now();
Stream<LocalDate> allDays = start.datesUntil(endExclusive);
Stream<LocalDate> firstDaysInMonth = start.datesUntil(endExclusive, Period.ofMonths(1));

In addition to LocalDate, there are also classes MonthDay, YearMonth, and Year to describe partial dates. For example, December 25 (with the year unspecified) can be represented as a MonthDay.

The example program in Listing 6.2 shows how to work with the LocalDate class.

Source: Horstmann Cay S. (2019), Core Java. Volume II – Advanced Features, Pearson; 11th edition.

Leave a Reply

Your email address will not be published. Required fields are marked *