
java.util.Date
and java.util.Calendar
Bikram Samvat (Bikram Sambat)
Hindu Calendar
Various Calendars
Yuga
Roman Calendar
Julian Calendar
Gregorian Calendar
32,768 Hz
Cesium 133: 9,192,631,770 cycles of radiation
Format |
Example |
Date |
2014-01-01 |
Combined Date and Time in UTC |
2014-07-07T07:01Z |
Combined Date and Time in MDT |
2014-07-07T07:38:51.716-06:00 |
Date With Week Number |
2014-W27-3 |
Ordinal Date |
2014-188 |
Duration |
P3Y6M4DT12H30M5S |
Finite Interval |
2014-03-01T13:00:00Z/2015-05-11T15:30:00Z |
Finite Start with Duration |
2014-03-01T13:00:00Z/P1Y2M10DT2H30M |
Duration with with Finite End |
P1Y2M10DT2H30M/2015-05-11T15:30:00Z |
java.util.Date
What was wrong with it?
java.util.Calendar
What is wrong with it?
> new java.util.GregorianCalendar
java.util.GregorianCalendar = java.util.GregorianCalendar[time=1393764079082,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSaving=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSaving=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=2,WEEK_OF_YEAR=10,WEEK_OF_MONTH=2,DAY_OF_MONTH=2,DAY_OF_YEAR=61,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=7,HOUR_OF_DAY=7,MINUTE=41,SECOND=19,MILLISECOND=82,ZONE_OFFSET=-18000000,DST_...
java.time
- Base package for managing date timejava.time.chrono
- Package that handles alternative calendering and chronology systemsjava.time.format
- Package that handles formatting of dates and timesjava.time.temporal
- Package that allows us to query dates and timesof
- static factory usually validating input parameters not converting themfrom
- static factory that converts to an instance of a target classparse
- static factory that parses an input stringformat
- uses a specified formatter to format the dateget
- Returns part of the state of the target objectis
- Queries the state of the objectwith
- Returns a copy of the object with one element changed, this is the immutable equivalentplus
- Returns a copy of the target object with the amount of time addedminus
- Returns a copy of the target object with the amount of time subtractedto
- Converts this object to another object typeat
- Combines the object with another1970-01-01T00:00:00Z
java.util.Date
and long
representationContains two states:
long
of seconds since the Unix Epochint
of nano seconds within one secondAn Instant
can be resolved as 1.844674407×1019 seconds
or 584542046090 years!
Instant
Instant now = Instant.now();
System.out.println(now.getEpochSecond());
System.out.println(now.getNano());
System.out.println(Instant.parse("2014-02-20T20:21:20.432Z"));
Instant
Month
and DayOfWeek
The Java Date/Time API contains enum
classes to describe our months and days
Month
DayOfWeek
Month
and DayOfWeek
ExemplifiedDayOfWeek.SUNDAY
DayOfWeek.FRIDAY
Month.JANUARY
Month.JULY
Month.DECEMBER
ChronoUnit
enum
to represent a unit of time for a scalarimplements TemporalUnit
ChronoUnit
is meant to be general enough for various calendarsChronoUnit
ChronoUnit
ExemplifiedChronoUnit.DAYS
ChronoUnit.CENTURIES
ChronoUnit.ERAS
ChronoUnit.MINUTES
ChronoUnit.MONTHS
ChronoUnit.SECONDS
ChronoUnit.FOREVER
Instant.now().plus(19, ChronoUnit.DAYS)
ChronoField
Given: 2010-10-22T12:00:13
has six fields
2010
10
22
12
0
13
implements TemporalField
ChronoField
is also meant to be general enough for various calendarsChronoField
ExemplifiedChronoField.MONTH_OF_YEAR
ChronoField.DAY_OF_MONTH
ChronoField.HOUR_OF_DAY
ChronoField.SECOND_OF_MINUTE
ChronoField.SECOND_OF_DAY
ChronoField.MINUTE_OF_DAY
ChronoField.MINUTE_OF_HOUR
Instant.now.get(ChronoField.HOUR_OF_DAY);
ChronoField
LocalDate
- An ISO 8601 date representation without timezone and timeLocalTime
- An ISO 8601 time representation without timezone and dateLocalDateTime
- An ISO 8601 date and time representation without time zoneLocalDate
, LocalTime
, LocalDateTime
LocalDate
exemplifiedLocalDate february20th = LocalDate.of(2014, Month.FEBRUARY, 20);
february20th; //2014-02-20
LocalDate.from(february20th.plus(15, ChronoUnit.YEARS)); //2029-02-20
LocalDate.parse("2014-11-22"); //2014-11-22
LocalTime
exemplifiedLocalTime.MIDNIGHT; //00:00
LocalTime.NOON; //12:00
LocalTime.of(23, 12, 30, 500); //23:12:30.000000500
LocalTime.now(); //00:40:34.110
LocalTime.ofSecondOfDay(11 * 60 * 60); //11:00
LocalTime.from(LocalTime.MIDNIGHT.plusHours(4)); //04:00
LocalDateTime
exemplifiedLocalDateTime.of(2014, 2, 15, 12, 30, 50, 200); //2014-02-15T12:30:50.000000200
LocalDateTime.now(); //2014-02-28T17:28:21.002
LocalDateTime.from(
LocalDateTime.of
(2014, 2, 15, 12, 30, 40, 500)
.plusHours(19))); //2014-02-16T07:30:40.000000500
LocalDateTime.MIN; //-999999999-01-01T00:00
LocalDateTime.MAX; //+999999999-12-31T23:59:59.999999999
ZonedDateTime
LocalDate
, LocalTime
, and LocalDateTime
to ZonedDateTime
ZoneId
ZoneId
represents the IANA Time Zone Entry# Monaco
# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
# more precise 0:09:21.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
0:09:21 - PMT 1911 Mar 11 # Paris Mean Time
0:00 France WE%sT 1945 Sep 16 3:00
1:00 France CE%sT 1977
1:00 EU CE%sT
ZoneId
ZoneId.of("America/Denver");
ZoneId.of("Asia/Jakarta");
ZoneId.of("America/Los_Angeles");
ZoneId.ofOffset("UTC", ZoneOffset.ofHours(-6));
ZoneId
namingMap<String, String> map = new HashMap<String, String>();
map.put("Pacific", "America/Los_Angeles");
map.put("Mountain", "America/Denver");
map.put("Central", "America/Chicago");
map.put("Eastern", "America/New_York");
ZoneId.of("Mountain", map); // Same as "America/Denver"
ZonedDateTime
ZonedDateTime
exemplifiedZonedDateTime.now(); //Current Date Time with Zone
ZonedDateTime myZonedDateTime = ZonedDateTime.of(2014, 1, 31, 11, 20, 30, 93020122, ZoneId.systemDefault());
ZonedDateTime nowInAthens = ZonedDateTime.now(ZoneId.of("Europe/Athens"));
LocalDate localDate = LocalDate.of(2013, 11, 12);
LocalTime localTime = LocalTime.of(23, 10, 44, 12882);
ZoneId chicago = ZoneId.of("America/Chicago");
ZonedDateTime chicagoTime = ZonedDateTime.of(localDate, localTime, chicago);
LocalDateTime localDateTime = LocalDateTime.of(1982, Month.APRIL, 17, 14, 11);
ZonedDateTime jakartaTime = ZonedDateTime.of(localDateTime, ZoneId.of("Asia/Jakarta"));
In the summer
LocalDateTime date = LocalDateTime.of(2012, 11, 12, 13, 11, 12);
date.atZone(ZoneId.of("America/Los_Angeles")) //2012-11-12T13:11:12-08:00[America/Los_Angeles]
LocalDateTime daylightSavingTime = LocalDateTime.of(2014, 3, 9, 2, 0, 0, 0);
daylightSavingTime.atZone(ZoneId.of("America/Denver")); //2014-03-09T03:00-06:00[America/Denver]
LocalDateTime daylightSavingTime2 = LocalDateTime.of(2014, 3, 9, 2, 30, 0, 0);
daylightSavingTime2.atZone(ZoneId.of("America/New_York")); //2014-03-09T03:30-04:00[America/New_York]
LocalDateTime daylightSavingTime3 = LocalDateTime.of(2014, 3, 9, 2, 0, 0, 0);
daylightSavingTime3.atZone(ZoneId.of("America/Phoenix")); //2014-03-09T03:59:59.999999999-05:00[America/Chicago]
LocalDateTime daylightSavingTime4 = LocalDateTime.of(2014, 3, 9, 2, 59, 59, 999999999);
daylightSavingTime4.atZone(ZoneId.of("America/Chicago")); //2014-03-09T02:00-07:00[America/Phoenix]
In the winter
LocalDateTime date2 = LocalDateTime.of(2012, 11, 12, 13, 11, 12);
date2.atZone(ZoneId.of("America/Los_Angeles"))); //2012-11-12T13:11:12-08:00[America/Los_Angeles]
LocalDateTime standardTime = LocalDateTime.of(2014, 11, 2, 2, 0, 0, 0);
standardTime.atZone(ZoneId.of("America/Denver")); //2014-11-02T02:00-07:00[America/Denver]
LocalDateTime standardTime2 = LocalDateTime.of(2014, 11, 2, 2, 30, 0, 0);
standardTime2.atZone(ZoneId.of("America/New_York")); //2014-11-02T02:30-05:00[America/New_York]
LocalDateTime standardTime3 = LocalDateTime.of(2014, 11, 2, 2, 0, 0, 0);
standardTime3.atZone(ZoneId.of("America/Phoenix")); //2014-11-02T02:00-07:00[America/Phoenix]
LocalDateTime standardTime4 = LocalDateTime.of(2014, 11, 2, 2, 59, 59, 999999999);
standardTime4.atZone(ZoneId.of("America/Chicago")); //2014-11-02T02:59:59.999999999-06:00[America/Chicago]
To model a span of time (e.g. 10 days) you have two choices
Duration
- a span of time in seconds and nanosecondsPeriod
-a span of time in years, months and daysTemporalAmount
Duration
LocalTime
(assumes no dates are involved)
static
method calls include construction for:
Duration
Duration
ExemplifiedDuration duration = Duration.ofDays(33); //seconds or nanos
Duration duration1 = Duration.ofHours(33); //seconds or nanos
Duration duration2 = Duration.ofMillis(33); //seconds or nanos
Duration duration3 = Duration.ofMinutes(33); //seconds or nanos
Duration duration4 = Duration.ofNanos(33); //seconds or nanos
Duration duration5 = Duration.ofSeconds(33); //seconds or nanos
Duration duration6 = Duration.between(LocalDate.of(2012, 11, 11), LocalDate.of(2013, 1, 1));
Period
LocalDate
(assumes no times are involved)
static
method calls include construction for:
Period
Period
ExemplifiedPeriod p = Period.ofDays(30);
Period p1 = Period.ofMonths(12);
Period p2 = Period.ofWeeks(11);
Period p3 = Period.ofYears(50);
Any class that derives from Temporal
has the ability to add or remove any time using methods:
plus
minus
Temporal
will provide a copy!LocalDate
A shift of LocalDate
can be done with:
TemporalAmount
(Period
)long
with TemporalUnit
(ChronoUnit
)LocalDate localDate = LocalDate.of(2012, 11, 23);
localDate.plus(3, ChronoUnit.DAYS); //2012-11-26
localDate.plus(Period.ofDays(3)); //2012-11-26
try {
localDate.plus(Duration.ofDays(3)); //2012-11-26
} catch (UnsupportedTemporalTypeException e) {
e.printStackTrace();
}
LocalTime
A shift of LocalTime
can be done with:
TemporalAmount
(Duration
)long
with TemporalUnit
(ChronoUnit
)LocalTime localTime = LocalTime.of(11, 20, 50);
localTime.plus(3, ChronoUnit.HOURS); //14:20:50
localTime.plus(Duration.ofDays(3)); //11:20:50
try {
localTime.plus(Period.ofDays(3));
} catch (UnsupportedTemporalTypeException e) {
e.printStackTrace();
}
interface
that can be implemented to specialize a time shift@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}
TemporalAdjuster fourMinutesFromNow = new TemporalAdjuster() {
@Override
public Temporal adjustInto(Temporal temporal) {
return temporal.plus(4, ChronoUnit.MINUTES);
}
};
LocalTime localTime = LocalTime.of(12, 0, 0);
localTime.with(fourMinutesFromNow)); //12:04
Remember this?
@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}
That’s a Java 8 Lambda! Therefore fourMinutesFromNow
can now be:
TemporalAdjuster fourMinutesFromNow = temporal -> temporal.plus(4, ChronoUnit.MINUTES);
LocalTime localTime = LocalTime.of(12, 0, 0);
localTime.with(fourMinutesFromNow)); //12:04
LocalTime.of(12, 0, 0).with(temporal -> temporal.plus(4, ChronoUnit.MINUTES));
String
is always importantjava.time.format.DateFormatter
LocalDate
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
dateFormatter.format(LocalDate.now()); // Jan. 19, 2014
LocalTime
DateTimeFormatter timeFormatter =
DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
timeFormatter.format(LocalTime.now())); //3:01:48 PM
LocalDateTime
DateTimeFormatter dateTimeFormatter =
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT);
dateTimeFormatter.format(LocalDateTime.now())); // Jan. 19, 2014 3:01 PM
DateTimeFormatter obscurePattern =
DateTimeFormatter.ofPattern("MMMM dd, yyyy '(In Time Zone: 'VV')'");
ZonedDateTime zonedNow = ZonedDateTime.now();
obscurePattern.format(zonedNow); //January 19, 2014 (In Time Zone: America/Denver)
Localization using java.util.Locale
is available for:
ofLocalizedDate
ofLocalizedTime
ofLocalizedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
DateTimeFormatter longDateTimeFormatter =
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL).withLocale(Locale.FRENCH);
longDateTimeFormatter.getLocale(); //fr
longDateTimeFormatter.format(zonedDateTime); //samedi 19 janvier 2014 00 h 00 CET
LocalDateTime localDateTime = LocalDateTime.of(1982, Month.APRIL, 17, 14, 11);
ZonedDateTime jakartaTime = ZonedDateTime.of(localDateTime, ZoneId.of("Asia/Jakarta"));
jakartaTime.withZoneSameInstant(ZoneId.of("America/Los_Angeles"))); //1982-04-16T23:11-08:00[America/Los_Angeles]
jakartaTime.withZoneSameLocal(ZoneId.of("America/New_York"))); //1982-04-17T14:11-05:00[America/New_York]
Process of asking information about a TemporalAccessor
LocalDate
LocalTime
LocalDateTime
ZonedDateTime
@FunctionalInterface
public interface TemporalQuery<R> {
R queryFrom(TemporalAccessor temporal);
}
TemporalQuery<Integer> daysBeforeChristmas = new TemporalQuery<Integer>() {
public int daysTilChristmas (int acc, Temporal temporal) {
int month = temporal.get(ChronoField.MONTH_OF_YEAR);
int day = temporal.get(ChronoField.DAY_OF_MONTH);
int max = Month.of(month).maxLength();
if (month == 12 && day <= 25) return acc + (25 - day);
return daysTilChristmas(acc + (max - day + 1),
temporal.with(TemporalAdjusters.firstDayOfNextMonth()));
}
@Override
public Integer queryFrom(TemporalAccessor temporal) {
if (!(temporal instanceof Temporal))
throw new RuntimeException("Temporal accessor must be of type Temporal");
return daysTilChristmas(0, (Temporal) temporal);
}
};
LocalDate.of(2013, 12, 26).query(daysBeforeChristmas); //364
LocalDate.of(2013, 12, 23).query(daysBeforeChristmas); //2
LocalDate.of(2013, 12, 25).query(daysBeforeChristmas); //0
ZonedDateTime.of(2013, 12, 1, 11, 0, 13, 938282,
ZoneId.of("America/Los_Angeles"))
.query(daysBeforeChristmas)); //24
format
but not parse
LOLWUT?
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
dateFormatter.parse("Jan 19, 2014")); // {}, ISO resolved to 2014-01-19
java.time.format.Parsed
which is rather uselessparse(CharSequence, TemporalQuery)
TemporalQuery<LocalDate> localDateTemporalQuery = new TemporalQuery<LocalDate>() {
@Override
public LocalDate queryFrom(TemporalAccessor temporal) {
return LocalDate.from(temporal);
}
};
dateFormatter.parse("Jan 19, 2014", localDateTemporalQuery); //2014-01-19
dateFormatter.parse("Jan 19, 2014", temporal -> LocalDate.from(temporal)); //2014-01-19
Given
@FunctionalInterface
public interface Predicate<T> {
public boolean test(T t);
}
And
static class IntPredicates {
public static boolean isOdd(Integer n) { return n % 2 != 0; }
public static boolean isEven(Integer n) { return n % 2 == 0; }
public static boolean isPositive(Integer n) { return n >= 0; }
}
Using the Predicate
Predicate<Integer> isOdd = n -> IntPredicates.isOdd(n);
Predicate<Integer> isEven = n -> IntPredicates.isEven(n);
We can always refer to those as:
Predicate<Integer> isOdd = IntPredicates::isOdd;
Predicate<Integer> isEven = IntPredicate::isEven;
Inside of LocalDate.java
public static LocalDate from(TemporalAccessor temporal) {
Objects.requireNonNull(temporal, "temporal");
LocalDate date = temporal.query(TemporalQueries.localDate());
if (date == null) {
throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName());
}
return date;
}
dateFormatter.parse("Jan 19, 2014", LocalDate::from); // Jan 19, 2014
calendar.toInstant()
- converts the Calendar object to an Instant.gregorianCalendar.toZonedDateTime()
- converts a GregorianCalendar instance to a ZonedDateTime.gregorianCalendar.from(ZonedDateTime)
- creates a GregorianCalendar object using the default locale from a ZonedDateTime instance.date.from(Instant)
- creates a Date object from an Instant.date.toInstant()
- converts a Date object to an Instant.timeZone.toZoneId()
- converts a TimeZone object to a ZoneId.GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.toZonedDateTime();
Multiple Clocks Provided
abstract
class therefore make your own!Clock clock = Clock.systemDefaultZone();
LocalDate localDate = LocalDate.now(clock);
Clock fixedClock = Clock.fixed(Instant.parse("2014-03-23T12:00:12Z"), ZoneId.of("America/Denver"));
LocalDate localDate = LocalDate.now(fixedClock);
(Perfect for Testing)
Clock offsetClock = Clock.offset(Clock.system(ZoneId.of("America/New_York")), Duration.ofMinutes(30));
LocalTime localTime = LocalTime.now(offsetClock); //Current Time plus 30 minutes
Clock tickClock = Clock.tick(Clock.system(ZoneId.of("America/New_York")), Duration.ofMinutes(30));
LocalTime localDate = LocalTime.now(tickClock); //Current time rounded to the nearest 30 minutes
LocalDate
, LocalTime
; Period
, and Duration