DateTimeFormatter 接受多种类型并转换为一种
DateTimeFormatter Accept Multiple Types and Convert to One
我正在尝试编写一个 DateTimeFormatter
允许我接受多种不同的字符串格式,然后将字符串格式转换为特定类型。由于项目的范围和已经存在的代码,我不能使用不同类型的格式化程序。
例如。
我想接受 MM/dd/yyyy
和 yyyy-MM-dd'T'HH:mm:ss
,然后将两者都转换为 MM/dd/yyyy
。
有人可以就如何使用 org.joda.time.format
执行此操作提出建议吗?
我还没有在网上找到 good/working 这个例子。
我正在使用 Joda-Time 2.9.7 和 JDK 1.7.0_79.
您可以使用 DateTimeFormatterBuilder.append
method:它接收一台打印机(具有用于打印 date/times 的模式)和一组具有所有可能输入模式的解析器:
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),夏令时开始于 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: 由于您只关心 date 部分 (day/month/year),您也可以使用 org.joda.time.LocalDate
class。要使用它,只需更改代码的最后一部分(您可以使用相同的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
没有时区信息。
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);
我正在尝试编写一个 DateTimeFormatter
允许我接受多种不同的字符串格式,然后将字符串格式转换为特定类型。由于项目的范围和已经存在的代码,我不能使用不同类型的格式化程序。
例如。
我想接受 MM/dd/yyyy
和 yyyy-MM-dd'T'HH:mm:ss
,然后将两者都转换为 MM/dd/yyyy
。
有人可以就如何使用 org.joda.time.format
执行此操作提出建议吗?
我还没有在网上找到 good/working 这个例子。
我正在使用 Joda-Time 2.9.7 和 JDK 1.7.0_79.
您可以使用 DateTimeFormatterBuilder.append
method:它接收一台打印机(具有用于打印 date/times 的模式)和一组具有所有可能输入模式的解析器:
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),夏令时开始于 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: 由于您只关心 date 部分 (day/month/year),您也可以使用 org.joda.time.LocalDate
class。要使用它,只需更改代码的最后一部分(您可以使用相同的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
没有时区信息。
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);