New Java8 features, the right posture for Data and Time

It has been a long time since Java8 was released. The new version of java has brought us a lot of exciting new features. The new API s of Date and Time bring new good news to the students who normally need to perform various complex operations on time and date. This article also starts from this point to explore the new features of Data and Time.

Basically, this article is code-based, text-assisted.There won't be too much text because most of the code is concise and understandable at first glance.

LocalDate

All new API s for Data/Time are included in the java.time package. First, let's look at java.time.LocalDate, which represents a time-independent date with a specific format year-month-day.

// the current date
LocalDate currentDate = LocalDate.now();
 
// 2014-02-10
LocalDate tenthFeb2014 = LocalDate.of(2017, Month.FEBRUARY, 10);
 
// months values start at 1 (2014-08-01)
LocalDate firstAug2014 = LocalDate.of(2014, 8, 1);
 
// the 65th day of 2010 (2010-03-06)
LocalDate sixtyFifthDayOf2010 = LocalDate.ofYearDay(2010, 65);

LocalTime, LocalDateTime

LocalTime is a time-only class without dates, and LocalDateTime is a combination of LocalTime and LocalDate.Here are the usages of these two classes:

LocalTime currentTime = LocalTime.now(); // current time
LocalTime midday = LocalTime.of(12, 0); // 12:00
LocalTime afterMidday = LocalTime.of(13, 30, 15); // 13:30:15
 
// 12345th second of day (03:25:45)
LocalTime fromSecondsOfDay = LocalTime.ofSecondOfDay(12345);
 
// dates with times, e.g. 2014-02-18 19:08:37.950
LocalDateTime currentDateTime = LocalDateTime.now();
 
// 2014-10-02 12:30
LocalDateTime secondAug2014 = LocalDateTime.of(2014, 10, 2, 12, 30);
 
// 2014-12-24 12:00
LocalDateTime christmas2014 = LocalDateTime.of(2014, Month.DECEMBER, 24, 12, 0);

LocalDate/Time normally uses the system's default clock and time zone. If you want to query the time in other time zones, you can do the following:

// current (local) time in Los Angeles
LocalTime currentTimeInLosAngeles = LocalTime.now(ZoneId.of("America/Los_Angeles"));

// current time in UTC time zone
LocalTime nowInUtc = LocalTime.now(Clock.systemUTC());

Here's an example of a combination of LocalTime/Date:

LocalDate date = LocalDate.of(2014, 2, 15); // 2014-02-15
 
boolean isBefore = LocalDate.now().isBefore(date); // false
 
// information about the month
Month february = date.getMonth(); // FEBRUARY
int februaryIntValue = february.getValue(); // 2
int minLength = february.minLength(); // 28
int maxLength = february.maxLength(); // 29
Month firstMonthOfQuarter = february.firstMonthOfQuarter(); // JANUARY
 
// information about the year
int year = date.getYear(); // 2014
int dayOfYear = date.getDayOfYear(); // 46
int lengthOfYear = date.lengthOfYear(); // 365
boolean isLeapYear = date.isLeapYear(); // false
 
DayOfWeek dayOfWeek = date.getDayOfWeek();
int dayOfWeekIntValue = dayOfWeek.getValue(); // 6
String dayOfWeekName = dayOfWeek.name(); // SATURDAY
 
int dayOfMonth = date.getDayOfMonth(); // 15
LocalDateTime startOfDay = date.atStartOfDay(); // 2014-02-15 00:00
 
// time information
LocalTime time = LocalTime.of(15, 30); // 15:30:00
int hour = time.getHour(); // 15
int second = time.getSecond(); // 0
int minute = time.getMinute(); // 30
int secondOfDay = time.toSecondOfDay(); // 55800

In addition to this, the new api also provides a Year class, so let's see what we can do with it:

Year currentYear = Year.now();
Year twoThousand = Year.of(2000);
boolean isLeap = currentYear.isLeap(); // false
int length = currentYear.length(); // 365
 
// sixtyFourth day of 2014 (2014-03-05)
LocalDate date = Year.of(2014).atDay(64);

We can use methods like plus and minus to do some basic addition and subtraction of time.These methods return a new related instance:

LocalDate tomorrow = LocalDate.now().plusDays(1);
 
// before 5 houres and 30 minutes
LocalDateTime dateTime = LocalDateTime.now().minusHours(5).minusMinutes(30);

Temporal Adjusters is another very important interface for manipulating time and date, which provides different static methods to support time and date operations:

LocalDate date = LocalDate.of(2014, Month.FEBRUARY, 25); // 2014-02-25
 
// first day of february 2014 (2014-02-01)
LocalDate firstDayOfMonth = date.with(TemporalAdjusters.firstDayOfMonth());
 
// last day of february 2014 (2014-02-28)
LocalDate lastDayOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());

Using static imports will make your code more readable

import static java.time.temporal.TemporalAdjusters.*;

...

// last day of 2014 (2014-12-31)
LocalDate lastDayOfYear = date.with(lastDayOfYear());

// first day of next month (2014-03-01)
LocalDate firstDayOfNextMonth = date.with(firstDayOfNextMonth());

// next sunday (2014-03-02)
LocalDate nextSunday = date.with(next(DayOfWeek.SUNDAY));

Time zones

If you want to associate date/time with time zone, java provides another class, ZoneDateTIme or OffsetDateTime

ZoneId losAngeles = ZoneId.of("America/Los_Angeles");
ZoneId berlin = ZoneId.of("Europe/Berlin");
 
// 2014-02-20 12:00
LocalDateTime dateTime = LocalDateTime.of(2014, 02, 20, 12, 0);
 
// 2014-02-20 12:00, Europe/Berlin (+01:00)
ZonedDateTime berlinDateTime = ZonedDateTime.of(dateTime, berlin);
 
// 2014-02-20 03:00, America/Los_Angeles (-08:00)
ZonedDateTime losAngelesDateTime = berlinDateTime.withZoneSameInstant(losAngeles);
 
int offsetInSeconds = losAngelesDateTime.getOffset().getTotalSeconds(); // -28800
 
// a collection of all available zones
Set<String> allZoneIds = ZoneId.getAvailableZoneIds();
 
// using offsets
LocalDateTime date = LocalDateTime.of(2013, Month.JULY, 20, 3, 30);
ZoneOffset offset = ZoneOffset.of("+05:00");
 
// 2013-07-20 03:30 +05:00
OffsetDateTime plusFive = OffsetDateTime.of(date, offset);
 
// 2013-07-19 20:30 -02:00
OffsetDateTime minusTwo = plusFive.withOffsetSameInstant(ZoneOffset.ofHours(-2));

TimeStamps timestamp

LocalData and ZonedDateTime provide time and date methods that are human readable, but we can use this class if we need to explore time and date from a machine perspective.The instant calculation starts on the first second of January 1, 1970 (1970-01 00:00:00), also known as EPOCH.Immediate values can be negative if they occur before the time.They follow ISO 8601 standards for representing dates and times.

// current time
Instant now = Instant.now();
 
// from unix timestamp, 2010-01-01 12:00:00
Instant fromUnixTimestamp = Instant.ofEpochSecond(1262347200);
 
// same time in millis
Instant fromEpochMilli = Instant.ofEpochMilli(1262347200000l);
 
// parsing from ISO 8601
Instant fromIso8601 = Instant.parse("2010-01-01T12:00:00Z");
 
// toString() returns ISO 8601 format, e.g. 2014-02-15T01:02:03Z
String toIso8601 = now.toString();
 
// as unix timestamp
long toUnixTimestamp = now.getEpochSecond();
 
// in millis
long toEpochMillis = now.toEpochMilli();
 
// plus/minus methods are available too
Instant nowPlusTenSeconds = now.plusSeconds(10);

Periods, Durations

These are the other two very useful and important classes.Period mainly uses date-based values, such as years, months, days, to represent a period of time.Duration s are based on seconds or milliseconds.Their values can be negative if the end time occurs before the start time.

// periods
 
LocalDate firstDate = LocalDate.of(2010, 5, 17); // 2010-05-17
LocalDate secondDate = LocalDate.of(2015, 3, 7); // 2015-03-07
Period period = Period.between(firstDate, secondDate);
 
int days = period.getDays(); // 18
int months = period.getMonths(); // 9
int years = period.getYears(); // 4
boolean isNegative = period.isNegative(); // false
 
Period twoMonthsAndFiveDays = Period.ofMonths(2).plusDays(5);
LocalDate sixthOfJanuary = LocalDate.of(2014, 1, 6);
 
// add two months and five days to 2014-01-06, result is 2014-03-11
LocalDate eleventhOfMarch = sixthOfJanuary.plus(twoMonthsAndFiveDays);
 
 
// durations
 
Instant firstInstant= Instant.ofEpochSecond( 1294881180 ); // 2011-01-13 01:13
Instant secondInstant = Instant.ofEpochSecond(1294708260); // 2011-01-11 01:11
 
Duration between = Duration.between(firstInstant, secondInstant);
 
// negative because firstInstant is after secondInstant (-172920)
long seconds = between.getSeconds();
 
// get absolute result in minutes (2882)
long absoluteResult = between.abs().toMinutes();
 
// two hours in seconds (7200)
long twoHoursInSeconds = Duration.ofHours(2).getSeconds();

Formatting, Parsing

/ 2014-04-01 10:45
LocalDateTime dateTime = LocalDateTime.of(2014, Month.APRIL, 1, 10, 45);
 
// format as basic ISO date format (20140220)
String asBasicIsoDate = dateTime.format(DateTimeFormatter.BASIC_ISO_DATE);
 
// format as ISO week date (2014-W08-4)
String asIsoWeekDate = dateTime.format(DateTimeFormatter.ISO_WEEK_DATE);
 
// format ISO date time (2014-02-20T20:04:05.867)
String asIsoDateTime = dateTime.format(DateTimeFormatter.ISO_DATE_TIME);
 
// using a custom pattern (01/04/2014)
String asCustomPattern = dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
 
// french date formatting (1. avril 2014)
String frenchDate = dateTime.format(DateTimeFormatter.ofPattern("d. MMMM yyyy", new Locale("fr")));
 
// using short german date/time formatting (01.04.14 10:45)
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
    .withLocale(new Locale("de"));
String germanDateTime = dateTime.format(formatter);
 
// parsing date strings
LocalDate fromIsoDate = LocalDate.parse("2014-01-20");
LocalDate fromIsoWeekDate = LocalDate.parse("2014-W14-2", DateTimeFormatter.ISO_WEEK_DATE);
LocalDate fromCustomPattern = LocalDate.parse("20.01.2014", DateTimeFormatter.ofPattern("dd.MM.yyyy"));

Conversion between different date/time objects

// LocalDate/LocalTime <-> LocalDateTime
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTimeFromDateAndTime = LocalDateTime.of(date, time);
LocalDate dateFromDateTime = LocalDateTime.now().toLocalDate();
LocalTime timeFromDateTime = LocalDateTime.now().toLocalTime();
 
// Instant <-> LocalDateTime
Instant instant = Instant.now();
LocalDateTime dateTimeFromInstant = LocalDateTime.ofInstant(instant, ZoneId.of("America/Los_Angeles"));
Instant instantFromDateTime = LocalDateTime.now().toInstant(ZoneOffset.ofHours(-2));
 
// convert old date/calendar/timezone classes
Instant instantFromDate = new Date().toInstant();
Instant instantFromCalendar = Calendar.getInstance().toInstant();
ZoneId zoneId = TimeZone.getDefault().toZoneId();
ZonedDateTime zonedDateTimeFromGregorianCalendar = new GregorianCalendar().toZonedDateTime();
 
// convert to old classes
Date dateFromInstant = Date.from(Instant.now());
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("America/Los_Angeles"));
GregorianCalendar gregorianCalendar = GregorianCalendar.from(ZonedDateTime.now());

Now, the operation of time and date is really much more convenient than before. We can say goodbye to all kinds of logical operations of egg pain completely.

Keywords: Java Unix

Added by cactuscake on Thu, 30 May 2019 19:27:03 +0300