将日期时间字符串转换为 android 中的 Utc 日期时间,减少一小时

Convert a date time string to Utc date time in android give an hour less

我有一个日期时间字符串,我需要将其转换为 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. 我做错了什么?

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);

此片段的输出是:

2019-09-06T13:09:00Z

输出中的尾部 Z 表示 UTC。

您尝试使用的日期和时间 classes,SimpleDateFormatTimeZoneDate,设计不佳且早已过时。考虑不使用它们。相反,我使用 java.time,现代 Java 日期和时间 API。我和许多人都觉得它更好用。

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

你的代码出了什么问题?

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

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

其次,您在格式模式字符串 MM/dd/yy HH:mm a 中使用大写字母 HHHH 表示从 00 到 23 的一天中的小时。由于字符串中有 pm,因此您应该使用小写 hh 表示从 01 到 12 的 AM 或 PM 中的小时。它应该有当第 6 天的小时与下午不一致时,期望 SimpleDateFormat 抛出异常是合理的,但通常 SimpleDateFormat 给你一个错误的结果并假装一切都很好。这只是这个 class.

的众多麻烦之一

组合错误导致您的字符串在 UTC 中被解析为 06:39 AM,这与 12:09 PM 在同一时间点offset 05:30,你看到的结果。您可能还对您的 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,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接