将字符串解析为日期时间不会返回正确的时间 [英] Parsing a string to a datetime does not return the correct time

查看:129
本文介绍了将字符串解析为日期时间不会返回正确的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆