Recipe Name:
Migrate new DateTime(java.time.Instant, DateTimeZone) to java.time
Description:
Migrate new DateTime(java.time.Instant, DateTimeZone) to java.time
Level:
warning
Language:
  • java
Tags:
  • framework specific
  • java.time
  • Joda-Time
  • quality
Documentation

Migrate from org.joda.time.DateTime to Java Time

Joda-Time DateTime migrates to java.time ZonedDateTime or OffsetDateTime.

ZonedDateTime is the same concept, date and time with time-zone.

OffsetDateTime is a new concept, date and time with offset from UTC.

Before
    DateTime dateTime = new DateTime();
    int monthOfYear = dateTime.getMonthOfYear();
After
    ZonedDateTime dateTime = ZonedDateTime.now();
    int monthOfYear = dateTime.getMonthValue();
References
Recipe
id: scw:java.time:Joda-Time:DateTime-constructor-Instant-DateTimeZone
version: 10
metadata:
  name: Migrate new DateTime(java.time.Instant, DateTimeZone) to java.time
  shortDescription: Migrate new DateTime(java.time.Instant, DateTimeZone) to java.time
  level: warning
  language: java
  enabled: true
  comment: |
    This recipe is designed to match on broken code as part of an overall migration from Joda-Time to java.time.

    The Instant and DateTimeZone arguments provided to this constructor will be required to be migrated to complete this migration.
    This can be done before or after the migration of this constructor. This recipe detects both Joda-Time and java.time types for each argument 1 to allow this behaviour.

    It is worth noting this recipe uses ZoneId.of("UTC") and ZoneOffset.UTC instead of ZoneId.systemDefault() in the fixes.
    The reason for this, is that in Joda-Time the new DateTime(Instant) constructor behaves differently to the other DateTime constructors, by using UTC as the Default DateTimeZone instead of the System Default.

    Additionally, the reason there are separate migration recipes for Instant and TemporalAccessor, is that even though java.time.Instant implements the java.time.temporal.TemporalAccessor interface, it cannot be used in ZonedDateTime.from(TemporalAccessor) or OffsetDateTime.from(TemporalAccessor) because a DateTimeException will be thrown, complaining it cannot determine the time zone.

    This recipe will cause broken code as part of an overall number of steps to perform a migration of Joda-Time to java.time.

    After migrating this instance creation to the java.time equivalent, subsequent method calls and usages of the instance may become invalid.
    Further Sensei recipes are available to help resolve many of these invalid usages.
  descriptionFile: descriptions/datetime.html
  tags: framework specific;java.time;Joda-Time;quality
search:
  instanceCreation:
    args:
      1:
        anyOf:
        - type: java.time.Instant
        - type: org.joda.time.Instant
      2:
        anyOf:
        - type: java.time.ZoneId
        - type: org.joda.time.DateTimeZone
    argCount: 2
    type: org.joda.time.DateTime
availableFixes:
- name: Migrate to java.time.ZonedDateTime
  actions:
  - rewrite:
      to: java.time.ZonedDateTime.ofInstant({{{ arguments.0 }}},{{{ arguments.1 }}})
  - modifyAssignedVariable:
      type: java.time.ZonedDateTime
- name: Migrate to java.time.OffsetDateTime
  actions:
  - rewrite:
      to: java.time.OffsetDateTime.ofInstant({{{ arguments.0 }}},{{{ arguments.1 }}})
  - modifyAssignedVariable:
      type: java.time.OffsetDateTime