Formatting and Parsing Slides
Formatting and Parsing Slides
Maurice Naftalin
@mauricenaftalin
Summary
Summary
Interconversions with Other
Representations
Summary
Interconversions with Other
Representations
Summary • Strings – Formatting and Parsing
Interconversions with Other
Representations
Summary • Strings – Formatting and Parsing
• Other JDK Date/Time Classes
Interconversions with Other
Representations
Summary • Strings – Formatting and Parsing
• Other JDK Date/Time Classes
• Database Persistence
Interconversions with Other
Representations
Summary • Strings – Formatting and Parsing
• Other JDK Date/Time Classes
• Database Persistence
Unit Testing
String Interconversion
String Interconversion
Predefined Instances
Obtaining DateTimeFormatter Instances
Factory Methods
Predefined Instances Using predefined date and time
styles
Obtaining DateTimeFormatter Instances
Factory Methods
Predefined Instances Using predefined date and time
styles
Factory Methods
Using format patterns
Obtaining DateTimeFormatter Instances
Factory Methods
Predefined Instances Using predefined date and time
styles
Factory Methods
Predefined Instances Using predefined date and time
styles
LocalDate
LocalTime
OffsetTime
LocalDateTime
OffsetDateTime
ZonedDateTime
Instant
Obtaining DateTimeFormatter Instances
Factory Methods
Predefined Instances Using predefined date and time
styles
Factory Methods
Predefined Instances Using predefined date and time
styles
Arguments of type :
java.time.format.FormatStyle
The enum FormatStyle
The enum FormatStyle
FormatStyle members:
• FULL
• LONG
• MEDIUM
• SHORT
Obtaining DateTimeFormatter Instances
Factory Methods
Predefined Instances Using predefined date and time
styles
Factory Methods
Predefined Instances Using predefined date and time
styles
Year, output in a
field at least four
characters wide
Formatter Patterns
Patterns define string formats
• e.g. the pattern for ISO_LOCAL_DATE is
"yyyy'-'MM'-'dd"
Year, output in a
field at least four Literal "-"
characters wide
Formatter Patterns
Patterns define string formats
• e.g. the pattern for ISO_LOCAL_DATE is
"yyyy'-'MM'-'dd"
Year, output in a
field at least four
characters wide
Month, output in a
field exactly two
characters wide
Formatter Patterns
Patterns define string formats
• e.g. the pattern for ISO_LOCAL_DATE is
"yyyy'-'MM'-'dd"
Year, output in a
Day, output in a
field at least four
field exactly two
characters wide
characters wide
Month, output in a
field exactly two
characters wide
Formatter Patterns
Patterns define string formats
• e.g. the pattern for ISO_LOCAL_DATE is
"yyyy'-'MM'-'dd"
er
es
Formatter Properties
Properties of
java.time.format.DateTimeFormatter
er
es
Formatter Properties
Properties of
java.time.format.DateTimeFormatter
•Zone
- Used when a zone is required
but not supplied by the parse
string or date-time value
er
es
Formatter Properties
Properties of
java.time.format.DateTimeFormatter
•Zone
- Used when a zone is required
but not supplied by the parse
string or date-time value
er•Locale
es - Used for localization
Formatter Properties
Properties of
java.time.format.DateTimeFormatter
•Zone
- Used when a zone is required
but not supplied by the parse
string or date-time value
er•Locale
es - Used for localization
•ResolverStyle
- STRICT, LENIENT, or SMART
Obtaining DateTimeFormatter Instances
Factory Methods
Predefined Instances Using predefined date and time
styles
Factory Methods
Predefined Instances Using predefined date and time
styles
DateTimeFormatter
Builder
• Implementation of the Builder Pattern
- Simplifies the construction of complex
objects
• Can set properties:
- zone
DateTimeFormatter - locale
Builder - resolver style
• Implementation of the Builder Pattern
- Simplifies the construction of complex
objects
• Can set properties:
- zone
DateTimeFormatter - locale
Builder - resolver style
• Can append existing DateTimeFormatters
• Implementation of the Builder Pattern
- Simplifies the construction of complex
objects
• Can set properties:
- zone
DateTimeFormatter - locale
Builder - resolver style
• Can append existing DateTimeFormatters
• Once building is complete, calling
toFormatter() creates a
DateTimeFormatter
DateTimeFormatterBuilder
DateTimeFormatterBuilder
e.g. to parse LocalDates in this format:
"2018 Aug 23"
DateTimeFormatterBuilder
e.g. to parse LocalDates in this format:
"2018 Aug 23"
we could use a formatter:
DateTimeFormatter.ofPattern("yyyy' 'MMM' 'dd")
DateTimeFormatterBuilder
e.g. to parse LocalDates in this format:
"2018 Aug 23"
we could use a formatter:
DateTimeFormatter.ofPattern("yyyy' 'MMM' 'dd")
java.time
Legacy Type Conversion Methods
Equivalent
Legacy Date/Time Classes
java.time
Legacy Type Conversion Methods
Equivalent
java.util.Date Instant toInstant() from(Instant)
Legacy Date/Time Classes
java.time
Legacy Type Conversion Methods
Equivalent
java.util.Date Instant toInstant() from(Instant)
java.util.GregorianCalendar ZonedDateTime toInstant() from(ZonedDateTime)
toZonedDateTime()
Legacy Date/Time Classes
java.time
Legacy Type Conversion Methods
Equivalent
java.util.Date Instant toInstant() from(Instant)
java.util.GregorianCalendar ZonedDateTime toInstant() from(ZonedDateTime)
toZonedDateTime()
java.util.TimeZone ZoneId toZoneId() getTimeZone(ZoneId)
Legacy Date/Time Classes
java.time
Legacy Type Conversion Methods
Equivalent
java.util.Date Instant toInstant() from(Instant)
java.util.GregorianCalendar ZonedDateTime toInstant() from(ZonedDateTime)
toZonedDateTime()
java.util.TimeZone ZoneId toZoneId() getTimeZone(ZoneId)
java.sql.Date LocalDate toLocalDate() valueOf(LocalDate)
Legacy Date/Time Classes
java.time
Legacy Type Conversion Methods
Equivalent
java.util.Date Instant toInstant() from(Instant)
java.util.GregorianCalendar ZonedDateTime toInstant() from(ZonedDateTime)
toZonedDateTime()
java.util.TimeZone ZoneId toZoneId() getTimeZone(ZoneId)
java.sql.Date LocalDate toLocalDate() valueOf(LocalDate)
java.sql.Time LocalTime toLocalTime() valueOf(LocalTime)
Legacy Date/Time Classes
java.time
Legacy Type Conversion Methods
Equivalent
java.util.Date Instant toInstant() from(Instant)
java.util.GregorianCalendar ZonedDateTime toInstant() from(ZonedDateTime)
toZonedDateTime()
java.util.TimeZone ZoneId toZoneId() getTimeZone(ZoneId)
java.sql.Date LocalDate toLocalDate() valueOf(LocalDate)
java.sql.Time LocalTime toLocalTime() valueOf(LocalTime)
java.sql.Timestamp Instant toInstant() from(Instant)
toLocalDateTime()
Legacy Date/Time Classes
java.time
Legacy Type Conversion Methods
Equivalent
java.util.Date Instant toInstant() from(Instant)
java.util.GregorianCalendar ZonedDateTime toInstant() from(ZonedDateTime)
toZonedDateTime()
java.util.TimeZone ZoneId toZoneId() getTimeZone(ZoneId)
java.sql.Date LocalDate toLocalDate() valueOf(LocalDate)
java.sql.Time LocalTime toLocalTime() valueOf(LocalTime)
java.sql.Timestamp Instant toInstant() from(Instant)
toLocalDateTime()
java.nio.file.attribute.FileTime Instant toInstant() from(Instant)
Interconversions and Testing
convertToDatabaseColumn(LocalDate)
Persistence
Without JPA
Retrieving
Support
Persistence
Without JPA
Retrieving
Support
Persistence
Without JPA
Retrieving
Support
convertToEntityAttribute(Date)
interface AttributeConverter<X,Y> {
Y convertToDatabaseColumn(X)
X convertToEntityAttribute(Y)
}
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
interface AttributeConverter<X,Y> {
Y convertToDatabaseColumn(X)
X convertToEntityAttribute(Y)
}
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate localDate) {
return (localDate == null ? null : Date.valueOf(localDate));
}
interface AttributeConverter<X,Y> {
Y convertToDatabaseColumn(X)
X convertToEntityAttribute(Y)
}
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate localDate) {
return (localDate == null ? null : Date.valueOf(localDate));
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
interface AttributeConverter<X,Y> {
Y convertToDatabaseColumn(X)
X convertToEntityAttribute(Y)
}
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate localDate) {
return (localDate == null ? null : Date.valueOf(localDate));
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
interface AttributeConverter<X,Y> {
Y convertToDatabaseColumn(X)
X convertToEntityAttribute(Y)
}
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate localDate) {
return (localDate == null ? null : Date.valueOf(localDate));
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
JPA 2.2
With JPA Support
JPA 2.2
Supported by
– DataNucleus
– EclipseLink (v2.7+)
– Hibernate (v5.3+)
With JPA Support
JPA 2.2
JAVA TYPE JDBC TYPE
java.time.LocalDate DATE
Supported by java.time.LocalTime TIME
java.time.LocalDateTime TIMESTAMP
– DataNucleus java.time.OffsetTime TIME_WITH_TIMEZONE
– EclipseLink (v2.7+) java.time.OffsetDateTime TIMESTAMP_WITH_TIMEZONE
– Hibernate (v5.3+)
With JPA Support
JPA 2.2
JAVA TYPE JDBC TYPE
java.time.LocalDate DATE
Supported by java.time.LocalTime TIME
java.time.LocalDateTime TIMESTAMP
– DataNucleus java.time.OffsetTime TIME_WITH_TIMEZONE
– EclipseLink (v2.7+) java.time.OffsetDateTime TIMESTAMP_WITH_TIMEZONE
– Hibernate (v5.3+)
JPA 2.2
JAVA TYPE JDBC TYPE
java.time.LocalDate DATE
Supported by java.time.LocalTime TIME
java.time.LocalDateTime TIMESTAMP
– DataNucleus java.time.OffsetTime TIME_WITH_TIMEZONE
– EclipseLink (v2.7+) java.time.OffsetDateTime TIMESTAMP_WITH_TIMEZONE
java.time.Duration BIGINT
– Hibernate (v5.3+)
java.time.Instant TIMESTAMP
java.time.ZonedDateTime TIMESTAMP
Methods of
the Class Clock
Factory Methods
systemDefaultZone()
systemUTC()
system(ZoneId)
Methods of
the Class Clock
Factory Methods
systemDefaultZone()
systemUTC()
system(ZoneId)
tickSeconds(ZoneId)
Methods of tickMinutes(ZoneId)
Testing without
a Clock
private Calendar cal;
private ZonedDateTime start;
@Before
public void setup() {
cal = new Calendar();
start = ZonedDateTime.now()
}
@Test
public void testNoWorkPeriods() {
cal.addEvent(Event.of(start, start.plusHours(1),""));
NavigableSet<WorkPeriod> combined = cal.overwritePeriodsByEvents(ZoneId.systemDefault());
assertTrue(combined.isEmpty());
}
Testing without
a Clock
private Clock clock;
private Calendar cal;
private ZonedDateTime start;
@Before
public void setup() {
cal = new Calendar();
clock = Clock.fixed(Instant.EPOCH, ZoneOffset.UTC);
start = ZonedDateTime.now(clock);
}
@Test
public void testNoWorkPeriods() {
cal.addEvent(Event.of(start, start.plusHours(1),""));
NavigableSet<WorkPeriod> combined = cal.overwritePeriodsByEvents(clock.getZone());
assertTrue(combined.isEmpty());
}
Testing with
a Clock
Using a Mocking Framework to
Simulate Changed Time in a Method
private Instant currentTime;
@Test
public void myTest() {
testObject.methodThatAcceptsAnInstant(clock.instant());
currentTime = currentTime.plus(1, ChronoUnit.DAYS); // simulate passage of time
testObject.methodThatAcceptsAnInstant(clock.instant());
}
@Test
public void myTest() {
testObject.methodThatAcceptsAnInstant(clock.instant());
currentTime = currentTime.plus(1, ChronoUnit.DAYS); // simulate passage of time
testObject.methodThatAcceptsAnInstant(clock.instant());
}