Java localTimeDate公式转换

Java localTimeDate公式转换,java,timestamp,timezone,epoch,Java,Timestamp,Timezone,Epoch,我遇到了以下公式,其中localTimeDay是从时间戳和时区检索的: long localTimeDay = (timeStamp + timeZone) / (24 * 60 * 60 * 1000) * (24 * 60 * 60 * 1000); 我无法理解当地时间日的含义,以及该公式如何“神奇地”基于TS和TZ进行转换。 timestamp是自1970年1月1日00:00 UTC开始的毫秒计数 时区是以毫秒为单位的UTC偏移量。它可以是正、负或零。不过,就我所见,它的符号必须颠倒,公

我遇到了以下公式,其中localTimeDay是从时间戳和时区检索的:

long localTimeDay = (timeStamp + timeZone) / (24 * 60 * 60 * 1000) * (24 * 60 * 60 * 1000);
我无法理解
当地时间日
的含义,以及该公式如何“神奇地”基于TS和TZ进行转换。

  • timestamp
    是自1970年1月1日00:00 UTC开始的毫秒计数
  • 时区
    是以毫秒为单位的UTC偏移量。它可以是正、负或零。不过,就我所见,它的符号必须颠倒,公式才能工作:偏移量
    +01:00
    应为-360000毫秒。当我添加偏移量时,我会得到一个不同的时间点,其中UTC中的日期和时间与该UTC偏移量处的原始日期和时间相同
  • 除以24*60*60*1000,从纪元开始将毫秒转换为天。一天中的任何时间都会被丢弃
  • 乘以24*60*60*1000可将天数转换为毫秒。由于一天中的时间已被丢弃,我们现在的时间为当天的UTC 00:00
因此,这是一种从某个UTC偏移量处的时间点转换为仅以UTC表示的日期的方法

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

编辑:为什么我认为偏移的符号已反转?难道不是相反的转换,从UTC到本地吗?变量名
localTimeDay
似乎暗示了这一点?除法和乘法仅适用于UTC。由于历元为UTC 00:00,因此公式必须以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);
输出:

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

    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));
编辑:您在评论中询问:

我仍然有这样一个疑问:有固定数量的毫秒已经存在 从1970年1月1日开始,每个国家都应该得到相同的数字。 localTimeDate是指“我的国家的日期”还是指 这些数据来自哪里?例如:A国、B国;他们会看到的 从新纪元开始就是这样。假设数据处理发生在 国家A和数据来源是国家B。所以当我们说 “localTimeDate”,它是属于A国还是B国

这对两国都有效。这完全取决于输入公式的
时区值。如果这是国家A的UTC偏移量(符号颠倒),则转换将从国家A时间转换为UTC日期。如果是国家B的偏移量,则转换将从国家B时间开始。您完全正确,如果A国和B国的日期不同,您将得到两个不同的日期,这很容易成为事实。

  • timestamp
    是自1970年1月1日00:00 UTC开始的毫秒计数
  • 时区
    是以毫秒为单位的UTC偏移量。它可以是正、负或零。不过,就我所见,它的符号必须颠倒,公式才能工作:偏移量
    +01:00
    应为-360000毫秒。当我添加偏移量时,我会得到一个不同的时间点,其中UTC中的日期和时间与该UTC偏移量处的原始日期和时间相同
  • 除以24*60*60*1000,从纪元开始将毫秒转换为天。一天中的任何时间都会被丢弃
  • 乘以24*60*60*1000可将天数转换为毫秒。由于一天中的时间已被丢弃,我们现在的时间为当天的UTC 00:00
因此,这是一种从某个UTC偏移量处的时间点转换为仅以UTC表示的日期的方法

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

编辑:为什么我认为偏移的符号已反转?难道不是相反的转换,从UTC到本地吗?变量名
localTimeDay
似乎暗示了这一点?除法和乘法仅适用于UTC。由于历元为UTC 00:00,因此公式必须以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);
输出:

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

    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));
编辑:您在评论中询问:

我仍然有这样一个疑问:有固定数量的毫秒已经存在 从1970年1月1日开始,每个国家都应该得到相同的数字。 localTimeDate是指“我的国家的日期”还是指 这些数据来自哪里?例如:A国、B国;他们会看到的 从新纪元开始就是这样。假设数据处理发生在 国家A和数据来源是国家B。所以当我们说 “localTimeDate”,它是属于A国还是B国

这对两国都有效。这完全取决于输入公式的
时区值。如果这是国家A的UTC偏移量(符号颠倒),则转换将从国家A时间转换为UTC日期。如果是国家B的偏移量,则转换将从国家B时间开始。你完全正确,如果A国和B国的日期不一样,你会得到两个不同的日期