我在从字符串解析以下日期时遇到问题:“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)
有谁能告诉我我做错了什么?
答案 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捆绑在一起的麻烦的旧遗留日期时间类。现在取代了java.time类。
顺便说一下,在生成字符串时使用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 8及更高版本中。这些类取代了麻烦的旧日期时间类,例如java.util.Date
,.Calendar
和& java.text.SimpleDateFormat
。
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
等。