7.3. Date operations (JSR-310 Date and Time API)¶
Index
7.3.1. Overview¶
java.util.Date
and java.util.Calendar
.Note
Since JSR-310 Date and Time API has been introduced from Java8, using Joda Time is recommended for the environments of versions Java8 and below. For how to use Joda Time, refer Date Operations (Joda Time).
7.3.2. How to use¶
java.time.LocalDate
, java.time.LocalTime
and java.time.LocalDateTime
, however, since the prefix of all the methods offered by each class is same for primary date and time operations, it should be interpreted by substituting with the appropriate class name.Class name | Description | Primary factory methods |
---|---|---|
Class which handles date and time operation and does not possess information about timezone difference | now Generated by current date and timeof Generated by any date and timeparse Generated from date and time stringfrom Generated from other objects with date and time information |
|
Class which handles date and time operation considering timezone difference | Same as above | |
Class to handle Japanese calendar operations | Same as above |
Class name | Description | Primary factory methods |
---|---|---|
Class which handles date and time base, time base period | between Generated from the difference between two objects with date and time informationfrom Generated from another object that contains amount of timeof Generated in any time period |
Class name | Description | Primary factory method |
---|---|---|
Class which handles operations related to date and time format | ofPattern Generates a formatter in specified pattern |
Note
For the topics that are not covered in the guideline, refer Javadoc for details.
Note
Date and Time API class is immutable (date and time calculation result is considered as a new object, and changes do not occur in the objects for calculation).
7.3.2.1. Fetch date and time¶
7.3.2.1.1. Fetch by current date and time¶
java.time.LocalTime
, java.time.LocalDate
and java.time.LocalDateTime
must be selectively used in accordance with the purpose for which it is to be used. Example is shown below.- Use
java.time.LocalTime
when only time is to be fetched.
LocalTime localTime = LocalTime.now();
- Use
java.time.LocalDate
when only date is to be fetched.
LocalDate localDate = LocalDate.now();
- Use
java.time.LocalDateTime
when both date and time are to be fetched.
LocalDateTime localDateTime = LocalDateTime.now();
7.3.2.1.2. Fetch by specifying year, month, day, hours, minutes and seconds¶
- Specify time and fetch
java.time.LocalTime
.
// 23:30:59
LocalTime localTime = LocalTime.of(23, 30, 59);
- Specify date and fetch
java.time.LocalDate
.
// 2015/12/25
LocalDate localDate = LocalDate.of(2015, 12, 25);
- Specify date and time and fetch
java.time.LocalDateTime
.
// 2015/12/25 23:30:59
LocalDateTime localDateTime = LocalDateTime.of(2015, 12, 25, 23, 30, 59);
java.time.temporal.TemporalAdjusters
.// LeapYear(2012/2)
LocalDate localDate1 = LocalDate.of(2012, 2, 1);
// Last day of month(2012/2/29)
LocalDate localDate2 = localDate1.with(TemporalAdjusters.lastDayOfMonth());
// Next monday(2012/2/6)
LocalDate localDate3 = localDate1.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
Note
Unlike the specifications of java.util.Calendar
, calendar month starts from 1.
7.3.2.1.3. Fetch date and time when time zone is specified¶
java.time.OffsetTime
, java.time.OffsetDateTime
and java.time.ZonedDateTime
must be used selectively in Date and Time API in accordance with the purpose for which it is to be used.- Use
java.time.OffsetTime
when the time difference between time + UTC is to be fetched.
// Ex, 12:30:11.567+09:00
OffsetTime offsetTime = OffsetTime.now();
- Use
java.time.OffsetDateTime
when the time difference between date, time + UTC is to be fetched.
// Ex, 2015-12-25T12:30:11.567+09:00
OffsetDateTime offsetDateTime = OffsetDateTime.now();
- Use
java.time.ZonedDateTime
when the time difference and region for date, time + UTC is to be fetched.
// Ex, 2015-12-25T12:30:11.567+09:00[Asia/Tokyo]
ZonedDateTime zonedDateTime = ZonedDateTime.now();
java.time.ZoneId
which indicates time zone in the argument.java.time.ZoneId
example is shown below.ZoneId zoneIdTokyo = ZoneId.of("Asia/Tokyo");
OffsetTime offsetTime = OffsetTime.now(zoneIdTokyo);
java.time.ZoneId
consists of a method to be defined by region name/area name format and a method defined by time difference from UTC.ZoneId.of("Asia/Tokyo");
ZoneId.of("UTC+01:00");
java.time.OffsetDateTime
and java.time.ZonedDateTime
is similar, the basic difference is as given below.Class name | Description |
---|---|
java.time.OffsetDateTime |
Since it only consists of quantitative value (only time difference), system does not undergo any change even if there is a change in the concept of time for each area. |
java.time.ZonedDateTime |
Since it includes concept of region besides time difference, the system undergoes change when a change occurs in the concept of time for each region.(when daylight saving etc is included as a policy) |
7.3.2.2. Time period¶
7.3.2.2.1. Fetch time period¶
java.time.Period
is used while handling date based period and java.time.Duration
is used while handling time based period.java.time.Duration
is of exactly 24 hours, expected results may not be obtained if daylight saving changes are not incorporated.java.time.Period
represents 1 day including daylight saving, an error does not occur even in the system which handles daylight saving.LocalDate date1 = LocalDate.of(2010, 01, 15);
LocalDate date2 = LocalDate.of(2011, 03, 18);
LocalTime time1 = LocalTime.of(11, 50, 50);
LocalTime time2 = LocalTime.of(12, 52, 53);
// One year, two months and three days.
Period pd = Period.between(date1, date2);
// One hour, two minutes and three seconds.
Duration dn = Duration.between(time1, time2);
Note
A method can also be employed wherein the period is generated by specifying it by using
of
method. For details, refer Javadoc of Period, Duration.
7.3.2.3. Type conversion¶
7.3.2.3.1. Interoperability of each class of Date and Time API¶
java.time.LocalTime
, java.time.LocalDate
and java.time.LocalDateTime
can easily be mutually converted. Example is given below.- Conversion from
java.time.LocalTime
tojava.time.LocalDateTime
.
// Ex. 12:10:30
LocalTime localTime = LocalTime.now();
// 2015-12-25 12:10:30
LocalDateTime localDateTime = localTime.atDate(LocalDate.of(2015, 12, 25));
- Conversion from
java.time.LocalDate
tojava.time.LocalDateTime
.
// Ex. 2012-12-25
LocalDate localDate = LocalDate.now();
// 2015-12-25 12:10:30
LocalDateTime localDateTime = localDate.atTime(LocalTime.of(12, 10, 30));
- Conversion from
java.time.LocalDateTime
tojava.time.LocalTime
andjava.time.LocalDate
.
// Ex. 2015-12-25 12:10:30
LocalDateTime localDateTime = LocalDateTime.now();
// 12:10:30
LocalTime localTime = localDateTime.toLocalTime();
// 2012-12-25
LocalDate localDate = localDateTime.toLocalDate();
java.time.OffsetTime
, java.time.OffsetDateTime
and java.time.ZonedDateTime
can also be easily mutually converted. Example is given below.- Conversion from
java.time.OffsetTime
tojava.time.OffsetDateTime
.
// Ex, 12:30:11.567+09:00
OffsetTime offsetTime = OffsetTime.now();
// 2015-12-25T12:30:11.567+09:00
OffsetDateTime offsetDateTime = offsetTime.atDate(LocalDate.of(2015, 12, 25));
- Conversion from
java.time.OffsetDateTime
tojava.time.ZonedDateTime
.
// Ex, 2015-12-25T12:30:11.567+09:00
OffsetDateTime offsetDateTime = OffsetDateTime.now();
// 2015-12-25T12:30:11.567+09:00[Asia/Tokyo]
ZonedDateTime zonedDateTime = offsetDateTime.atZoneSameInstant(ZoneId.of("Asia/Tokyo"));
- Conversion from
java.time.ZonedDateTime
tojava.time.OffsetDateTime
andjava.time.OffsetTime
.
// Ex, 2015-12-25T12:30:11.567+09:00[Asia/Tokyo]
ZonedDateTime zonedDateTime = ZonedDateTime.now();
// 2015-12-25T12:30:11.567+09:00
OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime();
// 12:30:11.567+09:00
OffsetTime offsetTime = zonedDateTime.toOffsetDateTime().toOffsetTime();
java.time.LocalTime
can be converted to java.time.OffsetTime
by adding time difference information.// Ex, 12:30:11.567
LocalTime localTime = LocalTime.now();
// 12:30:11.567+09:00
OffsetTime offsetTime = localTime.atOffset(ZoneOffset.ofHours(9));
LocalTime
to LocalDateTime
).7.3.2.3.2. Interoperability with java.util.Date¶
A method which directly converts java.time.LocalDate
class to java.util.Date
is not provided.
java.time.Instant
offered by Date and Time API is added to java.util.Date
from Java8 and subsequent versions, a conversion can be carried out through java.time.Instant
.- Conversion from
java.time.LocalDateTime
tojava.util.Date
.
LocalDateTime localDateTime = LocalDateTime.now();
Instant instant = localDateTime.toInstant(ZoneOffset.ofHours(9));
Date date = Date.from(instant);
- Conversion from
java.util.Date
tojava.time.LocalDateTime
.
Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
Note
Since
java.time.LocalTime
andjava.time.LocalDate
do not contain Instant values, it is necessary to convert once tojava.time.LocalDateTime
.
7.3.2.3.3. Interoperability with java.sqlpackage¶
java.sql
package from Java8 version and a method for mutual conversion with java.time
package is defined.- Conversion from
java.sql.Date
tojava.time.LocalDate
.
java.sql.Date date = new java.sql.Date(System.currentTimeMillis());
LocalDate localDate = date.toLocalDate();
- Conversion from
java.time.LocalDate
tojava.sql.Date
.
LocalDate localDate = LocalDate.now();
java.sql.Date date = java.sql.Date.valueOf(localDate);
- Conversion from
java.sql.Time
tojava.time.LocalTime
.
java.sql.Time time = new java.sql.Time(System.currentTimeMillis());
LocalTime localTime = time.toLocalTime();
- Conversion from
java.time.LocalTime
tojava.sql.Time
.
LocalTime localTime = LocalTime.now();
java.sql.Time time = java.sql.Time.valueOf(localTime);
- Conversion from
java.sql.Timestamp
tojava.time.LocalDateTime
.
java.sql.Timestamp timestamp = new java.sql.Timestamp(System.currentTimeMillis());
LocalDateTime localDateTime = timestamp.toLocalDateTime();
- Conversion from
java.time.LocalDateTime
tojava.sql.Timestamp
.
LocalDateTime localDateTime = LocalDateTime.now();
java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf(localDateTime);
7.3.2.3.4. How to use org.terasoluna.gfw.common.date package¶
java.time.LocalDate
can be generated by using org.terasoluna.gfw.common.date.ClassicDateFactory
and java.sql.Date
as an interim measure.java.time.LocalDate
even for the java.time.LocalTime
and java.time.LocalDateTime
classes.bean definition file ([projectname]-env.xml)
<bean id="dateFactory" class="org.terasoluna.gfw.common.date.DefaultClassicDateFactory" />
Java class
@Inject
ClassicDateFactory dateFactory;
public DateFactorySample getSystemDate() {
java.sql.Date date = dateFactory.newSqlDate();
LocalDate localDate = date.toLocalDate();
// omitted
}
Note
Date Factory corresponding to Date and Time API will be added later.
7.3.2.3.5. Format for the string¶
toString
method and a method which uses java.time.fomat.DateTimeFormatter
can be used for converting the object containing date and time information to string.java.time.fomat.DateTimeFormatter
.java.time.fomat.DateTimeFormatter
consists of a method which uses a formatter of predefined ISO pattern and a method which is used by defining a format of any pattern.DateTimeFormatter formatter1 = DateTimeFormatter.BASIC_ISO_DATE;
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("G uuuu/MM/dd E")
.withLocale(Locale.JAPANESE)
.withResolverStyle(ResolverStyle.STRICT);
Locale
and ResolverStyle
(strict) can be defined besides string format.Locale
changes depending on the system, it should be set at the time of initialization.ResolverStyle
(strict) uses ofPattern
method, ResolverStyle.SMART
is set as default, however, in this guideline, it is recommended to specify ResolverStyle.STRICT
for strict interpretation of date to avoid occurrence of unexpected behaviour.(When ISO pattern formatter is to be used, ResolverStyle.STRICT
is specified.)yyyy
in Date and Time API represent year in the calendar, interpretation will be different according to the calendar. (Year will be 2015 according to Western calendar but will be 0027 according to Japanese calendar).uuuu
format instead of yyyy
format.For the defined format list, refer DateTimeFormatter .DateTimeFormatter formatter1 = DateTimeFormatter.BASIC_ISO_DATE;
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("G uuuu/MM/dd E")
.withLocale(Locale.JAPANESE)
.withResolverStyle(ResolverStyle.STRICT);
LocalDate localDate1 = LocalDate.of(2015, 12, 25);
// "2015-12-25"
System.out.println(localDate1.toString());
// "20151225"
System.out.println(formatter1.format(localDate1));
// "Western calendar 2015/12/25 Friday"
System.out.println(formatter2.format(localDate1));
fmt:formatDate
tag of JSTL handles only java.util.Date
and java.util.TimeZone
objects,Controller class
@Controller
public class HomeController {
@RequestMapping(value = "/", method = {RequestMethod.GET, RequestMethod.POST})
public String home(Model model, Locale locale) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu/MM/dd")
.withLocale(locale)
.withResolverStyle(ResolverStyle.STRICT);
LocalDate localDate1 = LocalDate.now();
model.addAttribute("currentDate", localDate1.toString());
model.addAttribute("formattedCurrentDateString", dateFormatter.format(localDate1));
// omitted
}
}
jsp file
<p>currentDate = ${f:h(currentDate)}.</p>
<p>formattedCurrentDateString = ${f:h(formattedCurrentDateString)}.</p>
Output results example (html)
<p>currentDate = 2015-12-25.</p>
<p>formattedCurrentDateString = 2015/12/25.</p>
7.3.2.3.6. Path from the string¶
java.time.fomat.DateTimeFormatter
.DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("uuuu/MM/dd")
.withLocale(Locale.JAPANESE)
.withResolverStyle(ResolverStyle.STRICT);
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("HH:mm:ss")
.withLocale(Locale.JAPANESE)
.withResolverStyle(ResolverStyle.STRICT);
LocalDate localDate = LocalDate.parse("2015/12/25", formatter1);
LocalTime localTime = LocalDate.parse("14:09:20", formatter2);
7.3.2.4. Date operation¶
7.3.2.4.1. Date and time calculation¶
plus
method and minus
method are provided for calculating date and time.- Example for calculating time.
LocalTime localTime = LocalTime.of(20, 30, 50);
LocalTime plusHoursTime = localTime.plusHours(2);
LocalTime plusMinutesTime = localTime.plusMinutes(10);
LocalTime minusSecondsTime = localTime.minusSeconds(15);
- Example for calculating date.
LocalDate localDate = LocalDate.of(2015, 12, 25);
LocalDate plusYearsDate = localDate.plusYears(10);
LocalDate minusMonthsTime = localDate.minusMonths(1);
LocalDate plusDaysTime = localDate.plusDays(3);
Note
If a negative number is passed in the
plus
method, results similar to the results at the time of usingminus
method can be obtained. Same forminus
method.
7.3.2.4.2. Date and time comparison¶
- Example for comparison of time.
LocalTime morning = LocalTime.of(7, 30, 00);
LocalTime daytime = LocalTime.of(12, 00, 00);
LocalTime evening = LocalTime.of(17, 30, 00);
daytime.isBefore(morning); // false
morning.isAfter(evening); // true
evening.equals(LocalTime.of(17, 30, 00)); // true
daytime.isBefore(daytime); // false
morning.isAfter(morning); // false
- Example for comparison of date.
LocalDate may = LocalDate.of(2015, 6, 1);
LocalDate june = LocalDate.of(2015, 7, 1);
LocalDate july = LocalDate.of(2015, 8, 1);
may.isBefore(june); // true
june.isAfter(july); // false
july.equals(may); // false
may.isBefore(may); // false
june.isAfter(june); // false
Interval
of Joda Time currently does not exist in Date and Time API.7.3.2.4.3. Determination of date and time¶
- When a valid date and time string is to be determined, it can be determined based on the occurrence and non-occurrence of
java.time.format.DateTimeParseException
.
String strDateTime = "aabbcc";
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HHmmss")
.withLocale(Locale.JAPANESE)
.withResolverStyle(ResolverStyle.STRICT);;
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuMMdd")
.withLocale(Locale.JAPANESE)
.withResolverStyle(ResolverStyle.STRICT);;
try {
// DateTimeParseException
LocalTime localTime = LocalTime.parse(strDateTime, timeFormatter);
}
catch (DateTimeParseException e) {
System.out.println("Invalid time string !!");
}
try {
// DateTimeParseException
LocalDate localDate = LocalDate.parse(strDateTime, dateFormatter);
}
catch (DateTimeParseException e) {
System.out.println("Invalid date string !!");
}
- When a leap year is to be determined,
isLeapYear
method ofjava.time.LocalDate
can be used.
LocalDate date1 = LocalDate.of(2012, 1, 1);
LocalDate date2 = LocalDate.of(2015, 1, 1);
date1.isLeapYear(); // true
date2.isLeapYear(); // false
7.3.2.4.4. Fetching year, month, day, hours, minutes, seconds¶
get
method.LocalDate localDate = LocalDate.of(2015, 2, 1);
// 2015
int year = localDate.getYear();
// 2
int month = localDate.getMonthValue();
// 1
int dayOfMonth = localDate.getDayOfMonth();
// 32 ( day of year )
int dayOfYear = localDate.getDayOfYear();
7.3.2.5. Japanese calendar (JapaneseDate)¶
java.time.chrono.JapaneseDate
is provided in Date and Time API to handle Japanese calendar.Note
java.time.chrono.JapaneseDate
cannot be used before Meiji 6 (1873 of Western calendar) when the Gregorian calendar was introduced.
7.3.2.5.1. Fetching Japanese calendar¶
java.time.LocalDate
, Japanese calendar can be fetched by using now
method and of
method.java.time.chrono.JapaneseEra
class.JapaneseDate japaneseDate1 = JapaneseDate.now();
JapaneseDate japaneseDate2 = JapaneseDate.of(2015, 12, 25);
JapaneseDate japaneseDate3 = JapaneseDate.of(JapaneseEra.HEISEI, 27, 12, 25);
// DateTimeException
JapaneseDate japaneseDate = JapaneseDate.of(1500, 1, 1);
7.3.2.5.2. Format for the string¶
java.time.fomat.DateTimeFormatter
. While using, calendar is set to java.time.chrono.JapaneseChronology
by using DateTimeFormatter#withChronology
method.DateTimeFormatter formatter = DateTimeFormatter.ofPattern("GppyYearppMMonthppdDay")
.withLocale(Locale.JAPANESE)
.withResolverStyle(ResolverStyle.STRICT)
.withChronology(JapaneseChronology.INSTANCE);
JapaneseDate japaneseDate = JapaneseDate.of(1992, 1, 1);
// "Heisei YY4 MM1 DD1"
System.out.println(formatter.format(japaneseDate));
7.3.2.5.3. Path from the string¶
java.time.chrono.JapaneseDate
by using java.time.fomat.DateTimeFormatter
.DateTimeFormatter formatter = DateTimeFormatter.ofPattern("GyYearMMMonthddDate")
.withLocale(Locale.JAPANESE)
.withResolverStyle(ResolverStyle.STRICT)
.withChronology(JapaneseChronology.INSTANCE);
JapaneseDate japaneseDate1 = JapaneseDate.from(formatter.parse("Heisei 27YY12MM25DD"));
JapaneseDate japaneseDate2 = JapaneseDate.from(formatter.parse("Meiji YY6MM01DD01"));
7.3.2.5.4. Conversion of Western and Japanese calendar¶
java.time.LocalDate
by using from method.LocalDate localDate = LocalDate.of(2015, 12, 25);
JapaneseDate jpDate = JapaneseDate.from(localDate);