当前位置: 首页 > 知识库问答 >
问题:

如何使用模式dMMyyyy的日期时间格式

况景龙
2023-03-14

我需要使用DateTimeFormatter将字符串解析为LocalDate。

有2种不同的情况,模式的字符串dMMyy或ddMMyy(20320, 020320, 120320)和模式的字符串ddMMyyyy或dMMyyyy(2032020, 02032020, 12032020)。

对于第一种情况,我可以使用DateTimeFormatter.of模式(dMMyy),它适用于5位或6位长日期。

 @Test
    public void dateConversionyy() {
       DateTimeFormatter worksShortd = DateTimeFormatter.ofPattern("dMMyy");
       DateTimeFormatter worksShortdd = DateTimeFormatter.ofPattern("ddMMyy");
       String longString = "120320";
       String leadingZeroString = "020320";
       String shortString = "20320";

       LocalDate res = LocalDate.parse(longString, worksShortd);
       assertNotNull(res);

       LocalDate res2 = LocalDate.parse(longString, worksShortdd);
       assertNotNull(res2);
       assertEquals(res, res2);

       LocalDate res3 = LocalDate.parse(shortString, worksShortd);
       assertNotNull(res3);

       LocalDate res4 = LocalDate.parse(leadingZeroString, worksShortd);
       assertNotNull(res4);
       assertEquals(res3, res4);

       LocalDate res5 = LocalDate.parse(leadingZeroString, worksShortdd);
       assertNotNull(res);
       assertEquals(res3, res5);

    }

对于第二种情况,我认为我可以使用模式“dMMyyyy”,但它只是不解析任何输入字符串。

 @Test
    public void dateConversionyyyy() {
        LocalDate res;
       DateTimeFormatter failsLong = DateTimeFormatter.ofPattern("dMMyyyy");
       DateTimeFormatter worksLong = DateTimeFormatter.ofPattern("ddMMyyyy");
       String longString = "13082020";
       String shortString = "3082020";
       boolean notParsed1 = false;
       try {
           LocalDate.parse(longString, failsLong);
       } catch (DateTimeParseException e) {
           notParsed1 = true;
       }
       assertTrue(notParsed1);
       res = LocalDate.parse(longString, worksLong);
       assertNotNull(res);

        boolean notParsed2 = false;
        try {
            LocalDate.parse(shortString, failsLong);
        } catch (DateTimeParseException e) {
            notParsed2 = true;
        }
        assertTrue(notParsed2);

    }

编辑:我的问题:有没有一种方法来实例化DateTimeForware 使用DateTimeFormatter.of模式,以解析7-8位变体?

编辑问题,使@user16320675答案匹配,因为它解决了我的问题。


共有1个答案

凌景辉
2023-03-14

我正在使用并略微修改用户16320675在评论中提到的想法:

尝试使用DateTimeFormatterBuilder并使用appendValue(ChronoField.DAY\u OF\u MONTH,1,2,SignStyle.NEVER),对其他字段使用固定大小。

    DateTimeFormatter worksLong = new DateTimeFormatterBuilder()
            .appendPattern("dMM")
            .appendValue(ChronoField.YEAR, 4)
            .toFormatter(Locale.ROOT);
    System.out.println(LocalDate.parse("2032020", worksLong));
    System.out.println(LocalDate.parse("02032020", worksLong));
    System.out.println(LocalDate.parse("12032020", worksLong));

输出:

2020-03-02
2020-03-02
2020-03-12

如果您希望在构建格式化程序时具有更高的一致性:

    DateTimeFormatter worksLong = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.DAY_OF_MONTH)
            .appendValue(ChronoField.MONTH_OF_YEAR, 2)
            .appendValue(ChronoField.YEAR, 4)
            .toFormatter(Locale.ROOT);

结果是一样的。

年,或者更准确地说,模式字母u、y和y在日期时间格式中是特殊的。ofPattern()。对于其他数字字段,四个图案字母表示宽度正好为4的字段。多年来,这意味着最小田地宽度为4。这反过来又破坏了在两位数年份情况下工作的邻接值解析。相反,我认为解析器贪婪地使用所有7或8位数字作为月份的日期,然后无法找到它们之后的一个月。

相邻值解析是使模式dMMyy工作的原因。当所有其他字段都具有固定宽度时,它基本上允许一系列字段中的第一个(并且只有第一个)具有可变宽度,这些字段之间没有分隔符。因此,让相邻值解析再次工作的技巧是使年份字段的宽度固定为4。生成器的appendValue方法可以做到这一点。

那么,当YYY没有工作时,为什么yy工作了呢?因为岁月是特别的<代码>yy表示固定宽度2<代码>yyyy表示最小宽度为4。

DateTimeForware的留档:

年份:字母数决定使用填充的最小字段宽度。如果字母数为2,则使用缩减的两位数形式。对于打印,这将输出最右边的两位数字。对于解析,这将使用2000的基值进行解析,结果是2000到2099(含)之间的一年。如果字母数少于四个(但不是两个),则符号仅按符号样式输出负年份。正常。否则,如果超过焊盘宽度,则根据SignStyle输出符号。超过PAD。

  • 日期时间格式
  • 日期时间格式生成器。附录值(临时字段,int)
 类似资料:
  • 问题内容: 我正在使用新的日期时间API,但是在运行时: 它抛出: 查看LocalDate类的源代码时,我看到: 如文档中所述: 此方法将根据类文档中描述的简单字母和符号模式创建格式化程序。 并且所有这些字母都已定义。 那么为什么不允许我们使用一些图案字母呢? 问题答案: 仅代表一个日期,而不代表DateTime。因此,在格式化a时,“ HH:mm:ss”毫无意义。假设您要代表日期和时间,请改用a

  • 我正在玩新的日期时间API,但在运行时: 它抛出: 在查看LocalDate类的源代码时,我看到: 正如文件中所述: 该方法将根据类文档中描述的字母和符号的简单模式创建格式化程序。 所有这些字母都有定义。 那么为什么选择DateTimeFormatter呢。ofPattern不允许我们使用一些模式字母?

  • 下表显示可用于为图表中的日期时间字段创建用户定义的数据格式的说明符。 说明符 描述 D 将日显示为不带前导零的数字(1-31)。 DD 将日显示为带前导零的数字(01-31)。 M 将月份显示为不带前导零的数字(1-12)。 MM 将月份显示为带前导零的数字(01-12)。 MMM 将月份显示为缩写形式(Jan-Dec)。 MMMM 将月份显示为完整月份名(January-December)。 Y

  • 下表显示可用于为图表中的日期时间字段创建用户定义的数据格式的说明符。 说明符 描述 D 将日显示为不带前导零的数字(1-31)。 DD 将日显示为带前导零的数字(01-31)。 M 将月份显示为不带前导零的数字(1-12)。 MM 将月份显示为带前导零的数字(01-12)。 MMM 将月份显示为缩写形式(Jan-Dec)。 MMMM 将月份显示为完整月份名(January-December)。 Y

  • 下表显示可用于为图表中的日期时间字段创建用户定义的数据格式的说明符。 说明符 描述 D 将日显示为不带前导零的数字(1-31)。 DD 将日显示为带前导零的数字(01-31)。 M 将月份显示为不带前导零的数字(1-12)。 MM 将月份显示为带前导零的数字(01-12)。 MMM 将月份显示为缩写形式(Jan-Dec)。 MMMM 将月份显示为完整月份名(January-December)。 Y

  • 问题内容: 我需要改变从一个日期/时间 2014年8月20日15:30:00 看起来像 二○一四年八月二十○日下午3:30 可以使用javascript的Date对象完成此操作吗? 问题答案: 是的,您可以使用本地javascript Date() 对象 及其方法。 例如,您可以创建一个类似以下的函数: 并显示上午/下午和正确的时间。 请记住使用 getFullYear() 方法,而不要使用get