diff --git a/util/src/main/java/google/registry/util/DateTimeUtils.java b/util/src/main/java/google/registry/util/DateTimeUtils.java index 0aa0fa617..362e8118e 100644 --- a/util/src/main/java/google/registry/util/DateTimeUtils.java +++ b/util/src/main/java/google/registry/util/DateTimeUtils.java @@ -19,6 +19,9 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.TimeZone; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; @@ -86,4 +89,23 @@ public class DateTimeUtils { checkArgument(years >= 0); return years == 0 ? now : now.minusYears(1).minusYears(years - 1); } + + /** + * Converts a Joda {@link DateTime} object to an equivalent java.time {@link ZonedDateTime} + * object. + */ + public static ZonedDateTime toZonedDateTime(DateTime dateTime) { + java.time.Instant instant = java.time.Instant.ofEpochMilli(dateTime.getMillis()); + return ZonedDateTime.ofInstant(instant, ZoneId.of(dateTime.getZone().getID()).normalized()); + } + + /** + * Converts a java.time {@link ZonedDateTime} object to an equivalent Joda {@link DateTime} + * object. + */ + public static DateTime toJodaDateTime(ZonedDateTime zonedDateTime) { + return new DateTime( + zonedDateTime.toInstant().toEpochMilli(), + DateTimeZone.forTimeZone(TimeZone.getTimeZone(zonedDateTime.getZone()))); + } } diff --git a/util/src/test/java/google/registry/util/DateTimeUtilsTest.java b/util/src/test/java/google/registry/util/DateTimeUtilsTest.java index f4e41da7d..481296a8d 100644 --- a/util/src/test/java/google/registry/util/DateTimeUtilsTest.java +++ b/util/src/test/java/google/registry/util/DateTimeUtilsTest.java @@ -24,8 +24,11 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt; import static google.registry.util.DateTimeUtils.latestOf; import static google.registry.util.DateTimeUtils.leapSafeAddYears; import static google.registry.util.DateTimeUtils.leapSafeSubtractYears; +import static google.registry.util.DateTimeUtils.toJodaDateTime; +import static google.registry.util.DateTimeUtils.toZonedDateTime; import com.google.common.collect.ImmutableList; +import java.time.ZonedDateTime; import org.joda.time.DateTime; import org.junit.Test; import org.junit.runner.RunWith; @@ -94,4 +97,46 @@ public class DateTimeUtilsTest { public void testFailure_latestOfEmpty() { assertThrows(IllegalArgumentException.class, () -> earliestOf(ImmutableList.of())); } + + @Test + public void testSuccess_toZonedDateTime_preservesTimeZone() { + DateTime dateTime = DateTime.parse("2019-09-06T10:59:36.283-07:00"); // PDT + ZonedDateTime zonedDateTime = toZonedDateTime(dateTime); + assertThat(zonedDateTime.toString()).isEqualTo("2019-09-06T10:59:36.283-07:00"); // still PDT + } + + @Test + public void testSuccess_toZonedDateTime_fromStringZulu() { + DateTime dateTime = DateTime.parse("2015-10-13T11:22:33.168Z"); + ZonedDateTime zonedDateTime = toZonedDateTime(dateTime); + assertThat(zonedDateTime.toString()).isEqualTo("2015-10-13T11:22:33.168Z"); + } + + @Test + public void testSuccess_toZonedDateTime_leapYear() { + DateTime dateTime = DateTime.parse("2016-02-29T11:22:33.168Z"); + ZonedDateTime zonedDateTime = toZonedDateTime(dateTime); + assertThat(zonedDateTime.toString()).isEqualTo("2016-02-29T11:22:33.168Z"); + } + + @Test + public void testSuccess_toJodaDateTime_preservesTimeZone() { + ZonedDateTime zonedDateTime = ZonedDateTime.parse("2019-09-06T10:59:36.283-07:00"); // PDT + DateTime dateTime = toJodaDateTime(zonedDateTime); + assertThat(dateTime.toString()).isEqualTo("2019-09-06T10:59:36.283-07:00"); // still PDT + } + + @Test + public void testSuccess_toJodaDateTime_fromStringZulu() { + ZonedDateTime zonedDateTime = ZonedDateTime.parse("2015-10-13T11:22:33.168Z"); + DateTime dateTime = toJodaDateTime(zonedDateTime); + assertThat(dateTime.toString()).isEqualTo("2015-10-13T11:22:33.168Z"); + } + + @Test + public void testSuccess_toJodaDateTime_leapYear() { + ZonedDateTime zonedDateTime = ZonedDateTime.parse("2016-02-29T11:22:33.168Z"); + DateTime dateTime = toJodaDateTime(zonedDateTime); + assertThat(dateTime.toString()).isEqualTo("2016-02-29T11:22:33.168Z"); + } }