Skip to content

Commit

Permalink
Use Instant internally
Browse files Browse the repository at this point in the history
Signed-off-by: Jacob Laursen <[email protected]>
  • Loading branch information
jlaur committed Apr 29, 2023
1 parent ac0f512 commit ab14428
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
Expand All @@ -37,6 +36,7 @@
* @author Wouter Born - increase parsing and formatting precision
* @author Laurent Garnier - added methods toLocaleZone and toZone
* @author Gaël L'hopital - added ability to use second and milliseconds unix time
* @author Jacob Laursen - Refactored to use {@link Instant} internally
*/
@NonNullByDefault
public class DateTimeType implements PrimitiveType, State, Command {
Expand Down Expand Up @@ -66,57 +66,56 @@ public class DateTimeType implements PrimitiveType, State, Command {
private static final DateTimeFormatter FORMATTER_TZ_RFC = DateTimeFormatter
.ofPattern(DATE_FORMAT_PATTERN_WITH_TZ_RFC);

private ZonedDateTime zonedDateTime;
private Instant instant;

public DateTimeType() {
this(ZonedDateTime.now());
this(Instant.now());
}

public DateTimeType(Instant instant) {
this.instant = instant;
}

public DateTimeType(ZonedDateTime zoned) {
this.zonedDateTime = ZonedDateTime.from(zoned).withFixedOffsetZone();
instant = zoned.toInstant();
}

public DateTimeType(String zonedValue) {
ZonedDateTime date = null;
try {
// direct parsing (date and time)
try {
date = parse(zonedValue);
instant = parse(zonedValue);
} catch (DateTimeParseException fullDtException) {
// time only
try {
date = parse("1970-01-01T" + zonedValue);
instant = parse("1970-01-01T" + zonedValue);
} catch (DateTimeParseException timeOnlyException) {
try {
long epoch = Double.valueOf(zonedValue).longValue();
int length = (int) (Math.log10(epoch >= 0 ? epoch : epoch * -1) + 1);
Instant i;
// Assume that below 12 digits we're in seconds
if (length < 12) {
i = Instant.ofEpochSecond(epoch);
instant = Instant.ofEpochSecond(epoch);
} else {
i = Instant.ofEpochMilli(epoch);
instant = Instant.ofEpochMilli(epoch);
}
date = ZonedDateTime.ofInstant(i, ZoneOffset.UTC);
} catch (NumberFormatException notANumberException) {
// date only
if (zonedValue.length() == 10) {
date = parse(zonedValue + "T00:00:00");
instant = parse(zonedValue + "T00:00:00");
} else {
date = parse(zonedValue.substring(0, 10) + "T00:00:00" + zonedValue.substring(10));
instant = parse(zonedValue.substring(0, 10) + "T00:00:00" + zonedValue.substring(10));
}
}
}
}
} catch (DateTimeParseException invalidFormatException) {
throw new IllegalArgumentException(zonedValue + " is not in a valid format.", invalidFormatException);
}

zonedDateTime = date.withFixedOffsetZone();
}

public ZonedDateTime getZonedDateTime() {
return zonedDateTime;
return instant.atZone(ZoneId.systemDefault());
}

/**
Expand All @@ -125,7 +124,7 @@ public ZonedDateTime getZonedDateTime() {
* @return an {@link Instant} representation of the current object
*/
public Instant getInstant() {
return zonedDateTime.toInstant();
return instant;
}

public static DateTimeType valueOf(String value) {
Expand All @@ -135,49 +134,55 @@ public static DateTimeType valueOf(String value) {
@Override
public String format(@Nullable String pattern) {
if (pattern == null) {
return DateTimeFormatter.ofPattern(DATE_PATTERN).format(zonedDateTime);
return DateTimeFormatter.ofPattern(DATE_PATTERN).format(instant.atZone(ZoneId.systemDefault()));
}

return String.format(pattern, zonedDateTime);
return String.format(pattern, instant.atZone(ZoneId.systemDefault()));
}

public String format(Locale locale, String pattern) {
return String.format(locale, pattern, zonedDateTime);
return String.format(locale, pattern, instant.atZone(ZoneId.systemDefault()));
}

/**
* Create a {@link DateTimeType} being the translation of the current object to the locale time zone
* @deprecated
* Create a {@link DateTimeType} being the translation of the current object to the locale time zone
*
* @return a {@link DateTimeType} translated to the locale time zone
* @throws DateTimeException if the converted zone ID has an invalid format or the result exceeds the supported date
* range
* @throws ZoneRulesException if the converted zone region ID cannot be found
*/
@Deprecated
public DateTimeType toLocaleZone() throws DateTimeException, ZoneRulesException {
return toZone(ZoneId.systemDefault());
return new DateTimeType(instant);
}

/**
* Create a {@link DateTimeType} being the translation of the current object to a given zone
* @deprecated
* Create a {@link DateTimeType} being the translation of the current object to a given zone
*
* @param zone the target zone as a string
* @return a {@link DateTimeType} translated to the given zone
* @throws DateTimeException if the zone has an invalid format or the result exceeds the supported date range
* @throws ZoneRulesException if the zone is a region ID that cannot be found
*/
@Deprecated
public DateTimeType toZone(String zone) throws DateTimeException, ZoneRulesException {
return toZone(ZoneId.of(zone));
return new DateTimeType(instant);
}

/**
* Create a {@link DateTimeType} being the translation of the current object to a given zone
* @deprecated
* Create a {@link DateTimeType} being the translation of the current object to a given zone
*
* @param zoneId the target {@link ZoneId}
* @return a {@link DateTimeType} translated to the given zone
* @throws DateTimeException if the result exceeds the supported date range
*/
@Deprecated
public DateTimeType toZone(ZoneId zoneId) throws DateTimeException {
return new DateTimeType(zonedDateTime.withZoneSameInstant(zoneId));
return new DateTimeType(instant);
}

@Override
Expand All @@ -187,7 +192,7 @@ public String toString() {

@Override
public String toFullString() {
String formatted = zonedDateTime.format(FORMATTER_TZ_RFC);
String formatted = instant.atZone(ZoneId.systemDefault()).format(FORMATTER_TZ_RFC);
if (formatted.contains(".")) {
String sign = "";
if (formatted.contains("+")) {
Expand All @@ -208,7 +213,7 @@ public String toFullString() {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getZonedDateTime().hashCode();
result = prime * result + instant.hashCode();
return result;
}

Expand All @@ -224,10 +229,10 @@ public boolean equals(@Nullable Object obj) {
return false;
}
DateTimeType other = (DateTimeType) obj;
return zonedDateTime.compareTo(other.zonedDateTime) == 0;
return instant.compareTo(other.instant) == 0;
}

private ZonedDateTime parse(String value) throws DateTimeParseException {
private Instant parse(String value) throws DateTimeParseException {
ZonedDateTime date = null;
try {
date = ZonedDateTime.parse(value, PARSER_TZ_RFC);
Expand All @@ -244,6 +249,6 @@ private ZonedDateTime parse(String value) throws DateTimeParseException {
}
}

return date;
return date.toInstant();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,35 +181,35 @@ public static Collection<Object[]> parameters() {
{ new ParameterSet(TimeZone.getTimeZone("UTC"), initTimeMap(), TimeZone.getTimeZone("UTC"),
"2014-03-30T10:58:47.033+0000", "2014-03-30T10:58:47.033+0000") },
{ new ParameterSet(TimeZone.getTimeZone("UTC"), initTimeMap(), TimeZone.getTimeZone("CET"),
"2014-03-30T10:58:47.033+0200", "2014-03-30T08:58:47.033+0000") },
"2014-03-30T08:58:47.033+0000", "2014-03-30T08:58:47.033+0000") },
{ new ParameterSet(TimeZone.getTimeZone("UTC"), "2014-03-30T10:58:47.23",
"2014-03-30T10:58:47.230+0000", "2014-03-30T10:58:47.230+0000") },
{ new ParameterSet(TimeZone.getTimeZone("UTC"), "2014-03-30T10:58:47UTC",
"2014-03-30T10:58:47.000+0000", "2014-03-30T10:58:47.000+0000") },
{ new ParameterSet(TimeZone.getTimeZone("CET"), initTimeMap(), TimeZone.getTimeZone("UTC"),
"2014-03-30T10:58:47.033+0000", "2014-03-30T12:58:47.033+0200") },
"2014-03-30T12:58:47.033+0200", "2014-03-30T12:58:47.033+0200") },
{ new ParameterSet(TimeZone.getTimeZone("CET"), initTimeMap(), TimeZone.getTimeZone("CET"),
"2014-03-30T10:58:47.033+0200", "2014-03-30T10:58:47.033+0200") },
{ new ParameterSet(TimeZone.getTimeZone("CET"), "2014-03-30T10:58:47CET",
"2014-03-30T10:58:47.000+0200", "2014-03-30T10:58:47.000+0200") },
{ new ParameterSet(TimeZone.getTimeZone("GMT+5"), "2014-03-30T10:58:47.000Z",
"2014-03-30T10:58:47.000+0000", "2014-03-30T15:58:47.000+0500") },
"2014-03-30T15:58:47.000+0500", "2014-03-30T15:58:47.000+0500") },
{ new ParameterSet(TimeZone.getTimeZone("GMT+2"), null, null, "2014-03-30T10:58:47",
"2014-03-30T10:58:47.000+0200", "2014-03-30T10:58:47.000+0200", null,
"%1$td.%1$tm.%1$tY %1$tH:%1$tM", "30.03.2014 10:58") },
{ new ParameterSet(TimeZone.getTimeZone("GMT"), initTimeMap(), TimeZone.getTimeZone("GMT"),
"2014-03-30T10:58:47.033+0000", "2014-03-30T10:58:47.033+0000") },
// Parameter set with an invalid time zone id as input, leading to GMT being considered
{ new ParameterSet(TimeZone.getTimeZone("CET"), initTimeMap(), TimeZone.getTimeZone("+02:00"),
"2014-03-30T10:58:47.033+0000", "2014-03-30T12:58:47.033+0200") },
"2014-03-30T12:58:47.033+0200", "2014-03-30T12:58:47.033+0200") },
// Parameter set with an invalid time zone id as input, leading to GMT being considered
{ new ParameterSet(TimeZone.getTimeZone("GMT+2"), initTimeMap(), TimeZone.getTimeZone("GML"),
"2014-03-30T10:58:47.033+0000", "2014-03-30T12:58:47.033+0200") },
"2014-03-30T12:58:47.033+0200", "2014-03-30T12:58:47.033+0200") },
{ new ParameterSet(TimeZone.getTimeZone("GMT-2"), initTimeMap(), TimeZone.getTimeZone("GMT+3"), null,
"2014-03-30T10:58:47.033+0300", "2014-03-30T05:58:47.033-0200", Locale.GERMAN,
"%1$tA %1$td.%1$tm.%1$tY %1$tH:%1$tM", "Sonntag 30.03.2014 10:58") },
"2014-03-30T05:58:47.033-0200", "2014-03-30T05:58:47.033-0200", Locale.GERMAN,
"%1$tA %1$td.%1$tm.%1$tY %1$tH:%1$tM", "Sonntag 30.03.2014 05:58") },
{ new ParameterSet(TimeZone.getTimeZone("GMT-2"), initTimeMap(), TimeZone.getTimeZone("GMT-4"),
"2014-03-30T10:58:47.033-0400", "2014-03-30T12:58:47.033-0200") },
"2014-03-30T12:58:47.033-0200", "2014-03-30T12:58:47.033-0200") },
{ new ParameterSet(TimeZone.getTimeZone("UTC"), "10:58:47", "1970-01-01T10:58:47.000+0000",
"1970-01-01T10:58:47.000+0000") },
{ new ParameterSet(TimeZone.getTimeZone("UTC"), "10:58", "1970-01-01T10:58:00.000+0000",
Expand Down Expand Up @@ -265,16 +265,21 @@ public void zonedParsingTest() {

@Test
public void instantParsingTest() {
DateTimeType dt1 = new DateTimeType("2019-06-12T17:30:00Z");
DateTimeType dt2 = new DateTimeType("2019-06-12T17:30:00+0000");
DateTimeType dt3 = new DateTimeType("2019-06-12T19:30:00+0200");
DateTimeType dt1 = new DateTimeType(Instant.parse("2019-06-12T17:30:00Z"));
DateTimeType dt2 = new DateTimeType("2019-06-12T17:30:00Z");
DateTimeType dt3 = new DateTimeType("2019-06-12T17:30:00+0000");
DateTimeType dt4 = new DateTimeType("2019-06-12T19:30:00+0200");
assertThat(dt1, is(dt2));
assertThat(dt2, is(dt3));
assertThat(dt3, is(dt4));

Instant i1 = dt1.getInstant();
Instant i2 = dt2.getInstant();
Instant i3 = dt3.getInstant();
Instant i4 = dt4.getInstant();
assertThat(i1, is(i2));
assertThat(i1, is(i3));
assertThat(i2, is(i3));
assertThat(i3, is(i4));
}

@Test
Expand Down

0 comments on commit ab14428

Please sign in to comment.