This rule raises an issue when calling .now() without arguments on java.time API classes that support time zone specification, such as LocalDateTime, ZonedDateTime, or OffsetDateTime.

Why is this an issue?

The java.time API provides various classes for working with dates and times. Many of these classes have a .now() method that returns the current date/time. When called without arguments, these methods use the system’s default time zone.

Relying on the system default time zone can lead to several problems:

By explicitly specifying a ZoneId or a Clock object, you make your intent clear and ensure consistent behavior across all environments. This applies to the following classes:

Note that even though LocalDateTime and similar "Local" classes don’t store time zone information, their .now() methods still use the system default to determine what "now" means.

What is the potential impact?

Using system default time zones can lead to:

How to fix it

Explicitly specify the time zone by passing a ZoneId or a Clock to the .now() method. If you genuinely want to use the system default, make this explicit by using ZoneId.systemDefault(). If you need a specific time zone, use ZoneId.of() with the appropriate zone identifier.

Code examples

Noncompliant code example

LocalDateTime dt = LocalDateTime.now(); // Noncompliant

Compliant solution

// Option 1: Make system default explicit
LocalDateTime dt1 = LocalDateTime.now(ZoneId.systemDefault());

// Option 2: Use a specific time zone
LocalDateTime dt2 = LocalDateTime.now(ZoneId.of("Europe/Zurich"));

// Option 3: Use UTC for server-side operations
LocalDateTime dt3 = LocalDateTime.now(ZoneId.of("UTC"));

// Option 4: Provide a Clock
Clock myClock = Clock.systemUTC();
LocalDateTime dt4 = LocalDateTime.now(myClock);

Resources

Documentation