4

我有一个使用 JavaScript 运行的客户端应用程序。和一个使用 Java 运行的服务器应用程序。当客户端执行某个操作时,我Date.getTime()会记录它完成的时间,并将其发送回服务器。在路上的某个地方,我想计算从用户执行该操作到现在已经过去了多少时间 - 我想在服务器端进行这个计算。

我的问题-服务器的当前时间和操作完成的时间之间的差异很大,很大。可能是因为时差。

无论客户端或服务器实际在哪里,我都希望这个计算通常是正确的。我知道我应该使用 GMT/UTC 时间,但我找不到正确的方法。

4

2 回答 2

0

要获取 UTC 时间,可以使用(公历)日历类:

Calendar cal = new GregorianCalendar();
System.out.println("UTC ms from the epoch: " + cal.getTimeInMillis());
于 2013-11-03T15:43:50.753 回答
0

正如 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

提示:时区定义频繁且不合理地更改。用户的记忆变化频繁且不合理。如果在您的业务中实际记录用户的感知时间很重要,那么请执行上面讨论的工作,但还要记录用户的时区标识符和用户时区中的服务器时间(您将发送给用户的时间为他们的当地时间)。

于 2013-11-09T03:56:27.933 回答