【问题标题】:Saving date time for all time zones in java在java中保存所有时区的日期时间
【发布时间】:2016-04-16 15:06:45
【问题描述】:

我有一个应用程序,用户可以在其中创建问题,而其他人可以 用它查看日期时间(创建问题的时间)。现在我得到了 服务器日期时间并将其保存在数据库中,但问题是应用程序被使用 居住在时差为 6-7 小时的国家/地区的人。 一个小例子是我住在某个国家,我在晚上 7:00 创建问题,但在美国的时间是上午 11 点(只是猜测)。所以用户立即检索问题,但对他来说,提问时间应该是上午 11 点而不是晚上 7 点。那么如何保存日期时间,以便所有时区都相同。我有点困惑 所以我需要一点帮助。我知道它与 UTC 日期时间有关,但可以 有人详细说明了这一点:)。谢谢你

【问题讨论】:

  • 日期没有时区。只有日期表示有。您自己存储日期,当您显示它时,您根据区域设置应用时区。

标签: java android


【解决方案1】:

将当前时间与 UTC 1970 年 1 月 1 日午夜的epoch 之间的差值(以毫秒为单位)存储到您的数据库中。您可以拨打System.currentTimeMillis()获取。

一旦你有了它,你可以在任何你想要的Time Zone中提供时间,这里有一个简单的代码sn-p,它显示了我机器上可用的all the time zones中的时间。

此代码使用 Java 8 及更高版本中内置的 java.time 框架。 back-ported to Java 6 & 7to Android 也提供了大部分此类功能。

long time = System.currentTimeMillis();
Instant instant = Instant.ofEpochMilli(time);
ZoneId.getAvailableZoneIds().stream().forEach(id -> {
        ZoneId zId = ZoneId.of(id);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zId);
        System.out.printf(
            "The current time in %s is %s%n",  
            zId, localDateTime.format(DateTimeFormatter.ISO_DATE_TIME)
        );
    }
);

这是旧版本 Java 的等效项:

long time = System.currentTimeMillis();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);
for (String id : TimeZone.getAvailableIDs()) {
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    formatter.setTimeZone(TimeZone.getTimeZone(id));
    System.out.printf(
        "The current time in %s is %s%n",  id, formatter.format(cal.getTime())
    );
}

响应更新:

由于您想保留原始 TimeZone,您还必须将时区 ID 以 伪标准格式 GMT+/-mm:ss 存储到您的数据库中。

为此,首先您需要获取与 UTC 时间相比的增量(在 tz 下面的代码 sn-p 中是我当前的时区):

int offsetFromUTC = tz.getOffset(time);

然后您可以将这个增量(以毫秒为单位)转换为预期的时区 ID,可以这样完成:

String timeZoneId = String.format(
    "GMT%+02d:%02d", offsetFromUTC / (60 * 60 * 1000), offsetFromUTC / (60 * 1000) % 60
);

timeZoneId 的值是您必须存储到数据库中的第二个值。使用这两个值,您可以以任何预期的格式显示时间,例如:

Calendar cal = Calendar.getInstance();
// Here I use the time retrieved from the DB
cal.setTimeInMillis(time);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
// Here I use the time zone id retrieved from the DB
TimeZone tz = TimeZone.getTimeZone(timeZoneId);
formatter.setTimeZone(tz);
System.out.printf("The current time in %s is %s%n",  id, formatter.format(cal.getTime()));

【讨论】:

  • 我不能同时导入 Instant 和 zoneid 类,这意味着我必须使用库吗? .但我不想使用图书馆
  • 它是Java 8的一部分,你用的是哪个版本的Java?
  • @SyedMuhammadOan 我更新了对以前版本 Java 的回答
  • 好的,我明白代码中发生了什么,但我还是不明白,我应该在数据库中保存什么时间?以及当我使用我的安卓应用程序时如何转换那个时间。那是我的实际问题。
  • 您应该将 System.currentTimeMillis() 返回的 long 返回的值存储到数据库中
【解决方案2】:

那么我怎样才能保存日期时间,以便所有时区都一样

您应该使用 UTC 来存储您的日期,因此如果有人在 +1 时区使用您的应用,您需要先将其转换为 UTC。时区应该只用于向用户显示时间。

【讨论】:

  • 或者只存储完整日期+时区;您可以随心所欲地转换到任何时区。如果您使用 Joda Time,它会特别容易
  • 你的意思是我应该将 utc 日期保存在数据库中并在我的 android 应用程序中转换它?
  • 是的。使用时区仅向用户显示“本地”时间。因此,如果他/她因为旅行而更改时区,您仍然会在 TZ 中显示正确的时间,那么他/她将是
猜你喜欢
  • 2020-12-03
  • 1970-01-01
  • 2013-04-04
  • 2013-08-10
  • 1970-01-01
  • 2021-08-16
  • 1970-01-01
  • 2018-12-25
  • 1970-01-01
相关资源
最近更新 更多