将日期字符串解析为某些Java对象

时间:2012-01-13 17:36:55

标签: java datetime jodatime date-parsing

我正在一个读取文件和处理数据的项目中工作。在那里,我开始使用日期,例如:

  1. 2012-01-10 23:13:26
  2. 2012年1月13日
  3. 我找到了包Joda,有点有趣的包但不知道它是否是最简单的。

    我能够将第一个示例解析为DateTime对象(Joda)reg-ex和String操作。 (例如:用' - '替换空格并将其传递给构造函数。

    new DateTime("2012-01-10 23:13:26".replace(' ', '-'))
    

    我猜它有用,但问题在于第二种格式。如何使用这样的输入来提取对象,最好是Joda对象。我确定可以编写一个函数来将格式更改为Joda支持的格式,但是想知道是否会有其他方式(甚至是一些本机Java库)来完成它。

    如果有比Joda更好的东西,请告诉我。

    谢谢。

6 个答案:

答案 0 :(得分:39)

使用Joda-Time,看看DateTimeFormat;它允许解析你提到的两种日期字符串(以及几乎任何其他任意格式)。如果您的需求更加复杂,请尝试DateTimeFormatterBuilder

解析#1:

DateTimeFormatter f = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime dateTime = f.parseDateTime("2012-01-10 23:13:26");

编辑:实际上LocalDateTime对于没有时区的日期时间来说是更合适的类型:

LocalDateTime dateTime = f.parseLocalDateTime("2012-01-10 23:13:26");

对于#2:

DateTimeFormatter f = DateTimeFormat.forPattern("MMMM dd, yyyy");
LocalDate localDate = f.parseLocalDate("January 13, 2012");

是的,就Java日期而言,Joda-Time绝对是最佳选择。时间处理。 :)

大多数人都会同意,Joda是一个非常用户友好的库。例如,我之前从未使用Joda进行过这种解析,但是我花了几分钟才从API中弄清楚并编写它。

更新(2015)

如果您使用 Java 8 ,在大多数情况下,您应该只使用java.time而不是Joda-Time。它包含来自Joda的几乎所有好东西 - 或它们的等价物。对于那些已经熟悉Joda API的人来说,Stephen Colebourne的Joda-Time to java.time migration guide会派上用场。

以下是上述示例的java.time版本。

解析#1:

DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.from(f.parse("2012-01-10 23:13:26"));

你无法将其解析为ZonedDateTime或OffsetDateTime(它们是Joda的DateTime的对应部分,在我的原始答案中使用),但这种情况有意义,因为解析后的字符串中没有时区信息。

解析#2:

DateTimeFormatter f = DateTimeFormatter.ofPattern("MMMM dd, yyyy");
LocalDate localDate = LocalDate.from(f.parse("January 13, 2012"));

这里LocalDate是最适合解析的类型(就像使用Joda-Time一样)。

答案 1 :(得分:23)

SimpleDateFormat将日期解析为Java Date对象:

http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html

SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // first example
SimpleDateFormat format2 = new SimpleDateFormat("MMMMM dd,yyyy"); // second example

Date d1 = format1.parse( dateStr1 );
Date d2 = format2.parse( dateStr2 );

答案 2 :(得分:7)

我认为Joda会为你做一些Formatter。我通过快速谷歌搜索找到了这个:http://johannburkard.de/blog/programming/java/date-time-parsing-formatting-joda-time.html

DateTimeFormatter parser1 =
    DateTimeFormat.forPattern("dd/MMM/yyyy:HH:mm:ss Z");

DateTimeFormatter parser2 =
    DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");

DateTime time = parser1.parseDateTime("<data>");

可以在X-Zero's link中找到用于评估模式的语法。

答案 3 :(得分:4)

JodaTime在很大程度上被认为是Java中日期时间处理的事实标准 - 他们正在努力将它添加到下一版本的Java库中(好吧,有效)。

为了从字符串中获取JodaTime日期,您将需要查看DateTimeFormat类。

答案 4 :(得分:2)

最简单的方法是按照您期望的格式正确设置SimpleDateFormat,并使用其解析方法为您提供Date对象

答案 5 :(得分:1)

TL;博士

LocalDateTime ldt = LocalDateTime.parse( "2012-01-10 23:13:26".replace( " " , "T" ) );

...和...

LocalDate localDate = LocalDate.parse ( "January 13, 2012" , DateTimeFormatter.ofLocalizedDate ( FormatStyle.LONG ).withLocale ( Locale.US ) );

详细

Answer by Jonik基本上是正确的,但遗漏了一些重要问题。

java.time

  

如果有比Joda更好的东西,请告诉我。

是的,有一些更好的,java.time框架。 Joda-Time团队建议迁移到java.time作为其继任者。

java.time框架内置于Java 8及更高版本中。这些类取代了旧的麻烦日期时间类,例如java.util.Date.Calendar和&amp; java.text.SimpleDateFormat

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。

大部分java.time功能都被反向移植到Java 6&amp; ThreeTen-Backport中的7,并在ThreeTenABP中进一步适应Android。

日期 - 时间

您的第一个输入是日期加上一个时间。它没有任何offset-from-UTCtime zone信息,因此我们将其解析为LocalDateTime对象。 “Local ...”表示任何位置,没有特定的位置。所以它不是时间轴上的实际时刻,而是一个关于片刻的粗略想法。

要解析输入字符串2012-01-10 23:13:26,我们可以用T替换中间的SPACE,以符合ISO 8601标准格式的日期时间值的规范样式。

在解析和生成日期时间值的文本表示时,java.time类默认使用ISO 8601格式。所以不需要定义解析模式。

String input = "2012-01-10 23:13:26".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );

如果从该值的上下文中知道预期的时区,请应用它来定义时间轴上的实际时刻。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );

转储到控制台。

System.out.println ( "input: " + input + " | zdt: " + zdt );
  

输入:2012-01-10T23:13:26 | zdt:2012-01-10T23:13:26-05:00 [美国/蒙特利尔]

日期仅

您输入的第二个是仅限日期的值,没有时间和没有时区。为此,我们需要LocalDate类。

我认为该输入的格式符合美国的语言(英语)和文化规范。因此无需明确指定格式化模式。我们可以通过指定Locale来询问格式化程序,该格式化程序知道美国格式。我们根据此格式的长度指定FormatStyle.LONG

String input = "January 13, 2012";
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate ( FormatStyle.LONG ).withLocale ( Locale.US );
LocalDate localDate = LocalDate.parse ( input , formatter );

转储到控制台。

System.out.println ( "input: " + input + " | localDate: " + localDate );
  

输入:2012年1月13日| localDate:2012-01-13