0% found this document useful (0 votes)
2 views17 pages

Core Java Data Handling Date and Time

The document outlines learning objectives related to date and time handling in Java, focusing on UNIX timestamps, the Instant class, and datetime-specific classes such as LocalDateTime, LocalDate, and LocalTime. It explains how to create and manipulate these date and time representations, including methods for adding or subtracting time and comparing timestamps. Additionally, it highlights the importance of formatting date and time for human readability and provides examples of usage in Java code.

Uploaded by

learnwithoa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views17 pages

Core Java Data Handling Date and Time

The document outlines learning objectives related to date and time handling in Java, focusing on UNIX timestamps, the Instant class, and datetime-specific classes such as LocalDateTime, LocalDate, and LocalTime. It explains how to create and manipulate these date and time representations, including methods for adding or subtracting time and comparing timestamps. Additionally, it highlights the importance of formatting date and time for human readability and provides examples of usage in Java code.

Uploaded by

learnwithoa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Learning Objectives: Date and

Time

Learners will be able to…

Describe the structure of a UNIX timestamp and use


Instant to represent it in Java

Use datetime specific classes such as LocalDateTime,


LocalDate, and LocalTime

Find period or duration between two dates

Use ZonedDateTime and ZoneId to handle time zones

info

Make Sure You Know


Java syntax
Unix time and Instant
There are several standards for measuring and recording time. The two
main ones used normally are:

Greenwich Mean Time or GMT. GMT is based on the Royal Observatory


in Greenwich on the south bank in Eastern London, UK. When the sun
is at its highest point exactly above Greenwich, it is 12 noon GMT. The
Earth spins slightly unevenly, so 12 noon is based on the annual
average of when the sun is at its highest point.

Coordinated Universal Time or UTC is defined by atomic clocks instead


of the sun meaning that in UTC a second always has the same length. In
fact, leap seconds are inserted in UTC to keep UTC and GMT from
drifting apart.

Unix time is a date and time representation widely used in computing. It


measures time by the number of seconds that have elapsed since 00:00:00
UTC on 1 January 1970, the beginning of the Unix epoch (with
adjustments made due to leap seconds). Unix time matches UTC time
without any offset.

The amount of time in milliseconds from the Unix epoch is also called a
timestamp. The timestamp is usually a long (or an integer) value and is
useful for storing in databases or transferring over a network.

Instant
For a Unix timestamp representation, we use Instant Java class. Instant
models a single instantaneous point on the time-line, which is useful for
recording event time-stamps in the application. Unlike the classical
timestamp, Instant allows you to store the number of nanoseconds.

In the example on the left, we obtain the current instant from the system
clock and prints it as the number of milliseconds from the Unix epoch
(which is how Instant stores the timestamp). Click the button below to run
the file on the left:

You can try clicking the button multiple time to see the number change.

Generally, the number of milliseconds is not particularly meaningful to


humans. Add the following print statement:

System.out.println(currentTimestamp);
Run the code on the left again:

You will see the time stamp represented in ISO-8601 which is read as:

The characters before the T are the date in Year - month - day
order separated by hyphens. After the T is the time in normal
hour, minute, seconds order separated by colons. There is then a
period followed by milliseconds ending with the letter Z.

The letter Z at the end indicates the time zone is UTC.

Why is the date represented in this order? Because we all needed to agree:

As you will notice throughout this topic, while dates and times, in theory
are a simple math problem, there are many challenges going from the
stored number of milliseconds from epoch to a human readable format (or
the other way around).
Instant methods
You create an Instant instance using one of the Instant class factory
methods:
* Instant.now() - current time from system clock
* Instant.ofEpochMilli(long epochMilli) - time epochMilli milliseconds
from Unix epoch
java timestamp = Instant.ofEpochMilli(1_675_100_962_725L);
* Instant.ofEpochSecond(long epochSecond) - time epochSecond seconds
from Unix epoch
java timestamp = Instant.ofEpochSecond(1_675_100_962L);
* Instant.parse(CharSequence text) - Instant from a text string in valid
ISO format
java timestamp = Instant.parse("2023-01-30T17:49:22.725Z");

Try creating an instant using one of the examples above and then print it
out:

System.out.println(timestamp);

Run the code file on the left by pressing the button below:

challenge

Next Eclipse

Look up when the next Solar Eclipse will happen in your city:
https://www.timeanddate.com/eclipse/in.html

Create an eclipseTimestamp using one of the methods above.

Example Solution

Assume we are in South Africa and the eclipse we have selected


is the one on November 25, 2030 at 04:16:45 UTC.

Instant eclipseTimestamp = Instant.parse("2030-11-


25T04:16:45.000Z");

Obtaining timestamp data


Instant’s .toString presents the timestamp as a String in ISO format by
default, but there are other representations that can be obtained.

Instant.toEpochMilli() - Converts this instant to the number of


milliseconds from the epoch of 1970-01-01T00:00:00Z.

System.out.println(timestamp.toEpochMilli());

Update the print statement in the file to the left:

getEpochSecond() - Gets the number of seconds from the Java epoch of


1970-01-01T00:00:00Z.

System.out.println(timestamp.getEpochSecond());

Update the print statement in the file to the left:

getNano() - Gets the number of nanoseconds, later along the time-line,


from the start of the second.

System.out.println(timestamp.getNano());

Update the print statement in the file to the left:

Adding or Subtracting Time


There are a number of methods to easily shift an Instant by a given
number of seconds, millisecond, or nanoseconds.

plusSeconds(long secondsToAdd)
minusSeconds(long secondsToSubtract)
Returns a copy of this instant with the specified duration in seconds
added or subtracted.

plusMillis(long millisToAdd)
minusMillis(long millisToSubtract)
Returns a copy of this instant with the specified duration in
milliseconds added or subtracted.

plusNanos(long nanosToAdd)
minusNanos(long nanosToSubtract)
Returns a copy of this instant with the specified duration in
nanoseconds added or subtracted.

These methods are nice for shorter periods of time, but when you start
need to shift by minutes, hours and days they can get clunky:
Instant instant = Instant.parse("2023-01-01T00:00:00Z");

// add 1 hour = 60 seconds * 60 minutes


System.out.println(instant.plusSeconds(60 * 60));

// add 1 day = 60 seconds * 60 minutes * 24 hours


System.out.println(instant.plusSeconds(60 * 60 * 24));

Notice that we are not shifting the original Instant.

To handle these larger time scales you can use the ChronoUnit class to
provide a TemporalUnit:
* plus(long amountToAdd, TemporalUnit unit)
minus(long amountToSubtract, TemporalUnit unit)
Returns a copy of this instant with the specified amount added or
subtracted.

The same code re-written is now much more readable:

Instant instant = Instant.parse("2023-01-01T00:00:00Z");

// add 1 hour
System.out.println(instant.plus(1, ChronoUnit.HOURS));
// add 1 day
System.out.println(instant.plus(1, ChronoUnit.DAYS));

Notice that we are not shifting the original Instant.


challenge

Shifting the Next Eclipse


Modify your eclipseTimestamp so that it is created from the local time
and then modify it using the methods above based on the timezone.

Hint: You will need to do the opposite operation. For example, if the
local timezone is UTC-5 then you will need to plus 5 hours.

Example Solution

If you are looking at a city-specific page, the time will be shown


for that timezone. So if we were considering the same eclipse
from the city of Durban, South Africa, the local time is November
25, 2030 at 6:32 am (SAST). SAST or South Africa Standard Time is
UTC+2 so we could also specify the time as:

Instant eclipseTimestampSAST = Instant.parse("2030-11-


25T06:32:00.000Z");
Instant eclipseTimestampUTC =
eclipseTimestampSAST.minus(2, ChronoUnit.HOURS);

Comparing Two Instants


If you need to figure out which timestamp is earliest (e.g. filtering out all
timestamps in a Stream that have already passed) Instant provides a couple
comparative methods:

isAfter(Instant otherInstant) - Checks if this instant is after the


specified instant - returns boolean.
isBefore(Instant otherInstant) - Checks if this instant is before the
specified instant - returns boolean.

Instant firstInstant = Instant.parse("2023-01-01T00:00:00Z");


Instant secondInstant = Instant.parse("2022-01-01T00:00:00Z");

System.out.println(firstInstant.isAfter(secondInstant));
System.out.println(firstInstant.isBefore(secondInstant));
Java Local Date Time
Instant represents a moment on a timeline which is helpful for things like
event logs, but sometimes we need to work with date/time as calendar or
clock data.

Java has 3 classes to handle this:


1. LocalDate - a date (without a time-zone)
2. LocalTime - a time (without a time-zone)
3. LocalDateTime - a combination of LocalDate + LocalTime

Please note that ==these classes cannot replace Instant== - as noted in their
documentation:
> [LocalDateTime] is a description of the date, as used for birthdays,
combined with the local time as seen on a wall clock. It cannot represent an
instant on the time-line without additional information such as an offset or
time-zone.

LocalDate creation

The first two ways to create a LocalDate instance look very similar to the
Instant class:

now() - Obtains the current date from the system clock in the default
time-zone

LocalDate now = LocalDate.now();


System.out.println(now);

Try out the example above by pasting it into the code file on the left and
then pressing the Run button below:

parse(CharSequence text) - Creates a LocalDate from a string in ISO


standard (YYYY-MM-DD)

LocalDate firstOfJanuary2023 = LocalDate.parse("2023-01-01");


System.out.println(firstOfJanuary2023);

In cases where the user is selecting dates from a series of drop downs, you
do not need to build the string above, you can pass each field individually
with one of the of methods:

of(int year, int month, int dayOfMonth)


of(int year, Month month, int dayOfMonth)
You can see the list of months in the documentation

LocalDate firstOfJanuary2023 = LocalDate.of(2023, 1, 1);


System.out.println(firstOfJanuary2023);

LocalDate firstOfFebruary2023 = LocalDate.of(2023,


Month.FEBRUARY, 1);
System.out.println(firstOfFebruary2023);

While it might be easier to use the integer representation of the month, it is


generally best practice to use the Month representation for code clarity.

LocalTime creation

The first two ways to create a LocalTime instance look very similar to the
Instant and LocalDate classes:
* now() - Obtains the current time from the system clock in the default time-
zone
java LocalTime now = LocalTime.now(); System.out.println(now);

parse(CharSequence text) - Creates a LocalTime from a text string in


ISO representation (HH:MM:SS.SSS)

LocalTime time = LocalTime.parse("11:50:35.130");


System.out.println(time);

challenge

Try these variations


You don’t need to specify the time all the way down to the millisecond.
Try replacing your parse example with the following:
* LocalTime.parse("11:50:35");

LocalTime.parse("11:50");

In cases where the user is selecting time from a series of drop downs, you
do not need to build the string above, you can pass each field individually
with one of the of methods:

of(int hour, int minute)


of(int hour, int minute, int second)
of(int hour, int minute, int second, int nanoOfSecond)
LocalTime time = LocalTime.of(11, 50, 35, 130000000);
System.out.println(time);

challenge

Try these variations


Try replacing your of example with the following:
* LocalTime.of(11, 50, 35);

LocalTime.of(11, 50);

LocalDateTime creation

The same three creation methods are also used for full DateTime
representations.

now() - Obtains the current date-time from the system clock in the
default time-zone

parse(CharSequence text) - Obtains an instance of LocalDateTime from


a text string such as 2007-12-03T10:15:30.

of(...) - method will combine LocalDate and LocalTime creation

LocalDateTime firstOfJanuary2023time1150am =
LocalDateTime.of(2023, Month.JANUARY, 1, 11, 50);
System.out.println(firstOfJanuary2023time1150am);

Similar to above, you can use the integer representation for month, but
it is not recommended for clarity reasons.
LocalDateTime methods
LocalDateTime has similar methods to the Instant class for shifting
timestamps and comparing timestamps. In addition, there are a set of
methods for formatting the timestamp data into human-readable
representations.

Adding or Subtracting Time


Here is a table summarizing the different methods for adding or
subtracting time arranged from the largest time unit (years) to the smallest
(nanoseconds):
| Adding | Subtracting |
|———-|———-|
|plusYears(long years) | minusYears(long years) |
|plusMonths(long months) | minusMonths(long months) |
|plusWeeks(long weeks) | minusWeeks(long weeks) |
|plusDays(long days) | minusDays(long days) |
|plusHours(long hours) | minusHours(long hours) |
|plusMinutes(long minutes) | minusMinutes(long minutes) |
|plusSeconds(long seconds) | minusSeconds(long seconds) |
|plusNanos(long nanos) | minusNanos(long nanos) |

All of the above methods returns a LocalDateTime instance with the


specified amount of time added/subtracted.

Try out some of the methods in the code file to the left. Here is an example
to get you started:

LocalDateTime dateInJanuary = LocalDateTime.parse("2023-01-


01T11:50");
System.out.println(dateInJanuary.plusYears(6));
System.out.println(dateInJanuary.plusDays(60));
System.out.println(dateInJanuary.plusMinutes(6050));

Similar to the Instant class, you can use more generalized plus and minus
methods by specifying a TemporalUnit such as those provided in the
ChronoUnit class.

plus(long amountToAdd, TemporalUnit unit)


minus(long amountToSubtract, TemporalUnit unit)

You can try replacing the first example method calls in the code file to the
left:
LocalDateTime dateInJanuary = LocalDateTime.parse("2023-01-
01T11:50");
System.out.println(dateInJanuary.plus(6, ChronoUnit.YEARS));
System.out.println(dateInJanuary.plus(60, ChronoUnit.DAYS));
System.out.println(dateInJanuary.plus(6050,
ChronoUnit.MINUTES));

Comparing LocalDateTimes
If you need to figure out which LocalDateTime is earliest (e.g. filtering out
all LocalDateTimes in a Stream that have already passed) LocalDateTime
provides a couple comparative methods that are similar to the Instant
class:
* boolean isAfter(ChronoLocalDateTime<?> other) - Checks if this date-
time is after the specified date-time.
* boolean isBefore(ChronoLocalDateTime<?> other) - Checks if this date-
time is before the specified date-time.

Try it out in the code file to the left:

LocalDateTime dateInJanuary = LocalDateTime.parse("2023-01-


01T11:50");
LocalDateTime dateInFebruary = LocalDateTime.parse("2023-02-
01T11:50");

System.out.println(dateInJanuary.isBefore(dateInFebruary));
System.out.println(dateInJanuary.isAfter(dateInFebruary));
System.out.println(dateInJanuary.isEqual(dateInFebruary));

Formating with DateTimeFormatter


For printing and parsing data objects Java use DateTimeFormatter class. It
provides a number of prepared formaters (e.g. ISO_LOCAL_DATE_TIME,
ISO_INSTANT and RFC_1123_DATE_TIME).

For example:

LocalDateTime dateInJanuary = LocalDateTime.parse("2023-01-


01T11:50");

System.out.println(dateInJanuary.format(DateTimeFormatter.ISO_DATE_T
IME));

DateTimeFormatter also enables you to create your own formatter by


specifying a pattern. Patterns are based on a simple sequence of letters and
symbols.
Here is a list of the most common symbols used to create patterns:
| Symbol | Meaning | Presentation | Examples |
|——– |—————————- |————– |——————— |
| y | year | year | 2004; 04 |
| D | day-of-year | number | 189 |
| M/L | month-of-year | number/text | 7; 07; Jul; July; J |
| d | day-of-month | number | 10 |
| E | day-of-week | text | Tue; Tuesday; T |
| F | day-of-week-in-month | number | 3 |
| a | am-pm-of-day | text | PM |
| h | clock-hour-of-am-pm (1-12) | number | 12 |
| K | hour-of-am-pm (0-11) | number | 0 |
| k | clock-hour-of-day (1-24) | number | 24 |
| H | hour-of-day (0-23) | number | 0 |
| m | minute-of-hour | number | 30 |
| s | second-of-minute | number | 55 |

For example, "d MMM yyyy" will format 2011-12-03 as "3 Dec 2011".

A pattern is used to create a Formatter using the ofPattern(String) and


ofPattern(String, Locale) methods:

To format local date time to string you need to use


format(DateTimeFormatter formatter) method - formats this date-time
using the specified formatter.

LocalDateTime dateInJanuary = LocalDateTime.parse("2023-01-


01T11:50");

DateTimeFormatter formatterYyyyMMdd =
DateTimeFormatter.ofPattern("yyyy MM dd");
System.out.println(dateInJanuary.format(formatterYyyyMMdd));

DateTimeFormatter formatterMMYyyydd =
DateTimeFormatter.ofPattern("MM/dd/yyyy");
System.out.println(dateInJanuary.format(formatterMMYyyydd));
Period and Duration
To calculate the time interval between two dates in Java, there are two
classes:
1. Period
1. Duration

Period

A Period instance represents a date-based amount of time represented as


the number of years, months and days, such as ‘2 years, 3 months and 4
days’.

Period has three methods for getting the duration:


1. getYears()
1. getMonths()
1. getDays()

Period’s between() method accepts two local dates and creates a Period
consisting of the number of years, months, and days between two dates.

Try it out in the code file to the left. Here is an example to get you started:

LocalDate firstDate = LocalDate.parse("2023-01-01");


LocalDate secondDate = LocalDate.parse("2019-05-19");

Period period = Period.between(secondDate, firstDate);


System.out.format("years = %d, months = %d, days = %d",
period.getYears(), period.getMonths(),
period.getDays());

Duration

For calculations accurate up to nanoseconds, use the Duration class which


models an amount of time in terms of seconds and nanoseconds:

getNano()
getSeconds()

For example:
LocalTime startTime = LocalTime.parse("10:51");
LocalTime endTime = LocalTime.parse("13:04");

System.out.println("Duration between times is " +


Duration.between(startTime, endTime).getSeconds());

Displaying time in seconds is typically inconvenient, so Duration has


methods that convert to other units of time. For example:
* toDays() - Gets the number of days in this duration.
* toDaysPart() - Extracts the days part in the duration.
* toHours() - Gets the number of hours in this duration.
* toHoursPart() - Extracts the hours part in the duration.
* toMinutes() - Gets the number of minutes in this duration.
* toMinutesPart() - Extracts the minutes part in the duration.

Compare the difference between the methods:

LocalDateTime firstDate = LocalDateTime.parse("2023-01-


01T11:50");
LocalDateTime secondDate = LocalDateTime.parse("2019-05-
19T23:15");

Duration period = Duration.between(secondDate, firstDate);

System.out.format("days = %d, hours = %d, minutes = %d\n",


period.toDays(), period.toHoursPart(),
period.toMinutesPart());

System.out.format("days = %d, hours = %d, minutes = %d",


period.toDays(), period.toHours(), period.toMinutes());
ZonedDateTime
Time zones are usually defined as differing from UTC, meaning the current
time in a particular time zone can be determined by adding or subtracting
the number of hours and minutes specified by the UTC offset (which ranges
from UTC−12:00 in the west to UTC+14:00 in the east).

The ZonedDateTime class is responsible for working with times that


include time zones in Java. ZonedDateTime combines LocalDateTime and
ZoneId.

ZoneId

ZoneId works in two modes:


1. fixed offsets - an offset from UTC/Greenwich used for all local date-times
java ZoneId zone1 = ZoneId.of("UTC+3"); ZoneId zone2 =
ZoneId.of("UTC-01:15");

1. geographical regions - an area where a specific set of rules for finding


the offset apply
java ZoneId zoneIdLondon = ZoneId.of("Europe/London");
ZoneId zoneIdIstanbul = ZoneId.of("Asia/Istanbul"); ZoneId
zoneIdNewYork = ZoneId.of("America/New_York");

Binding a ZoneId to a geographical region allows you to take into account


daylight savings time and any history of time zone changes. This means
that there is no way to translate a time zone from one mode to another -
because while they might sometimes coincide, there will be instances
(e.g. daylight savings, historical events) where they do not.

ZonedDateTime

ZonedDateTime methods are mostly identical to LocalDateTime but require


an additional ZoneId parameter.

now() - Obtains the current date-time from the system clock in the
default time-zone.

of(int year, int month, int dayOfMonth, int hour, int minute, int
second, int nanoOfSecond, ZoneId zone) -
Obtains an instance of ZonedDateTime from a year, month, day, hour,
minute, second, nanosecond and time-zone

Additionally, there are of methods for creating a ZonedDateTime from


LocalDateTime or Instant with an indication of the time zone:

of(LocalDateTime localDateTime, ZoneId zone)


ofInstant(Instant instant, ZoneId zone)

ZoneId zoneIdLondon = ZoneId.of("Europe/London");


LocalDateTime dateInJanuary = LocalDateTime.parse("2023-01-
01T11:50:37");
Instant instantInFebruary = Instant.parse("2023-02-
01T11:50:37Z");

System.out.println(ZonedDateTime.of(dateInJanuary,
zoneIdLondon));
System.out.println(ZonedDateTime.ofInstant(instantInFebruary,
zoneIdLondon));

While we are not re-listing them here, ZonedDateTime class contains the
same methods for adding and subtracting time which you can see in the
documentation.

You might also like