1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java】現在日時を取得する時はLocalDateTime.now()を使わない

Last updated at Posted at 2025-08-29

令和生まれなのにnew Date()をしているコードは見なかったことにします

結論:LocalDateTime.now(Clock clock)を使う

引数にClock型を渡してあげることで、テスト時に現在時刻を固定化できます。

他の時刻系クラス(Instant・OffsetDateTime・ZonedDateTime)も同様です。

自戒ですが、現在時刻がビジネスロジックに関わる場合は気を付けましょう。

(昔の現場でJunitを全件実行するとテストが失敗する問題を見ました)

サンプルコード

DIで利用する場合は以下のようなイメージ。

@Service
public class AService {

    private final Clock clock;

    public AService(Clock clock) {
        this.clock = clock;
    }

    public LocalDateTime generateTimestamp() {
        return LocalDateTime.now(clock);
    }
}
@Configuration
public class ClockConfig {
    @Bean
    public Clock systemClock() {
        return Clock.system(ZoneId.of("Asia/Tokyo"));
    }
}

テスト時はConfigurationを上書きできます。

@TestConfiguration
public class TestClockConfig {
    @Bean
    public Clock fixedClock() {
        return Clock.fixed(
            Instant.parse("2025-09-01T01:23:45Z"),
            ZoneId.of("Asia/Tokyo")
        );
    }
}

MockBeanを使うとテストケースごと時間を固定できる。

@SpringBootTest
class ReportServiceTest {

    @Autowired
    ReportService reportService;

    @MockBean
    Clock clock;

    @Test
    void morningTest() {
        ZoneId zone = ZoneId.of("Asia/Tokyo");
        Instant fixedInstant = Instant.parse("2025-08-30T00:00:00Z"); 

        when(clock.instant()).thenReturn(fixedInstant);
        when(clock.getZone()).thenReturn(zone);

        assertEquals(
            LocalDateTime.of(2025, 8, 30, 9, 0),
            reportService.generateTimestamp()
        );
    }
}

間違いがあれば指摘してください!

最後に

Twitterもやってます、エンジニアの友達が出来ればうれしいです!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?