正如 Pointy 所说,信任客户端计算机的时钟是不明智的。在你的情况下是不必要的。
你的第二句话:
当客户端执行某个操作时,我使用 Date.getTime() 记录它完成的时间,并将其发送回服务器。
……倒退了。服务器端应用程序应该驱动日志记录,并将事实发送给客户端。
在服务器端,在 Java 中,使用Joda-Time来捕获UTC 时间。将该日期时间保存为数据库的本机日期时间格式或ISO 8601格式的字符串。存储毫秒是不可取的,因为您需要知道或记录从哪个纪元开始的毫秒数——大多数人假设 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 );
运行时……</p>
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 格式的字符串。但是您可以使用格式化程序来创建您想要的任何字符串。
如果您想将java.util.Date对象传递给您的 Web 框架,您可以在 Joda-Time 和 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 );
运行时……</p>
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
提示:时区定义频繁且不合理地更改。用户的记忆变化频繁且不合理。如果在您的业务中实际记录用户的感知时间很重要,那么请执行上面讨论的工作,但还要记录用户的时区标识符和用户时区中的服务器时间(您将发送给用户的时间为他们的当地时间)。