java - DateTimeFormatter 接受多个日期并转换为一个(java.time 库)

标签 java datetime datetime-format java-time datetime-parsing

我正在尝试编写一个 DateTimeFormatter,它允许我接受多种不同的 String 格式,然后将 String 格式转换为特定类型。由于项目的范围和已经存在的代码,我不能使用不同类型的格式化程序。

例如,我想接受 MM/dd/yyyy 以及 yyyy-MM-dd'T'HH:mm:ss 但是当我打印时我只想打印成 MM/dd/yyyy 格式,并在我调用 LocalDate.format(formatter);

时使用该格式

有人可以建议有关如何使用 java.time.format.*;

执行此操作的想法

这是我在 org.joda 中的实现方式:

// MM/dd/yyyy format
DateTimeFormatter monthDayYear = DateTimeFormat.forPattern("MM/dd/yyyy");
// array of parsers, with all possible input patterns
DateTimeParser[] parsers = {
        // parser for MM/dd/yyyy format
        monthDayYear.getParser(),
        // parser for yyyy-MM-dd'T'HH:mm:ss format
        DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").getParser()
};
DateTimeFormatter parser = new DateTimeFormatterBuilder()
    // use the monthDayYear formatter for output (monthDayYear.getPrinter())
    // and parsers array for input (parsers)
    .append(monthDayYear.getPrinter(), parsers)
    // create formatter (using UTC to avoid DST problems)
    .toFormatter()
    .withZone(DateTimeZone.UTC);

我还没有在网上找到一个好的/有效的例子。

最佳答案

我已经使用 JDK 1.8.0_131 for Mac OS XJDK 1.8.0111 for Windows 进行了测试(均有效)。

我创建了一个包含可选部分(由 [] 分隔)的 DateTimeFormatter,以解析这两种情况 (MM/dd/yyyyyyyy-MM-dd'T'HH:mm:ss)。

相同的格式化程序适用于您的情况 (LocalDate),但下面有一些注意事项。

// parse both formats (use optional section, delimited by [])
DateTimeFormatter parser = DateTimeFormatter.ofPattern("[MM/dd/yyyy][yyyy-MM-dd'T'HH:mm:ss]");

// parse MM/dd/yyyy
LocalDate d1 = LocalDate.parse("10/16/2016", parser);
// parse yyyy-MM-dd'T'HH:mm:ss
LocalDate d2 = LocalDate.parse("2016-10-16T10:20:30", parser);

// parser.format(d1) is the same as d1.format(parser)
System.out.println(parser.format(d1));
System.out.println(parser.format(d2));

输出是:

10/16/2016
10/16/2016


PS:这仅适用于 LocalDate。如果我尝试使用时间字段(如 LocalDateTime)格式化对象,则会使用两种格式:

System.out.println(parser.format(LocalDateTime.now()));

这打印:

06/18/20172017-06-18T07:40:55

请注意,它使用两种模式进行格式化。我的猜测是格式化程序检查对象是否在每个可选部分中都有字段。由于 LocalDate 没有时间字段(小时/分钟/秒),第二个模式失败,它只打印第一个(MM/dd/yyyy)。但是LocalDateTime有所有的时间字段,而且两种模式都是有效的,所以都用来格式化。

我的结论是:这不是一个通用的解决方案(如 Joda-Time 的版本),它更像是一个“幸运”案例,其中涉及的模式创造了所需的情况。但我不会在所有情况下都依赖它。

无论如何,如果您只使用LocalDate,您可以尝试使用此代码。但是,如果您正在使用其他类型,那么您可能必须为输出使用另一个 格式化程序,如下所示:

// parser/formatter for month/day/year
DateTimeFormatter mdy = DateTimeFormatter.ofPattern("MM/dd/yyyy");
// parser for both patterns
DateTimeFormatter parser = new DateTimeFormatterBuilder()
    // optional MM/dd/yyyy
    .appendOptional(mdy)
    // optional yyyy-MM-dd'T'HH:mm:ss (use built-in formatter)
    .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    // create formatter
    .toFormatter();

// parse MM/dd/yyyy
LocalDate d1 = LocalDate.parse("10/16/2016", parser);
// parse yyyy-MM-dd'T'HH:mm:ss
LocalDate d2 = LocalDate.parse("2016-10-16T10:20:30", parser);

// use mdy to format
System.out.println(mdy.format(d1));
System.out.println(mdy.format(d2));

// format object with time fields: using mdy formatter to avoid multiple pattern problem
System.out.println(mdy.format(LocalDateTime.now()));

输出是:

10/16/2016
10/16/2016
06/18/2017

关于java - DateTimeFormatter 接受多个日期并转换为一个(java.time 库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44600420/

相关文章:

java - 尝试在 QT 项目中调用 Java 代码时找不到类异常

python - 当使用最小最大范围时,Django 对象过滤器收到一个简单的日期时间,而时区支持处于事件状态

java - 使用 DateTimeFormatterBuilder 将 String 解析为 LocalDateTime 时如何防止自动生成 'T' 字母

c# - DateTime.ParseExact 的正确格式

javascript - 我们如何停止将 UTC 日期时间对象转换为本地日期时间?

java - 如何将 firebase 数据 (snake_case) 转换为 Java 对象 (camelCase)

java - GRBVar 的绝对值

java - 如何动态调度不同的java类?

c# - 隐式转换为 DateTime?和 op_Equality

datetime - 自 1800 年 12 月 28 日以来,什么日历似乎可以计算天数?