将字符串解析为日期时间不会返回正确的时间 [英] Parsing a string to a datetime does not return the correct time
问题描述
在Android系统中,由于以下代码超时,我预计下午3:12,但下午4:12.解析此日期时间格式的正确方法是什么?
In Android...I am expecting 3:12 pm as time out put of the following code but I get 4:12 pm. Whats the correct way to parse this date time format.
String dt = "2018-09-02T19:12:00-0400";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
try {
Date date = dateFormat.parse(dt);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
推荐答案
时区
最好明确指定要在哪个时区输出:
Time zone
It’s best to specify explicitly in which time zone you want your output:
DateTimeFormatter inputFormatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXX");
DateTimeFormatter displayFormatter = DateTimeFormatter
.ofLocalizedDateTime(FormatStyle.LONG)
.withLocale(Locale.ENGLISH);
ZoneId displayZone = ZoneId.of("Pacific/Pitcairn");
String dt = "2018-09-02T19:12:00-0400";
OffsetDateTime dateTime = OffsetDateTime.parse(dt, inputFormatter);
String displayDateTime = dateTime.atZoneSameInstant(displayZone)
.format(displayFormatter);
System.out.println(displayDateTime);
此打印:
2018年9月2日,太平洋标准时间下午3:12:00
September 2, 2018 at 3:12:00 PM PST
我在代码中使用了太平洋/皮特凯恩时区,但您更了解自己想要的时区.
I have used Pacific/Pitcairn time zone in my code, but you know better which time zone you want.
我还使用了现代Java日期和时间API java.time.您使用的日期时间类 SimpleDateFormat
和 Date
被认为已经过时了,并且java.time更好用.
I am also using java.time, the modern Java date and time API. The date-time classes you are using, SimpleDateFormat
and Date
, are considered long outdated, and java.time is so much nicer to work with.
您解析日期字符串的方法是正确的,并产生正确的 Date
.
Your way of parsing your date string is correct and produces the correct Date
.
在打印 Date
时,您将隐式调用 toString
.过时的 Date
类具有一个奇怪且令人困惑的 toString
方法:它获取JVM的时区设置并将其用于生成字符串.因此,根据您的默认时区,您可以获得一天中的任何时间.因此,看来您的JVM的时区设置与您期望的不符.
When printing the Date
, you are implicitly calling toString
. The outdated Date
class has a peculiar and confusing toString
method: it grabs the JVM’s time zone setting and uses it for producing the string. So depending on your default time zone, you can get any hour of day in the output. So it seems your JVM’s time zone setting didn’t correspond to what you had expected.
由于您希望从19:12:00-0400的输入中获得3:12 PM,所以我认为您想要的时区与9月的UTC偏移-08:00.例如,如果您的默认时区为America/Los_Angeles,其标准时间为-08:00,则您会得到 Sun Sep 02 16:12:00 PDT 2018
,因为夏令时(夏令时时间)于9月在加利福尼亚生效,因此偏移量为-07:00.
Since you expected 3:12 PM from your input of 19:12:00-0400, I take it that you want a time zone that is at offset -08:00 from UTC in September. If for example your default time zone was America/Los_Angeles, the standard time of which is at -08:00, you would get Sun Sep 02 16:12:00 PDT 2018
because summer time (daylight saving time) is in effect in California in September, so the offset is -07:00.
依赖JVM的默认时区总是很脆弱,因为该程序的其他部分或运行在同一JVM中的其他程序可能会随时更改设置.
Relying on your JVM’s default time zone is always fragile since the setting may be changed at any time by other parts of your program or by other programs running in the same JVM.
是的, java.time
在较新的Android设备上都能很好地工作.它只需要至少Java 6 .
Yes, java.time
works nicely on older and newer Android devices. It just requires at least Java 6.
- 在Java 8和更高版本以及较新的Android设备(我听说API级别为26)上,内置了现代API.
- 在Java 6和7中,获取ThreeTen反向端口,即新类的反向端口(JSR 310的ThreeTen;请参见底部的链接).
- 在(较旧的)Android上,请使用Android版的ThreeTen Backport.称为ThreeTenABP.并确保使用子包从
org.threeten.bp
导入日期和时间类.
- In Java 8 and later and on newer Android devices (from API level 26, I’m told) the modern API comes built-in.
- In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
- On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from
org.threeten.bp
with subpackages.
- Oracle教程:日期时间解释了如何使用
java.时间
. - Java规范请求(JSR)310 ,其中
java首先描述了.time
. - ThreeTen Backport项目,即
java.time
的反向端口Java 6和7(JSR-310的ThreeTen). - ThreeTenABP ,ThreeTen Backport的Android版本
- 问题:如何在Android Project中使用ThreeTenABP ,非常详尽的解释.
- Oracle tutorial: Date Time explaining how to use
java.time
. - Java Specification Request (JSR) 310, where
java.time
was first described. - ThreeTen Backport project, the backport of
java.time
to Java 6 and 7 (ThreeTen for JSR-310). - ThreeTenABP, Android edition of ThreeTen Backport
- Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
这篇关于将字符串解析为日期时间不会返回正确的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!