我正在一个读取文件和处理数据的项目中工作。在那里,我开始使用日期,例如:
我找到了包Joda,有点有趣的包但不知道它是否是最简单的。
我能够将第一个示例解析为DateTime对象(Joda)reg-ex和String操作。 (例如:用' - '替换空格并将其传递给构造函数。
new DateTime("2012-01-10 23:13:26".replace(' ', '-'))
我猜它有用,但问题在于第二种格式。如何使用这样的输入来提取对象,最好是Joda对象。我确定可以编写一个函数来将格式更改为Joda支持的格式,但是想知道是否会有其他方式(甚至是一些本机Java库)来完成它。
如果有比Joda更好的东西,请告诉我。
谢谢。
答案 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中弄清楚并编写它。
如果您使用 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)
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基本上是正确的,但遗漏了一些重要问题。
如果有比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-UTC或time 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