1
0
mirror of https://github.com/google/nomulus synced 2026-06-03 13:36:41 +00:00

Migrate core temporal models and related entities to java.time.Instant (#3001)

This comprehensive refactor continues the migration from Joda-Time to java.time (Instant), focusing on core timestamp models, transition properties, and their integration across the codebase.

Key changes:
- Migrated CreateAutoTimestamp and UpdateAutoTimestamp to use Instant internally, providing Joda-Time bridge methods for backward compatibility.
- Updated TimedTransitionProperty to handle Instant-based transition maps and updated corresponding Hibernate UserTypes (TimedTransitionBaseUserType).
- Migrated GracePeriod, BillingBase, BillingEvent, PollMessage, and PendingActionNotificationResponse fields (e.g., expirationTime, eventTime) to Instant.
- Migrated additional core entities (DomainBase, Registrar, HostBase, LaunchNotice, BsaLabel, DomainTransactionRecord) to use Instant for registrationExpirationTime, lastTransferTime, creationTime, etc.
- Updated Tld and FeatureFlag models to use Instant for claimsPeriodEnd, bsaEnrollStartTime, and status transitions.
- Enhanced CLI tools and parameters (TransitionListParameter, InstantParameter, RequestParameters) to support Instant-based input and output.
- Updated EntityYamlUtils with custom Instant serializers/deserializers to maintain format consistency (e.g., .SSSZ precision) required for YAML-based tests.
- Implemented UtcInstantAdapter to ensure JAXB XML serialization maintains millisecond accuracy, matching legacy Joda-Time behavior.
- Resolved Hibernate 6 type mismatches in JPQL and Native queries by ensuring consistent use of Instant for comparisons.
- Updated GEMINI.md with project-specific engineering standards, including the 'one commit per PR' mandate, full-build validation requirement, and commit message style rules.
- Cleaned up unnecessary @JsonIgnore and @JsonProperty annotations that were previously added to methods with parameters or redundant fields.
- Refactored DateTimeUtils to use strongly-typed overloads and standardized naming (earliestOf, latestOf) while avoiding type erasure clashes.
- Cleaned up fully qualified calls to toDateTime and toInstant by adding static imports across core model and flow files.
- Refactored test suites to use clock.now() (Instant) instead of nowUtc() (DateTime) and removed custom Truth subjects in favor of standard assertions.
This commit is contained in:
Ben McIlwain
2026-04-20 10:03:20 -04:00
committed by GitHub
parent db733aa50f
commit c427f2cc9f
169 changed files with 3512 additions and 1211 deletions

View File

@@ -23,8 +23,8 @@ import static google.registry.util.DateTimeUtils.earliestOf;
import static google.registry.util.DateTimeUtils.isAtOrAfter;
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.minusYears;
import static google.registry.util.DateTimeUtils.plusYears;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.DateTimeUtils.toLocalDate;
@@ -50,10 +50,22 @@ class DateTimeUtilsTest {
assertThat(DateTimeUtils.earliestDateTimeOf(sampleDates)).isEqualTo(START_OF_TIME);
}
@Test
void testSuccess_earliestOf_instant() {
assertThat(earliestOf(START_INSTANT, END_INSTANT)).isEqualTo(START_INSTANT);
assertThat(earliestOf(ImmutableList.of(START_INSTANT, END_INSTANT))).isEqualTo(START_INSTANT);
}
@Test
void testSuccess_latestOf() {
assertThat(latestOf(START_OF_TIME, END_OF_TIME)).isEqualTo(END_OF_TIME);
assertThat(latestOf(sampleDates)).isEqualTo(END_OF_TIME);
assertThat(DateTimeUtils.latestDateTimeOf(sampleDates)).isEqualTo(END_OF_TIME);
}
@Test
void testSuccess_latestOf_instant() {
assertThat(latestOf(START_INSTANT, END_INSTANT)).isEqualTo(END_INSTANT);
assertThat(latestOf(ImmutableList.of(START_INSTANT, END_INSTANT))).isEqualTo(END_INSTANT);
}
@Test
@@ -71,47 +83,47 @@ class DateTimeUtilsTest {
}
@Test
void testSuccess_leapSafeAddYears() {
void testSuccess_plusYears() {
DateTime startDate = DateTime.parse("2012-02-29T00:00:00Z");
assertThat(startDate.plusYears(4)).isEqualTo(DateTime.parse("2016-02-29T00:00:00Z"));
assertThat(leapSafeAddYears(startDate, 4)).isEqualTo(DateTime.parse("2016-02-28T00:00:00Z"));
assertThat(plusYears(startDate, 4)).isEqualTo(DateTime.parse("2016-02-28T00:00:00Z"));
}
@Test
void test_leapSafeAddYears_worksWithInstants() {
void test_plusYears_worksWithInstants() {
Instant startDate = Instant.parse("2012-02-29T00:00:00Z");
assertThat(leapSafeAddYears(startDate, 4)).isEqualTo(Instant.parse("2016-02-28T00:00:00Z"));
assertThat(plusYears(startDate, 4)).isEqualTo(Instant.parse("2016-02-28T00:00:00Z"));
}
@Test
void testSuccess_leapSafeSubtractYears() {
void testSuccess_minusYears() {
DateTime startDate = DateTime.parse("2012-02-29T00:00:00Z");
assertThat(startDate.minusYears(4)).isEqualTo(DateTime.parse("2008-02-29T00:00:00Z"));
assertThat(leapSafeSubtractYears(startDate, 4))
.isEqualTo(DateTime.parse("2008-02-28T00:00:00Z"));
assertThat(minusYears(startDate, 4)).isEqualTo(DateTime.parse("2008-02-28T00:00:00Z"));
}
@Test
void test_leapSafeSubtractYears_worksWithInstants() {
void test_minusYears_worksWithInstants() {
Instant startDate = Instant.parse("2012-02-29T00:00:00Z");
assertThat(leapSafeSubtractYears(startDate, 4))
.isEqualTo(Instant.parse("2008-02-28T00:00:00Z"));
assertThat(minusYears(startDate, 4)).isEqualTo(Instant.parse("2008-02-28T00:00:00Z"));
}
@Test
void testSuccess_leapSafeSubtractYears_zeroYears() {
void testSuccess_minusYears_zeroYears() {
DateTime leapDay = DateTime.parse("2012-02-29T00:00:00Z");
assertThat(leapDay.minusYears(0)).isEqualTo(leapDay);
}
@Test
void testFailure_earliestOfEmpty() {
assertThrows(IllegalArgumentException.class, () -> earliestOf(ImmutableList.of()));
assertThrows(
IllegalArgumentException.class, () -> DateTimeUtils.earliestDateTimeOf(ImmutableList.of()));
}
@Test
void testFailure_latestOfEmpty() {
assertThrows(IllegalArgumentException.class, () -> latestOf(ImmutableList.of()));
assertThrows(
IllegalArgumentException.class, () -> DateTimeUtils.latestDateTimeOf(ImmutableList.of()));
}
@Test
@@ -144,13 +156,15 @@ class DateTimeUtilsTest {
@Test
void test_instantConversionMethods_workCorrectly() {
assertThat(toInstant(DateTime.parse("2024-03-27T10:15:30.105Z")))
.isEqualTo(Instant.parse("2024-03-27T10:15:30.105Z"));
assertThat(toDateTime(Instant.parse("2024-03-27T10:15:30.105Z")))
.isEqualTo(DateTime.parse("2024-03-27T10:15:30.105Z"));
assertThat(toInstant(toDateTime(Instant.parse("2024-03-27T10:15:30.105Z"))))
assertThat(toInstant(DateTime.parse("2024-03-27T10:15:30.105Z")))
.isEqualTo(Instant.parse("2024-03-27T10:15:30.105Z"));
assertThat(toDateTime(toInstant(DateTime.parse("2024-03-27T10:15:30.105Z"))))
.isEqualTo(DateTime.parse("2024-03-27T10:15:30.105Z"));
assertThat(DateTimeUtils.toJodaInstant(Instant.parse("2024-03-27T10:15:30.105Z")))
.isEqualTo(org.joda.time.Instant.parse("2024-03-27T10:15:30.105Z"));
assertThat(DateTimeUtils.parseInstant("2024-03-27T10:15:30.105Z"))
.isEqualTo(Instant.parse("2024-03-27T10:15:30.105Z"));
assertThat(DateTimeUtils.parseInstant("2024-03-27T10:15:30Z"))
.isEqualTo(Instant.parse("2024-03-27T10:15:30Z"));
}
}