我有一个使用JavaScript运行的客户端应用。以及使用Java运行的服务器应用程序。
当客户端执行某个操作时,我使用Date.getTime()
记录完成的时间,然后将其发送回服务器。
在某个地方,我想计算自用户执行该操作到现在已经过了多长时间 - 我想在服务器端进行此计算。
我的问题 - 我在服务器当前时间和动作完成时间之间的差异很大,很大。可能是因为时差。
我希望无论客户端或服务器实际位于何处,这种计算都是正确的。我知道我应该使用GMT / UTC时间,但我找不到正确的方法。
答案 0 :(得分:1)
正如Pointy所说,信任客户端机器的时钟是不明智的。在你的情况下没有必要。
你的第二句话:
当客户端执行某个操作时,我使用Date.getTime()记录完成的时间,然后将其发送回服务器。
......倒退了。服务器端应用程序应该驱动日志记录,并将事实发送给客户端。
在服务器端,在Java中,使用Joda-Time捕获UTC time。将该日期时间保存为数据库的本机日期时间格式或ISO 8601格式化字符串。不建议存储毫秒,因为您需要知道或记录epoch中的毫秒数 - 大多数人都假设是Unix纪元,但并非所有系统和软件都使用它。
在客户端,从服务器向客户端发送一个字符串,用于描述用户本地时区的日期时间。您需要能够获得用户的时区。大多数Web浏览器和Web框架都可以为您提供。
继续阅读本位于美国西雅图的服务器示例,其中一位用户居住在意大利罗马。
从您可信赖的时钟获取当前日期时间:服务器计算机的时钟。
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
org.joda.time.DateTime now = new org.joda.time.DateTime(); // Using host system's clock and default time zone.
org.joda.time.DateTime utc = now.toDateTime( org.joda.time.DateTimeZone.UTC );
System.out.println( "Server's default local time in ISO 8601 format: " + now );
System.out.println( "UTC (Zulu) time zone: " + utc );
跑步时......
Server's default local time in ISO 8601 format: 2013-11-08T19:50:56.990-08:00
UTC (Zulu) time zone: 2013-11-09T03:50:56.990Z
当需要向用户显示该日期时间时,请将其转换为用户的本地时区。
默认情况下,Joda-Time会转换为ISO 8601格式的String。但是您可以使用格式化程序来创建所需的任何字符串。
如果您想将java.util.Date对象传递给您的网络框架,可以convert between Joda-Time and Date。
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
org.joda.time.DateTimeZone romeTimeZone = org.joda.time.DateTimeZone.forID("Europe/Rome");
org.joda.time.DateTime userDateTime = utc.toDateTime( romeTimeZone );
System.out.println( "In User's time zone: " + userDateTime );
跑步时......
In User's time zone: 2013-11-09T04:50:56.990+01:00
关于Joda-Time及相关问题:
// Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
// http://www.joda.org/joda-time/
// Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
// JSR 310 was inspired by Joda-Time but is not directly based on it.
// http://jcp.org/en/jsr/detail?id=310
// By default, Joda-Time produces strings in the standard ISO 8601 format.
// https://en.wikipedia.org/wiki/ISO_8601
// About Daylight Saving Time (DST): https://en.wikipedia.org/wiki/Daylight_saving_time
// Time Zone list: http://joda-time.sourceforge.net/timezones.html
提示:时区定义经常变化且不合理。用户的记忆频繁且不合理地改变。如果您的业务在事实上记录用户的感知时间非常重要,那么请完成上面讨论的工作,但还记录用户的时区标识符和服务器的时间,如用户所在的时区(你是什么时候)将作为当地时间发送给用户。
答案 1 :(得分:0)
要获得UTC时间,可以使用(Gregorian)Calendar类:
Calendar cal = new GregorianCalendar();
System.out.println("UTC ms from the epoch: " + cal.getTimeInMillis());