java - DateTimeFormatter 接受多种类型并转换为一种

标签 java datetime jodatime datetime-format datetime-parsing

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

例如。 我想接受 MM/dd/yyyy 以及 yyyy-MM-dd'T'HH:mm:ss 但然后将两者都转换为 MM/dd/yyyy.

有人可以就如何使用 org.joda.time.format 提出建议吗?

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

最佳答案

我正在使用 Joda-Time 2.9.7JDK 1.7.0_79

您可以使用 DateTimeFormatterBuilder.append method : 它接收一台打印机(带有用于打印日期/时间的模式)和一组具有所有可能输入模式的解析器:

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;

// 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);

// test with MM/dd/yyyy
DateTime datetime1 = parser.parseDateTime("06/14/2017");
System.out.println(parser.print(datetime1)); // 06/14/2017

// test with yyyy-MM-dd'T'HH:mm:ss
DateTime datetime2 = parser.parseDateTime("2017-06-14T10:30:40");
System.out.println(parser.print(datetime2)); // 06/14/2017

我使用 DateTimeZone.UTC 来避免夏令时问题。

例如,在我的默认时区(America/Sao_Paulo),去年(2016 年)DST 开始于 10 月 16 日th:午夜时分,时钟移动 1提前一小时(因此,技术上,这一天不存在午夜,因为时间从 23:59:59 变为 01:00:00).

问题是,在解析MM/dd/yyyy 格式时,没有小时、分钟或秒的字段,解析器将0 设置为默认值所有这些字段(所以时间变成午夜)。但是,如果我尝试在 DST 开始的日期(如 10/16/2016)进行解析并且不使用上面的 UTC,代码会抛出异常,因为那天不存在午夜(由于 DST 时差)。

使用 UTC 可避免此错误,因为 DateTimeZone.UTC 没有 DST 效果。这样,代码就可以独立于系统的默认时区工作。

输出是:

06/14/2017
06/14/2017


PS:因为您只关心日期部分(日/月/年),您也可以使用org.joda.time.LocalDate 类。要使用它,只需更改代码的最后一部分(您可以使用相同的 parser):

// test with MM/dd/yyyy
LocalDate dt1 = parser.parseLocalDate("06/14/2017");
System.out.println(parser.print(dt1)); // 06/14/2017

// test with yyyy-MM-dd'T'HH:mm:ss
LocalDate dt2 = parser.parseLocalDate("2017-06-14T10:30:40");
System.out.println(parser.print(dt2)); // 06/14/2017

输出是一样的:

06/14/2017
06/14/2017

使用 LocalDate 是避免夏令时问题的另一种方法(如上所述)。在这种情况下,您不需要设置UTC,因为LocalDate没有时区信息。

关于java - DateTimeFormatter 接受多种类型并转换为一种,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44551994/

相关文章:

java - 使用 Javamail API 和 IMAP 批量获取邮件正文

java - 将 Spring 3、ReST 和 XML 与 Joda 日期类型一起使用时返回数据

java - Joda Time 获得两个瞬间之间的持续时间

java - 如何在Intellij Idea中创建类似Quick Doc的弹出提示窗口?

java - 在java中创建一个二进制文件

java - 记录调试消息

python - 无法使用 hist() 函数对齐日期时间对象直方图中的 bin

Javascript,没有时区的 Date.parse

java - java.sql.Timestamp 时区特定吗?

java - 使用 Joda API 解析日期