服务器正在使用System.currentTimeMillis((存储客户端操作的日期/时间。假设此服务器位于EST时区。
法国的一位客户想知道这一行动是什么时候进行的。通过System.currentTimeMillis(((在美国服务器上(存储的长值将返回到法国的客户端。
我在理解如何在客户端进行转换以准确描述他们的行动时间方面遇到了问题。我的理解是,在服务器上,System.currentTimeMillis((是一个无区域的UTC时间。当我用一个";UTC";时区,存储时区epoch时间的服务器在使用currentTimeMillis((保存时也是如此
第一次尝试:
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);
}
我是不是完全误解了这个问题?你将如何进行这种转换
Ole V.V.的回答是正确的:调用Instant::atZone
将UTC的某个时刻调整到特定时区。时间线上的同一点,不同的挂钟时间。
这里还有一些想法。
假设此服务器位于EST时区。
仅供参考,通常最好将UTC设置为服务器上的时区。
System.currentTimeMillis((是一个无区域UTC时间
并非无区域。该方法返回自1970年第一个时刻的历元引用(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
。
要明白,时区是特定地区人民使用的偏移量的过去、现在和未来变化的历史。出于各种原因,政客们经常改变他们管辖权的抵消。
搜索堆栈溢出以了解更多信息。这些问题已经被多次提及。
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教程:日期时间解释如何使用java.Time.