Javaの日付フォーマットYYYY-DDのピット

3387 ワード

このブログを書くのは年越しのバグを記録することだ.昨年、隣のグループの仲間は、年をまたいで計算が間違っていたため、2つの日付の間隔を計算する日数だった.
当時、テストチームの姉もこのようなシーンをシミュレートせず、生産環境がオンラインのデータに直接影響を及ぼした.
今日、技術論フォーラムをぶらぶらしていると、Javaの日付の操作バグに遭遇しました.
1 yyyyとYYYY
字を読まないで、コードを見て
  @Test
    public void testWeekBasedYear() {
        Calendar calendar = Calendar.getInstance();
        // 2019-12-31
        calendar.set(2019, Calendar.DECEMBER, 31);
        Date strDate1 = calendar.getTime();
        // 2020-01-01
        calendar.set(2020, Calendar.JANUARY, 1);
        Date strDate2 = calendar.getTime();
        //    YYYY
        SimpleDateFormat formatYYYY = new SimpleDateFormat("YYYY/MM/dd");
        System.out.println("2019-12-31   YYYY/MM/dd   : " + formatYYYY.format(strDate1));
        System.out.println("2020-01-01   YYYY/MM/dd   : " + formatYYYY.format(strDate2));
        //    YYYY
        SimpleDateFormat formatyyyy = new SimpleDateFormat("yyyy/MM/dd");
        System.out.println("2019-12-31   yyyy/MM/dd   : " + formatyyyy.format(strDate1));
        System.out.println("2020-01-01   yyyy/MM/dd   : " + formatyyyy.format(strDate2));
    }

出力結果
2019-12-31   YYYY/MM/dd   : 2020/12/31
2020-01-01   YYYY/MM/dd   : 2020/01/01
2019-12-31   yyyy/MM/dd   : 2019/12/31
2020-01-01   yyyy/MM/dd   : 2020/01/01

注意深い学友は発見したはずです2019-12-31 YYY/MM/ddで今2020/12/31になりました
??なぜですか?YYYYのような大きな能力は、2020年代まで走ることができますか?
私が2019年末に買ったものをYYYで出荷日をフォーマットすれば、2020年末に商品を受け取ることができますか?このバグの問題は大きいですね.
YYYYYはいったいどこの妖怪ですか?
Java's DateTimeFormatter pattern "YYYY"gives you the week-based-year, (by default, ISO-8601 standard) the year of the Thursday of that week.
例:
次はYYYYでコードをフォーマットします
  • 12/29/2019は2019年の今週にフォーマットされ、2019年
  • にも属します.
  • 12/30/2009は2020年の今週にフォーマットされ、2020年
  • に属しています.
    字を見て話すYYYY、week-based yearはISO 8601に規定されています.
    2019-12-31日のこの日、安周算年は2020年に属し、フォーマットされてから2020年になり、後の月の日付は変わらない.
    2 ddとDD
      private static void tryit(int Y, int M, int D, String pat) {
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pat);
            LocalDate         dat = LocalDate.of(Y,M,D);
            String            str = fmt.format(dat);
            System.out.printf("Y=%04d M=%02d D=%02d " +
                "formatted with " +
                "\"%s\" -> %s
    ",Y,M,D,pat,str); } public static void main(String[] args){ tryit(2020,01,20,"MM/DD/YYYY"); tryit(2020,01,21,"DD/MM/YYYY"); tryit(2020,01,22,"YYYY-MM-DD"); tryit(2020,03,17,"MM/DD/YYYY"); tryit(2020,03,18,"DD/MM/YYYY"); tryit(2020,03,19,"YYYY-MM-DD"); }

    出力結果
    Y=2020 M=01 D=20 formatted with "MM/DD/YYYY" -> 01/20/2020
    Y=2020 M=01 D=21 formatted with "DD/MM/YYYY" -> 21/01/2020
    Y=2020 M=01 D=22 formatted with "YYYY-MM-DD" -> 2020-01-22
    Y=2020 M=03 D=17 formatted with "MM/DD/YYYY" -> 03/77/2020
    Y=2020 M=03 D=18 formatted with "DD/MM/YYYY" -> 78/03/2020
    Y=2020 M=03 D=19 formatted with "YYYY-MM-DD" -> 2020-03-79

    見たか?最後の3つの日付が間違っています.ここの大文字のDDは、この年のその日を表し、今月の日ではありませんが、ddは問題ありません.
    仲間たちはこのような間違いを犯さないように覚えなければならない.この鍋は私たちが背負わない.
    結論
    YYYYとyyyyyは違いますが、DDとddも違いますので覚えておいてください.