LoginSignup
1
1

More than 5 years have passed since last update.

[Java] ResolverStyle.LENIENTを利用して日時をいい感じに扱う

Last updated at Posted at 2018-03-21

概要

Java8より利用可能な、 java.time.format.ResolverStyle を使って、
扱いづらい日時を、いい感じに利用できます。
25:16 ってどうやって扱えばよいのかわからないといった方に便利です。

java.time.format.ResolverStyleとは?

Java8より、java.time.format.DateTimeFormatterを利用して
Stringから日時オブジェクトへ変換します。
変換する際のスタイルが、EnumとしてResolverStyleに定義してあります。 DateTimeFormatterへ渡すことで、スタイルを切り替えることができます。

スタイル (3種類)

(STRICTとSMARTに関しては、実証できていないのでさらっと記載してます)

STRICT

日付と時間を厳密に解決するスタイル

SMART

日付と時間をスマートな(賢い)方法で解決するスタイル。

LENIENT

日付と時間を厳密でない方法で解決するスタイル。

  • 厳密でない解決 = 良い感じに解釈してくれる
    • 2018-01-322018-02-01
    • 2018-01-01 25:002018-01-02 01:00
    • 2018-01-01 00:672018-01-01 01:17

実装

LocalDateTimeクラスへの変換を記載しています。

実装クラス

DateTimeFormatter#withResolverStyle() にてスタイルを指定する
参考実装
(一部抜粋)

public class SampleResolver {
    private DateTimeFormatter formatter;

    public SampleResolver(String format, ResolverStyle style) {
        this.formatter = DateTimeFormatter
                .ofPattern(format)
                // ここが重要
                .withResolverStyle(style);
    }

    public LocalDateTime formatLocal(String s) {
        return LocalDateTime.parse(s, formatter);
    }
}

テスト

下記のテストが全て通ります。
参考テストコード
(一部抜粋)

// Fixture("入力値", "期待値")
@DataPoints
public static Fixture[] fixtures = {
        // 一般
        new Fixture("2018-01-01 10:00", "2018-01-01 10:00"),
        // 月が13
        new Fixture("2018-13-01 00:00", "2019-01-01 00:00"),
        // 日が32
        new Fixture("2018-01-32 00:00", "2018-02-01 00:00"),
        // うるう年
        new Fixture("2020-02-29 00:00", "2020-02-29 00:00"),
        // うるう年 + 1日
        new Fixture("2020-02-30 00:00", "2020-03-01 00:00"),
        // 時刻が24
        new Fixture("2018-01-01 24:00", "2018-01-02 00:00"),
        // 時刻が48
        new Fixture("2018-01-01 48:00", "2018-01-03 00:00"),
        // 分が70
        new Fixture("2018-01-01 00:70", "2018-01-01 01:10"),
};

@Theory
public void formatLocal_LENIENT(Fixture f) throws Exception {
    SampleResolver r = new SampleResolver(FORMAT, ResolverStyle.LENIENT);

    LocalDateTime actual = r.formatLocal(f.input);
    assertThat(f.toString(), actual.format(actualFormatter), is(f.expected));
}

所感

利用した感覚としては、大方期待通りの動作をしてくれています。
「日付またぎ等の仕様で25時xx分を扱わないといけない」となった場合に、
利用してみるのはいかがでしょうか。

参考

1
1
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
1