diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/TimeRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/TimeRules.java index 5ff77ff8fa..47fd62e0e7 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/TimeRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/TimeRules.java @@ -13,9 +13,11 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; +import java.time.OffsetTime; import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; import java.time.chrono.ChronoZonedDateTime; @@ -64,7 +66,83 @@ ZoneOffset after() { } } - /** Prefer {@link Instant#atOffset(ZoneOffset)} over the more verbose alternative. */ + /** Prefer {@link LocalDate#ofInstant(Instant, ZoneId)} over more indirect alternatives. */ + static final class LocalDateOfInstant { + @BeforeTemplate + LocalDate before(Instant instant, ZoneId zoneId) { + return Refaster.anyOf( + instant.atZone(zoneId).toLocalDate(), + LocalDateTime.ofInstant(instant, zoneId).toLocalDate(), + OffsetDateTime.ofInstant(instant, zoneId).toLocalDate()); + } + + @BeforeTemplate + LocalDate before(Instant instant, ZoneOffset zoneId) { + return instant.atOffset(zoneId).toLocalDate(); + } + + @AfterTemplate + LocalDate after(Instant instant, ZoneId zoneId) { + return LocalDate.ofInstant(instant, zoneId); + } + } + + /** Prefer {@link LocalDateTime#ofInstant(Instant, ZoneId)} over more indirect alternatives. */ + static final class LocalDateTimeOfInstant { + @BeforeTemplate + LocalDateTime before(Instant instant, ZoneId zoneId) { + return Refaster.anyOf( + instant.atZone(zoneId).toLocalDateTime(), + OffsetDateTime.ofInstant(instant, zoneId).toLocalDateTime()); + } + + @BeforeTemplate + LocalDateTime before(Instant instant, ZoneOffset zoneId) { + return instant.atOffset(zoneId).toLocalDateTime(); + } + + @AfterTemplate + LocalDateTime after(Instant instant, ZoneId zoneId) { + return LocalDateTime.ofInstant(instant, zoneId); + } + } + + /** Prefer {@link LocalTime#ofInstant(Instant, ZoneId)} over more indirect alternatives. */ + static final class LocalTimeOfInstant { + @BeforeTemplate + LocalTime before(Instant instant, ZoneId zoneId) { + return Refaster.anyOf( + instant.atZone(zoneId).toLocalTime(), + LocalDateTime.ofInstant(instant, zoneId).toLocalTime(), + OffsetDateTime.ofInstant(instant, zoneId).toLocalTime(), + OffsetTime.ofInstant(instant, zoneId).toLocalTime()); + } + + @BeforeTemplate + LocalTime before(Instant instant, ZoneOffset zoneId) { + return instant.atOffset(zoneId).toLocalTime(); + } + + @AfterTemplate + LocalTime after(Instant instant, ZoneId zoneId) { + return LocalTime.ofInstant(instant, zoneId); + } + } + + /** Prefer {@link OffsetDateTime#ofInstant(Instant, ZoneId)} over more indirect alternatives. */ + static final class OffsetDateTimeOfInstant { + @BeforeTemplate + OffsetDateTime before(Instant instant, ZoneId zoneId) { + return instant.atZone(zoneId).toOffsetDateTime(); + } + + @AfterTemplate + OffsetDateTime after(Instant instant, ZoneId zoneId) { + return OffsetDateTime.ofInstant(instant, zoneId); + } + } + + /** Prefer {@link Instant#atOffset(ZoneOffset)} over more verbose alternatives. */ static final class InstantAtOffset { @BeforeTemplate OffsetDateTime before(Instant instant, ZoneOffset zoneOffset) { @@ -77,6 +155,37 @@ OffsetDateTime after(Instant instant, ZoneOffset zoneOffset) { } } + /** Prefer {@link OffsetTime#ofInstant(Instant, ZoneId)} over more indirect alternatives. */ + static final class OffsetTimeOfInstant { + @BeforeTemplate + OffsetTime before(Instant instant, ZoneId zoneId) { + return OffsetDateTime.ofInstant(instant, zoneId).toOffsetTime(); + } + + @BeforeTemplate + OffsetTime before(Instant instant, ZoneOffset zoneId) { + return instant.atOffset(zoneId).toOffsetTime(); + } + + @AfterTemplate + OffsetTime after(Instant instant, ZoneId zoneId) { + return OffsetTime.ofInstant(instant, zoneId); + } + } + + /** Prefer {@link Instant#atZone(ZoneId)} over more verbose alternatives. */ + static final class InstantAtZone { + @BeforeTemplate + ZonedDateTime before(Instant instant, ZoneId zoneId) { + return ZonedDateTime.ofInstant(instant, zoneId); + } + + @AfterTemplate + ZonedDateTime after(Instant instant, ZoneId zoneId) { + return instant.atZone(zoneId); + } + } + /** Use {@link Clock#systemUTC()} when possible. */ static final class UtcClock { @BeforeTemplate diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/TimeRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/TimeRulesTestInput.java index b813403c0d..6407a91a5f 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/TimeRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/TimeRulesTestInput.java @@ -8,6 +8,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; +import java.time.OffsetTime; import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; @@ -35,10 +36,48 @@ ImmutableSet testUtcConstant() { ZoneId.from(ZoneOffset.UTC)); } + ImmutableSet testLocalDateOfInstant() { + return ImmutableSet.of( + Instant.EPOCH.atZone(ZoneId.of("Europe/Amsterdam")).toLocalDate(), + Instant.EPOCH.atOffset(ZoneOffset.UTC).toLocalDate(), + LocalDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Berlin")).toLocalDate(), + OffsetDateTime.ofInstant(Instant.EPOCH, ZoneOffset.MIN).toLocalDate()); + } + + ImmutableSet testLocalDateTimeOfInstant() { + return ImmutableSet.of( + Instant.EPOCH.atZone(ZoneId.of("Europe/Amsterdam")).toLocalDateTime(), + Instant.EPOCH.atOffset(ZoneOffset.UTC).toLocalDateTime(), + OffsetDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Berlin")).toLocalDateTime()); + } + + ImmutableSet testLocalTimeOfInstant() { + return ImmutableSet.of( + Instant.EPOCH.atZone(ZoneId.of("Europe/Amsterdam")).toLocalTime(), + Instant.EPOCH.atOffset(ZoneOffset.UTC).toLocalTime(), + LocalDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Berlin")).toLocalTime(), + OffsetDateTime.ofInstant(Instant.EPOCH, ZoneOffset.MIN).toLocalTime(), + OffsetTime.ofInstant(Instant.EPOCH, ZoneOffset.MAX).toLocalTime()); + } + + OffsetDateTime testOffsetDateTimeOfInstant() { + return Instant.EPOCH.atZone(ZoneOffset.UTC).toOffsetDateTime(); + } + OffsetDateTime testInstantAtOffset() { return OffsetDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC); } + ImmutableSet testOffsetTimeOfInstant() { + return ImmutableSet.of( + OffsetDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Amsterdam")).toOffsetTime(), + Instant.EPOCH.atOffset(ZoneOffset.UTC).toOffsetTime()); + } + + ZonedDateTime testInstantAtZone() { + return ZonedDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC); + } + Clock testUtcClock() { return Clock.system(ZoneOffset.UTC); } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/TimeRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/TimeRulesTestOutput.java index 2e411bcc19..1f02b4f622 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/TimeRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/TimeRulesTestOutput.java @@ -8,6 +8,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; +import java.time.OffsetTime; import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; @@ -35,10 +36,48 @@ ImmutableSet testUtcConstant() { ZoneOffset.UTC); } + ImmutableSet testLocalDateOfInstant() { + return ImmutableSet.of( + LocalDate.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Amsterdam")), + LocalDate.ofInstant(Instant.EPOCH, ZoneOffset.UTC), + LocalDate.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Berlin")), + LocalDate.ofInstant(Instant.EPOCH, ZoneOffset.MIN)); + } + + ImmutableSet testLocalDateTimeOfInstant() { + return ImmutableSet.of( + LocalDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Amsterdam")), + LocalDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC), + LocalDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Berlin"))); + } + + ImmutableSet testLocalTimeOfInstant() { + return ImmutableSet.of( + LocalTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Amsterdam")), + LocalTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC), + LocalTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Berlin")), + LocalTime.ofInstant(Instant.EPOCH, ZoneOffset.MIN), + LocalTime.ofInstant(Instant.EPOCH, ZoneOffset.MAX)); + } + + OffsetDateTime testOffsetDateTimeOfInstant() { + return OffsetDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC); + } + OffsetDateTime testInstantAtOffset() { return Instant.EPOCH.atOffset(ZoneOffset.UTC); } + ImmutableSet testOffsetTimeOfInstant() { + return ImmutableSet.of( + OffsetTime.ofInstant(Instant.EPOCH, ZoneId.of("Europe/Amsterdam")), + OffsetTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC)); + } + + ZonedDateTime testInstantAtZone() { + return Instant.EPOCH.atZone(ZoneOffset.UTC); + } + Clock testUtcClock() { return Clock.systemUTC(); }