Warm tip: This article is reproduced from serverfault.com, please click

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

(其他 - How to localize timestamps in an Android app using Java?)

发布于 2020-12-01 10:47:57

我正在开发一个应用程序,用户可以在该应用程序中从工作场所输入自己的进出时间戳。目前,我正在尝试完成时间戳的本地化。例如,当我在UTC +02:00于2020年2月1日08:00进行时间戳记时,它可以正常工作并将时间显示为08:00和正确的日期。但是,当我在手机设置中将其更改为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类和“ toInstant”(即时类)用于我想实现?什么是正确的解决方案?

Questioner
Dee9
Viewed
11
Ole V.V. 2020-12-04 04:26:28

偏移时间

我不明白+02:00你的字符串中的偏移量表示什么。特别是,当偏移量更改时,它会使我困惑。无论如何,现代的Java日期和时间API java.time都可以很轻松地解析和格式化你的时间。让我们首先定义描述所需输出格式的格式化程序:

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则是使用的正确类,同样,我们也不需要显式格式化程序来进行解析(仅用于格式化)。你在注释中的代码很好(除了你不小心颠倒了字符串中的日,月和年的顺序)。

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

2020年5月12日

你的代码出了什么问题?

看来你太过复杂了。特别是你混合了旧的和现代的日期时间类。老式的DateSimpleDateFormat,设计得很差且混乱,无疑会给你带来意想不到的结果。而且,在进行混合时,你将需要工作中真正不需要的转换,这只会使你的代码变得比所需的更为复杂。

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