DateTimeFormatter接受多个类型并转换为一个

时间:2017-06-14 18:21:20

标签: 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

执行此操作的建议

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

2 个答案:

答案 0 :(得分:3)

我使用 Joda-Time 2.9.7 JDK 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小时(所以, tecnically ,午夜不存在,因为时间从23:59:59变为01:00:00

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

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

输出结果为:

  

2017年6月14日
  2017年6月14日

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

输出相同:

  

2017年6月14日
  2017年6月14日

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

答案 1 :(得分:0)

private static final DateTimeFormatter SIMPLE_DATE_FORMAT = 
  DateTimeFormatter.ofPattern("[MM/dd/yy][M/dd/yy][MM/d/yy][M/d/yy]");

// value = "04/12/19"
// value = "4/12/19"
// value = "12/4/19"
// value = "2/4/19"

LocalDate.parse(value, SIMPLE_DATE_FORMAT);