如何使用 Java 在 Android 应用程序中本地化时间戳?

How to localize timestamps in an Android app using Java?

我正在开发一款应用,用户可以在其中为自己在工作场所的进出时间打上时间戳。目前我正在尝试完成时间戳的本地化。例如,当我在 08:00 02.01.2020 以 UTC +02:00 制作时间戳时,它可以正常工作并将时间显示为 08:00 和正确的日期。但是,当我在 phone 设置中更改为 UTC +01:00,并执行相同的时间戳时,时间变为 07:00,日期变为 01.01.2020.

我目前“解析”时间的代码如下所示:

String formattedTime = "";

String datetime2 = "1970-01-01T" + returntime;
Log.v("DATE", datetime2);
OffsetDateTime odt2 = OffsetDateTime.parse(datetime2);
Date date2 = Date.from(odt2.toInstant());

SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm",Locale.getDefault());
formattedTime = sdf2.format(date2);
Log.v("FORMTIME", formattedTime);

我也在使用类似的代码片段来“解析”日期。 两个日志的输出(在 UTC +01:00 时):

V/DATE: 1970-01-01T15:00:00+02:00
V/FORMTIME: 14:00 //SHOULD BE 15:00
V/DATE: 1970-01-01T08:00:00+02:00
V/FORMTIME: 07:00  //SHOULD BE 08:00
V/DATE: 1970-01-01T08:00:00+02:00
V/FORMTIME: 07:00  //SHOULD BE 08:00

似乎 UTC 的变化从 +02:00 到 +01:00 也将时间和日期减少了 1... 那么使用 OffsetDateTime class 和“toInstant”(Instant class)来实现我想要实现的目标是错误的吗?什么是正确的解决方案?

偏移时间

我不明白你的字符串中 +02:00 的偏移量是什么意思。特别是当偏移量发生变化时,它让我很困惑你想做什么。在任何情况下 java.time,现代 Java 日期和时间 API,都非常容易解析和格式化您的时间。让我们首先定义描述您所需输出格式的格式化程序:

private static final DateTimeFormatter timeFormatter
        = DateTimeFormatter.ofPattern("HH:mm");

有了这个你可以做:

    String returntime = "15:00:00+02:00";
    OffsetTime time = OffsetTime.parse(returntime);
    String formattedTime = time.format(timeFormatter);
    System.out.println(formattedTime);

输出:

15:00

偏移量已解析,但未用于任何用途。输出时间将始终与字符串中的时间相同。

我认为您在代码中使用的日期 1970-01-01 是任意的,没有意义。我用的OffsetTime没有日期,所以不用选择日期来处理时间。

用词:这里没有任何本地化。例如,本地化是针对美国观众打印 3:00 PM 而不是 15:00。

编辑:

如果您的字符串也包含日期,OffsetDateTime 是正确的 class 使用,同样我们不需要明确的格式化程序来解析(仅用于格式化)。您在评论中的代码没有问题(除了您不小心颠倒了字符串中日、月和年的顺序)。

    String returnDate1 = "2020-12-05T00:00+02:00";
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
    OffsetDateTime dateTime = OffsetDateTime.parse(returnDate1);
    String formattedDate = dateTime.format(dateFormatter);
    
    System.out.println(formattedDate);

05-12-2020

你的代码出了什么问题?

看来你把事情复杂化了。特别是你混合了旧的和现代的日期时间 classes。旧的 DateSimpleDateFormat 设计不佳且令人困惑,这无疑导致了您意想不到的结果。混合时,您将需要对您的工作而言并非真正需要的转换,这只会让您的代码比需要的更复杂。

您的 sdf2 正在使用您的默认时区打印时间。您在字符串中有偏移量 +02:00,因此当您将 phone 设置为 UTC+01:00 时,会发生转换。当偏移量 +02:00 处的时间为 08:00 时,偏移量 +01:00 处的时间仅为 07:00。这就是你得到的结果。这反过来意味着如果用户的时区偏移量为 1970-01-01 的 +01:00,那么您将获得该时区的正确时间。