0% found this document useful (0 votes)
71 views130 pages

Formatting and Parsing Slides

The document discusses interconversions between date/time classes and other representations like strings and databases. It covers obtaining DateTimeFormatter instances through predefined formats, factory methods using format styles, and custom patterns. The DateTimeFormatterBuilder class allows flexible creation of formatters by setting properties and appending existing formatters.

Uploaded by

KIRAKRATOS
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
71 views130 pages

Formatting and Parsing Slides

The document discusses interconversions between date/time classes and other representations like strings and databases. It covers obtaining DateTimeFormatter instances through predefined formats, factory methods using format styles, and custom patterns. The DateTimeFormatterBuilder class allows flexible creation of formatters by setting properties and appending existing formatters.

Uploaded by

KIRAKRATOS
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 130

Interconversions and Testing

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

Date/Time classes expose methods:


String Interconversion

Date/Time classes expose methods:


• toString()
• parse(CharSequence)
String Interconversion

Date/Time classes expose methods:


• toString()
• parse(CharSequence)

– these delegate to DateTimeFormatter


methods:
String Interconversion

Date/Time classes expose methods:


• toString()
• parse(CharSequence)

– these delegate to DateTimeFormatter


methods:
• format(TemporalAccessor)
• parse(CharSequence)
String Interconversion

Date/Time classes expose methods:


• toString()
• parse(CharSequence)

– these delegate to DateTimeFormatter


methods:
• format(TemporalAccessor)
• parse(CharSequence)
• parse(CharSequence,

TemporalQuery<T>)
Obtaining DateTimeFormatter Instances
Obtaining DateTimeFormatter Instances

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 DateTimeFormatterBuilder


Using format patterns Most flexible way of creating
Obtaining DateTimeFormatter Instances

Factory Methods
Predefined Instances Using predefined date and time
styles

Factory Methods DateTimeFormatterBuilder


Using format patterns Most flexible way of creating
Predefined DateTimeFormatters
Predefined DateTimeFormatters

LocalDate

LocalTime
OffsetTime

LocalDateTime
OffsetDateTime
ZonedDateTime

Instant
Obtaining DateTimeFormatter Instances

Factory Methods
Predefined Instances Using predefined date and time
styles

Factory Methods DateTimeFormatterBuilder


Using format patterns Most flexible way of creating
Obtaining DateTimeFormatter Instances

Factory Methods
Predefined Instances Using predefined date and time
styles

Factory Methods DateTimeFormatterBuilder


Using format patterns Most flexible way of creating
DateTimeFormatter Factory Methods
DateTimeFormatter Factory Methods

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 DateTimeFormatterBuilder


Using format patterns Most flexible way of creating
Obtaining DateTimeFormatter Instances

Factory Methods
Predefined Instances Using predefined date and time
styles

Factory Methods DateTimeFormatterBuilder


Using format patterns Most flexible way of creating
Formatter Patterns
Formatter Patterns
Patterns define string formats
Formatter Patterns
Patterns define string formats
• e.g. the pattern for ISO_LOCAL_DATE is

"yyyy'-'MM'-'dd"
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
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"

A few other pattern symbols:


Symbol Meaning
K hour of am/pm
a am/pm of day
E day of week
Z zone offset
[ optional section start
] optional section end
er
es
Formatter Properties

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 DateTimeFormatterBuilder


Using format patterns Most flexible way of creating
Obtaining DateTimeFormatter Instances

Factory Methods
Predefined Instances Using predefined date and time
styles

Factory Methods DateTimeFormatterBuilder


Using format patterns Most flexible way of creating
DateTimeFormatter
Builder
• Implementation of the Builder Pattern
- Simplifies the construction of complex 

objects

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")


To create the equivalent DateTimeFormatterBuilder we would write


DateTimeFormatterBuilder
e.g. to parse LocalDates in this format: 

"2018 Aug 23"
we could use a formatter:
DateTimeFormatter.ofPattern("yyyy' 'MMM' 'dd")


To create the equivalent DateTimeFormatterBuilder we would write


DateTimeFormatterBuilder dtfBuilder = new DateTimeFormatterBuilder()

.appendValue(YEAR, 4)

.appendLiteral(" ")

.appendText(MONTH_OF_YEAR, SHORT)

.appendLiteral(" ")

.appendValue(DAY_OF_MONTH, 2);

DateTimeFormatter formatter = dtfBuilder.toFormatter();
DateTimeFormatterBuilder
e.g. to parse LocalDates in this format: 

"2018 Aug 23"
we could use a formatter:
DateTimeFormatter.ofPattern("yyyy' 'MMM' 'dd")


To create the equivalent DateTimeFormatterBuilder we would write


DateTimeFormatterBuilder dtfBuilder = new DateTimeFormatterBuilder()

.appendValue(YEAR, 4)

.appendLiteral(" ")

Other TextStyle options:
.appendText(MONTH_OF_YEAR, SHORT)

NARROW, FULL
.appendLiteral(" ")

.appendValue(DAY_OF_MONTH, 2);

DateTimeFormatter formatter = dtfBuilder.toFormatter();
TemporalAmount classes
TemporalAmount classes

The Class Period


TemporalAmount classes

The Class Period


toString() – ISO-8601 format
TemporalAmount classes

The Class Period


toString() – ISO-8601 format
parse(Period) – relaxed ISO-8601
TemporalAmount classes

The Class Period


toString() – ISO-8601 format
parse(Period) – relaxed ISO-8601

For more flexible formatting, can


use accessors
• getYears()
• getMonths()
• getDays()
TemporalAmount classes
TemporalAmount classes
The Class Duration
TemporalAmount classes
The Class Duration
toString() – fixed format
parse(String) – fixed format
TemporalAmount classes
The Class Duration
toString() – fixed format
parse(String) – fixed format

In Java 8, the only accessors are


• getSeconds()
• getNano()

TemporalAmount classes
The Class Duration
toString() – fixed format
parse(String) – fixed format

In Java 8, the only accessors are


• getSeconds()
• getNano()


Java 9 provides new methods:


• toNanosPart()
• toMillisPart()
• toSecondsPart()
• toMinutesPart()
• toHoursPart()
• toDaysPart()
Interconversions and Testing

Interconversions with Other


Representations
• Strings – Formatting and Parsing
• Other JDK Date/Time Classes
• Database Persistence
Unit Testing
Demo: Testing the Methods of the Task
Scheduler
Legacy Date/Time Classes
Legacy Date/Time Classes
Legacy Date/Time Classes

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

Interconversions with Other


Representations
• Strings – Formatting and Parsing
• Other JDK Date/Time Classes
• Database Persistence
Unit Testing
Demo: Testing the Methods of the Task
Scheduler
Persistence
Without JPA
Support
Persistence
Without JPA
Support
Persistence
Without JPA
Support
Persistence
Without JPA
Persisting
Support
Persistence
Without JPA
Persisting
Support
Persistence
Without JPA
Persisting
Support

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());

}

}

Three conversion libraries:


https://github.com/perceptron8/datetime-jpa
https://github.com/marschall/threeten-jpa
https://bitbucket.org/montanajava/jpaattributeconverters
With JPA Support
With JPA Support

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+)

Hibernate also supports


persistence of Duration,
Instant, and ZonedDateTime
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
java.time.Duration BIGINT
– Hibernate (v5.3+)
java.time.Instant TIMESTAMP
java.time.ZonedDateTime TIMESTAMP

Hibernate also supports


persistence of Duration,
Instant, and ZonedDateTime
Interconversions and Testing

Interconversions with Other


Representations
• Strings – Formatting and Parsing
• Other JDK Date/Time Classes
• Database Persistence
Unit Testing
Demo: Testing the Methods of the Task
Scheduler
Methods of
the Class Clock
Factory Methods

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)

the Class Clock


Factory Methods
systemDefaultZone()

systemUTC()

system(ZoneId)
tickSeconds(ZoneId)

Methods of tickMinutes(ZoneId)
fixed(Instant, ZoneId)
the Class Clock
Factory Methods
systemDefaultZone()

systemUTC()

system(ZoneId)
tickSeconds(ZoneId)

Methods of tickMinutes(ZoneId)
fixed(Instant, ZoneId)
the Class Clock
Accessors
Factory Methods
systemDefaultZone()

systemUTC()

system(ZoneId)
tickSeconds(ZoneId)

Methods of tickMinutes(ZoneId)
fixed(Instant, ZoneId)
the Class Clock
Accessors
instant()
Factory Methods
systemDefaultZone()

systemUTC()

system(ZoneId)
tickSeconds(ZoneId)

Methods of tickMinutes(ZoneId)
fixed(Instant, ZoneId)
the Class Clock
Accessors
instant()
millis()
Factory Methods
systemDefaultZone()

systemUTC()

system(ZoneId)
tickSeconds(ZoneId)

Methods of tickMinutes(ZoneId)
fixed(Instant, ZoneId)
the Class Clock
Accessors
instant()
millis()
getZone()
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 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());
}

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());
}

Using a Mocking Framework to


Simulate Changed Time in a Method
private Instant currentTime;

private Clock clock = Mockito.mock(Clock.class);

 @Before

 public void setup() {

 currentTime = Instant.EPOCH; // or other initialisation

 when(clock.instant()).thenAnswer(invocation -> currentTime);

 }
@Test
public void myTest() {
testObject.methodThatAcceptsAnInstant(clock.instant());
currentTime = currentTime.plus(1, ChronoUnit.DAYS); // simulate passage of time
testObject.methodThatAcceptsAnInstant(clock.instant());
}

Using a Mocking Framework to


Simulate Changed Time in a Method
Interconversions and Testing

Interconversions with Other


Representations
• Strings – Formatting and Parsing
• Other JDK Date/Time Classes
• Database Persistence
Unit Testing
Demo: Testing the Methods of the Task
Scheduler
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

You might also like