【问题标题】:Time difference between Dates Java?日期Java之间的时差?
【发布时间】:2020-08-21 20:06:48
【问题描述】:

我一直在使用旧版 Date API 以 yyyyMMdd'T'HHmmss 格式计算两次之间的时差。

客户端在请求中设置requestExpirationTime 属性,服务器进行验证检查以确保“RequestExpirationTime 不早于当前系统时间”。

客户:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
Timestamp originatingTimestamp = new Timestamp(new Date().getTime());

// duration is offset 5minutes for exmaple

Timestamp requestExpirationTimestamp = new Timestamp(originatingTimestamp.getTime() + duration); 
request.setRequestExpirationTimestamp(simpleDateFormat.format(requestExpirationTimestamp));

服务器:

try {
        Date systemTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss");

        String ret = request.getRequestExpirationTimestamp();
        if (ret != null) {
            Date requestExpirationTimestamp = sdf.parse(ret);
            if (requestExpirationTimestamp.before(systemTime)) {                    

            logger.info("Request timedout: RequestExpirationTime is before current system time");

                }
            }
        }

此代码存在问题,因为服务器上的 systemTime 采用 IST(印度标准时间),而客户端可以发送任何 UTC/IST。

我现在已迁移到 Java 8,因此我可以将旧版 Date Api 保留在 Java 中。

如何确保此类时区问题不会出现在我的代码中?我尝试设置 timeZone 服务器上的 SimpleDateFormat,但 new Date() 在不同服务器上的行为不同。

感谢任何帮助。

【问题讨论】:

  • 考虑使用新的日期和时间 API(ZonedDateTime 或 Instant)和 Jackson (JSON) 或 JAXB (XML) 等框架来编组和解组日期。
  • 如果客户端以yyyyMMdd'T'HHmmss 格式发送日期,您将无法知道时区或时间偏移量是多少。您需要在客户端使用包含时区或时间偏移的格式。

标签: java date java-8 timestamp java-time


【解决方案1】:

当客户端发送的时间不是 UTC 时,例如印度标准时间 (IST),而服务器不知道客户端使用的时区,则服务器无法使其正常工作.相反,我建议您确保客户端始终以 UTC 格式发送时间。

客户

确保您始终以 UTC 格式发送时间:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmss");

    String requestExpirationTime = OffsetDateTime.now(ZoneOffset.UTC)
            .plusMinutes(5)
            .format(formatter);

    System.out.println(requestExpirationTime);

刚才运行的示例输出:

20200506T183409

服务器

现在服务器知道时间是 UTC。我假设它使用的格式化程序与客户端使用的格式化程序相同。

    OffsetDateTime dateTime = LocalDateTime.parse(requestExpirationTime, formatter)
            .atOffset(ZoneOffset.UTC);
    OffsetDateTime systemTime = OffsetDateTime.now(ZoneOffset.UTC);
    if (dateTime.isBefore(systemTime)) {
        System.out.println("Request timedout: RequestExpirationTime is before current system time");
    } else {
        System.out.println("OK");
    }

好的

提示

您可以将Z 附加到您的时间戳字符串中,以明确表示它是UTC。它可能会在以后防止一些错误。

20200506T183409Z

【讨论】:

  • 如果客户端在 IST 或任何其他时区发送时间,那么上面的逻辑将不起作用?
  • 宾果游戏,@SiddharthTrikha,这就是问题的核心:如果客户端发送的时间不是 UTC,而服务器不知道客户端使用的是哪个时区,那么服务器就什么也没有可以做以使其正常工作。这就是为什么我建议您确保客户端始终以 UTC 发送时间。
  • 是的,除非我们在当前日期格式“yyyyMMddTHHmmss”中包含时区
猜你喜欢
  • 2012-06-26
  • 2012-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多