localTimeDate公式转换

localTimeDate formula conversion

我遇到了以下公式,其中从 TimeStamp 和 Timezone 检索 localTimeDay:

long localTimeDay = (timeStamp + timeZone) / (24 * 60 * 60 * 1000) * (24 * 60 * 60 * 1000);

我无法理解 Local Time Day 的含义以及此公式 "magically" 如何基于 TS 和 TZ 进行转换。

  • timestamp 是自 1970 年 1 月 1 日 00:00 UTC 纪元以来的毫秒数。
  • timeZone 是与 UTC 的毫秒偏移量。它可以是正数、负数或零。但是,就我所见,它的符号必须颠倒才能使公式起作用:+01:00 的偏移量应为 减去 3 600 000 毫秒。当我添加偏移量时,我得到一个不同的时间点,其中 UTC 日期和时间与该 UTC 偏移量的原始日期和时间相同。
  • 除以 24 * 60 * 60 * 1000 将从纪元开始的毫秒数转换为天数。一天中的任何一小部分,即一天中的任何时间,都将被丢弃。
  • 乘以 24 * 60 * 60 * 1000 将从天转换回毫秒。由于一天中的时间被丢弃,我们现在有当天 00:00 UTC 的时间。

所以这是一种从某个 UTC 偏移量的时间点转换为 UTC 中单独表示的日期的方法。

这不是您希望在程序中包含的代码。您应该将此类转换留给经过验证的库方法。然而,它可能是可以在这样一个经过测试和验证的库中找到的代码。

编辑:为什么我认为偏移量的符号被颠倒了?难道不是相反的转换,从 UTC 到本地?变量名 localTimeDay 似乎暗示了这一点?除法和乘法仅适用于 UTC。由于纪元位于 00:00 UTC,因此该公式必然会以 UTC 为您提供一天的开始,它不能以任何非零偏移量为您提供一天的开始。因此我认为转换必须是从本地到 UTC。

如何在你的代码中做

这是使用 java.time、现代 Java 日期和时间 API

进行相同转换的好方法
    // The point in time given in UTC
    Instant time = Instant.parse("2020-04-23T05:16:45Z");
    // The UTC offset, +02:00
    ZoneOffset offset = ZoneOffset.ofHours(2);

    ZonedDateTime startOfDayInUtc = time.atOffset(offset)
            .toLocalDate()
            .atStartOfDay(ZoneOffset.UTC);
    System.out.println(startOfDayInUtc);
    long epochMillis = startOfDayInUtc.toInstant().toEpochMilli();
    System.out.println(epochMillis);

输出:

2020-04-23T00:00Z
1587600000000

我们可以检查它给出的结果是否与您的代码行相同:

    long timeStamp = time.toEpochMilli();
    // Reverse sign of offset
    long timeZone = -Duration.ofSeconds(offset.getTotalSeconds()).toMillis();
    long localTimeDay = (timeStamp + timeZone) / (24 * 60 * 60 * 1000) * (24 * 60 * 60 * 1000);

    System.out.println(localTimeDay);
    System.out.println("Agree? " + (localTimeDay == epochMillis));
1587600000000
Agree? true

编辑:您在评论中提问:

I still have this doubt: There is fixed number of millis that have elapsed since Jan 1 1970, so every country should get same number. Does localTimeDate mean "date for my country" or to the country where this data came from? For example: Country-A , Country-B; they will see same millis since Epoch. Suppose data processing is happening in Country-A and origin of data is Country-B. So when we say "localTimeDate" , does it pertain to Country-A or Country-B.

这对两国都适用。这完全取决于输入公式的 timeZone 值。如果那是国家 A 的 UTC 偏移量(符号反转),则转换将从国家 A 时间到 UTC 日期。如果是 B 国的偏移量,则转换将从 B 国时间开始。你是完全正确的,如果 A 国和 B 国的日期不同,你会得到两个不同的日期,这种情况很容易发生。