服务器上的java epoch时间转换为客户端时间

agxfikkp  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(532)

服务器正在用system.currenttimemillis()存储客户端操作的日期/时间。假设这个服务器在est时区。
法国的一位客户想知道这一行动是什么时候发生的。通过system.currenttimemillis()存储的长值(在美国服务器上)返回给法国的客户机。
我在理解如何在客户端进行转换以准确描述他们的动作时间时遇到了问题。我的理解是,在服务器上,system.currenttimemillis()是一个无区域的utc时间。当我用一个“utc”时区示例化一个日历对象时,事情看起来很奇怪,当服务器用currenttimemillis()保存时,它也存储了一个时间分区的epoch时间
第一次尝试:

String timezone = clientTimezone;//Lets say france

    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(time); //This time var is the server stored value (currentTimeMillis)

    if(!timezone.equals("")) {
        long timezoneAlteredTime = time + TimeZone.getTimeZone(timezone).getRawOffset();
        cal = Calendar.getInstance(TimeZone.getTimeZone(timezone));
        cal.setTimeInMillis(timezoneAlteredTime);
    }

其他尝试:

String timezone = clientTimezone;//Lets say france
    TimeZone utc = TimeZone.getTimeZone("UTC");
    Calendar cal = Calendar.getInstance(utc);
    cal.setTimeInMillis(time); //This time var is the server stored value 

    if(!timezone.equals("")) {
        long timezoneAlteredTime = time + TimeZone.getTimeZone(timezone).getRawOffset();
        cal = Calendar.getInstance(TimeZone.getTimeZone(timezone));
        cal.setTimeInMillis(timezoneAlteredTime);
    }

我完全误解了这个问题吗?你将如何进行这种转换

o3imoua4

o3imoua41#

java.time文件

当你知道怎么做的时候,这是非常简单的。我建议您将工作留给java.time,这是一种现代的java日期和时间api。

String clientTimezone = "Europe/Paris";
    long time = 1_607_708_578_154L;

    ZonedDateTime timeInClientTimeZone = Instant.ofEpochMilli(time)
            .atZone(ZoneId.of(clientTimezone));

    System.out.println(timeInClientTimeZone);

此示例代码段的输出为:
2020-12-11t18:42:58.154+01:00[欧洲/巴黎]

你的代码哪里出错了?

我的理解是,在服务器上,system.currenttimemillis()是一个无区域的utc时间。
到目前为止你的理解是正确的。
尽管纪元通常是用utc来定义的,但这里的线索是无区域的。所以您不需要utc中的任何日期时间对象。你也不需要对毫秒数做任何调整,这样做,你就把一个正确的时间变成了一个错误的时间。

链接

oracle教程:date time解释如何使用java.time。

edqdpe6u

edqdpe6u2#

ole v.v.的回答是正确的:打电话 Instant::atZone 将一个时刻从utc调整到一个特定的时区。时间轴上的同一点,不同的挂钟时间。
这里还有一些想法。
假设这个服务器在est时区。
仅供参考,通常最好将服务器上的时区设置为utc。
system.currenttimemillis()是无区域utc时间
不是无区域的。该方法返回自1970年第一个时刻的epoch引用以来的毫秒数,如utc所示(与utc的偏移量(0小时分秒)
如果没有utc偏移量或时区的上下文,就不能表示时间线上的某个时刻、某个特定点。
当我示例化一个日历对象时,事情看起来很奇怪
所有关于 Calendar 上课很奇怪。
这就是为什么我们几年前就不再使用那个糟糕的类了。只使用java.time类。
服务器正在用system.currenttimemillis()存储客户端操作的日期/时间。
我们有这样的课程: Instant . 所以不需要仅仅使用整数,现在可以使用类型安全且方便的类。
这个 Instant 类表示在utc中看到的一个时刻。它的物体使用纳秒的分辨率,尽管现在大多数计算机时钟可以捕捉微秒的瞬间。

Instant instant = Instant.now() ;

您可以在毫秒计数和 Instant .

Instant instant = Instant.ofEpochMilli( yourCountOfMillis ) ;

Instant 定义为utc。要从另一个偏移上看到相同的力矩,请使用 OffsetDateTime . 要查看特定时区中的同一时刻,请使用 ZonedDateTime .
要明白时区是过去、现在和将来某个特定地区的人们所使用的偏移量变化的历史。政客们经常因为各种原因改变他们管辖权的抵消。
搜索堆栈溢出以了解更多信息。这些问题已经讨论过很多次了。

相关问题