无法解析的日期:“2014年1月29日上午11:45:00” - Android

时间:2014-01-15 14:45:39

标签: java android simpledateformat

我在从字符串解析以下日期时遇到问题:“2014/1/29 11:45:00” 我这样做的方式如下:

String source = "1/29/2014 11:45:00 AM";
Date startDate;
String sdfPattern = "MM/dd/yyyy hh:mm:ss aa";
SimpleDateFormat sdf = new SimpleDateFormat(sdfPattern, Locale.getDefault());
sdf.setTimeZone(TimeZone.getTimeZone("Europe/London"));
this.startDate = sdf.parse(source);

有趣的是,这在java项目中工作正常,但在android中却没有。我收到的错误消息:

01-15 15:36:46.950: W/System.err(2713): java.text.ParseException: Unparseable date: "1/29/2014 11:45:00 AM" (at offset 19)

有谁能告诉我我做错了什么?

3 个答案:

答案 0 :(得分:6)

您的格式字符串指定您将提供两位数的月份,但您只提供“1”。

我怀疑你想要:

String sdfPattern = "M/d/yyyy hh:mm:ss aa";

此外,“AM / PM”指示符对语言环境敏感(日期和时间分隔符也是如此)。如果您知道它将始终使用英语,您应该这样说:

SimpleDateFormat sdf = new SimpleDateFormat(sdfPattern, Locale.US);

除非用户实际输入数据(或为用户格式化),否则应避免使用Locale.getDefault()

答案 1 :(得分:1)

您的默认语言环境可能与导致异常的输入String中的AM / PM标记不匹配。尝试使用

SimpleDateFormat sdf = new SimpleDateFormat(sdfPattern, Locale.ENGLISH);

答案 2 :(得分:0)

java.time

问题和其他答案使用与最早版本的Java捆绑在一起的麻烦的旧遗留日期时间类。现在取代了java.time类。

ISO 8601

顺便说一下,在生成字符串时使用ISO 8601格式来表示与其他软件交换的日期时间值。与标准格式不同,您的格式模糊且难以解析。

DateTimeFormatter

java.time.DateTimeFormatter中定义格式设置模式的代码类似于过时的SimpleDateFormat但不完全相同。所以仔细阅读文档。

String input = "1/29/2014 11:45:00 AM";

Locale locale = Locale.ENGLISH;  // For translating the “AM” & “PM”.
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "M/d/uuuu hh:mm:ss a" ).withLocale( locale );

LocalDateTime

您的输入缺少任何偏离UTC或时区的指示。因此我们将其解析为LocalDateTime对象。

LocalDateTime ldt = LocalDateTime.parse ( input , f );
  

ldt.toString():2014-01-29T11:45

LocalDateTime对象故意缺少任何offset-from-UTC或时区。这意味着它代表时间轴上的一个时刻,只是对可能时刻的粗略想法。您必须指定偏移量或时区以赋予其含义。

OffsetDateTime

如果您的建议的上下文表明此输入意图位于UTC,请应用常量ZoneOffset.UTC以获得OffsetDateTime

OffsetDateTime odt = ldt.atOffset ( ZoneOffset.UTC );
  

odt.toString():2014-01-29T11:45Z

ZonedDateTime

另一方面,如果上下文指示特定时区,请应用ZoneId获取ZonedDateTime。问题似乎表明Europe/London时区是有意的。请注意,此时区UTC相同。

ZoneId z = ZoneId.of ( "Europe/London" );
ZonedDateTime zdt = ldt.atZone ( z );
  

zdt.toString():2014-01-29T11:45-05:00 [美国/蒙特利尔]

关于java.time

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

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

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

大部分java.time功能都被反向移植到Java 6& ThreeTen-Backport中的7,并进一步适应Android中的ThreeTenABP(见How to use…)。

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter等。