【问题标题】:Convert a date time string to Utc date time in android give an hour less在 android 中将日期时间字符串转换为 Utc 日期时间少一个小时
【发布时间】:2020-01-09 08:58:36
【问题描述】:

我有一个日期时间字符串,我需要将其转换为 UTC 格式。我使用了下面的代码。

SimpleDateFormat format = new SimpleDateFormat("MM/dd/yy HH:mm a",Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
    Date date = format.parse("09/06/19 06:39 pm");
    System.out.println(date);
    selectedDateForApi=date.toString();
} catch (ParseException e) {
    e.printStackTrace();
}

Output: Fri Sep 06 12:09:00 GMT+05:30 2019

输出比实际时间少 1 小时。 it should be Fri Sep 06 13:09:00 GMT+05:30 2019. 我做错了什么?

【问题讨论】:

  • 英国夏令时 +1 小时
  • @JakeB,请解释您的评论,以及我需要在哪里添加 +1
  • 顺便考虑扔掉长期过时且臭名昭著的麻烦SimpleDateFormat和朋友,并将ThreeTenABP添加到您的Android项目中,以便使用java.time,现代Java日期和时间API .使用起来感觉好多了。
  • @JakeB 提问者似乎没有使用 BST,无论如何问题出在其他地方。

标签: android datetime utc


【解决方案1】:

java.time 和 ThreeTenABP

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("MM/dd/yy hh:mm a")
            .toFormatter(Locale.ENGLISH);
    ZoneId zone = ZoneId.of("Asia/Kolkata");

    ZonedDateTime indiaDateTime = LocalDateTime
            .parse("09/06/19 06:39 pm", formatter)
            .atZone(zone);
    Instant utcDateTime = indiaDateTime.toInstant();
    System.out.println(utcDateTime);

这个 sn-p 的输出是:

2019-09-06T13:09:00Z

输出中尾随的Z 表示UTC。

您尝试使用的日期和时间类SimpleDateFormatTimeZoneDate 都设计得很差,而且早已过时。考虑不使用它们。相反,我使用的是现代 Java 日期和时间 API java.time。我和许多人发现它更适合使用。

我还使用了正确的时区名称,Asia/Kolkata。使用GMT+05:30 作为时区是一种糟糕且危险的方式。在您的情况下,它可能适用于二战之后的日期,直到印度政客在未来某个未知时间更改时区偏移。对于其他时区,尤其是那些使用夏令时 (DST) 的时区,您会更快地遇到错误结果。

你的代码出了什么问题?

您的代码中有两个错误。也可能是一个不可能的期望的例子。

首先,您正在执行您说想要的转换的相反转换。您想将本地时间(印度标准时间)转换为 UTC,但您告诉SimpleDateFormat字符串已经采用UTC。

其次,您在格式模式字符串MM/dd/yy HH:mm a 中使用了大写的HHHH 表示一天中从 00 到 23 的小时。由于您的字符串中有 pm,因此您应该在上午或下午从 01 到 12 的小时内使用小写的 hh。期望 @987654338 是合理的@ 在一天中的 6 小时与 pm 不一致时抛出异常,但 SimpleDateFormat 通常会给您一个不正确的结果并假装一切都很好。这只是这个类的众多问题之一。

组合错误导致您的字符串在 UTC 中被解析为 06:39 AM,这与偏移 05:30 的 12:09 PM 的时间点相同,您看到的结果.您的Date 打印在您当地的时区也可能让您感到困惑。 Date 没有时区或偏移量,Date 对象总是在 JVM 的默认时区打印。换句话说,如果您想要 UTC 格式的 Date,那是不可能的。相比之下,同样独立于时区的现代 Instant 始终以 UTC 打印,我认为这可能是您想要的。

问题:我可以在 Android 上使用 java.time 吗?

是的,java.time 在较旧和较新的 Android 设备上运行良好。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中,现代 API 是内置的。
  • 在 Java 6 和 7 中获得 ThreeTen Backport,这是现代类的后向端口(JSR 310 的 ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

链接

【讨论】:

    猜你喜欢
    • 2011-06-13
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 2012-03-15
    • 2015-09-17
    • 2014-11-18
    相关资源
    最近更新 更多