如此岑寂 發表於 2026-3-26 11:21:00

算法~时间戳计算两个日期是否为同天同时同分

<p>UTC时间戳验证两个日期是否为同一天的核心原理在于:<strong>时间戳是绝对的时间点,而“天”是依赖于特定时区(如UTC)的人为划分区间。通过将两个绝对时间点转换到同一时区后,比较它们的年、月、日是否完全相同。</strong></p>
<p>具体原理可分以下几步理解:</p>
<h3 id="1-时间戳的本质">1. 时间戳的本质</h3>
<p>Unix时间戳(通常指秒数或毫秒数)是从 <strong>1970-01-01 00:00:00 UTC</strong> 开始经过的时间长度。它是一个<strong>绝对</strong>的时间度量,不携带时区信息。<br>
例如:<code>1710000000</code> 这个数值代表全球同一瞬间。</p>
<h3 id="2-天是时区相关的区间">2. “天”是时区相关的区间</h3>
<p>“同一天”并不是指时间戳数值相近,而是指在某个特定时区的日历上,它们属于同一个日期(年、月、日)。</p>
<ul>
<li>在 <strong>UTC+0</strong> 时区,一天是从 <code>00:00:00</code> 到 <code>23:59:59.999...</code></li>
<li>在 <strong>UTC+8</strong> 时区,同一天对应的UTC时间区间会偏移8小时</li>
</ul>
<p>因此,判断“同一天”必须<strong>先确定一个时区</strong>。如果题目特指“UTC时间戳验证同一天”,那么通常就是以 <strong>UTC</strong> 作为参考时区。</p>
<h3 id="3-验证逻辑">3. 验证逻辑</h3>
<p>验证两个时间戳 <code>t1</code> 和 <code>t2</code> 在UTC时区是否为同一天的步骤:</p>
<ol>
<li><strong>取整</strong>:如果时间戳是毫秒级,通常先除以1000转为秒(或保留毫秒但后续计算时注意边界)。</li>
<li><strong>计算每个时间戳对应的UTC日期</strong>:
<ul>
<li>将时间戳(秒数)转换为UTC时间的年、月、日。</li>
<li>这可以通过编程语言的内置函数完成(如JavaScript的 <code>new Date(timestamp).getUTCFullYear()</code> 等)。</li>
</ul>
</li>
<li><strong>比较</strong>:如果两个时间戳的 <strong>年、月、日</strong> 完全相同,则它们是UTC下的同一天。</li>
</ol>
<h3 id="4-边界情况时区转换的等效原理">4. 边界情况:时区转换的等效原理</h3>
<p>在数学上,这等价于计算两个时间戳在UTC时区下<strong>距离某个纪元日的天数</strong>是否相等。</p>
<p>设 <code>days = floor(timestamp / 86400)</code>(86400为一天的秒数)。<br>
如果两个时间戳除以86400取整后的结果相等,那么它们在UTC时区就是同一天。</p>
<p>但需要注意:</p>
<ul>
<li>这个取整公式 <code>floor(t / 86400)</code> 隐含了UTC时区,因为Unix纪元的起点是 <code>1970-01-01 00:00:00 UTC</code>。</li>
<li>直接比较 <code>floor(t1/86400) == floor(t2/86400)</code> 在数学上等价于UTC时区的日期比较,但前提是时间戳是<strong>精确到秒</strong>且没有闰秒干扰(Unix时间戳忽略闰秒)。</li>
</ul>
<h3 id="5-为什么要强调utc">5. 为什么要强调UTC</h3>
<p>如果问题中明确说“UTC时间戳验证两个日期为同一天”,那么原理就是利用UTC时区下天数索引的一致性。如果换成其他时区(如北京时间),则需要在计算时先加上时区偏移量,再取天数的整数部分。</p>
<p><strong>总结</strong>:原理就是将绝对的时间戳映射到UTC时区下的日历日期,通过比较年、月、日(或等价地比较从纪元开始的天数)来判断是否为同一天。</p>
<p><strong>Java代码实现</strong></p>
<pre><code class="language-java">/**
       * UTC时间戳验证同一天、同一小时、同一分钟
       */
        @Test
        public void utcTimeStampDayHourMin() {
                long sameDay = 24 * 60 * 60 * 1000;
                long sameHour = 60 * 60 * 1000;
                long sameMinute = 60 * 1000;
                LocalDateTime ldt = LocalDateTime.of(2026, 1, 1, 0, 50, 0);
                LocalDateTime ldt2 = LocalDateTime.of(2026, 1, 1, 23, 50, 0);
                long d1 = ldt.toInstant(ZoneOffset.UTC).toEpochMilli() / sameDay;
                long d2 = ldt2.toInstant(ZoneOffset.UTC).toEpochMilli() / sameDay;
                log.info("同一天 d1: {}, d2: {}, same day: {}", d1, d2, d1 == d2);

                LocalDateTime ldt3 = LocalDateTime.of(2026, 1, 1, 0, 50, 0);
                LocalDateTime ldt4 = LocalDateTime.of(2026, 1, 1, 0, 10, 0);
                long d3 = ldt3.toInstant(ZoneOffset.UTC).toEpochMilli() / sameHour;
                long d4 = ldt4.toInstant(ZoneOffset.UTC).toEpochMilli() / sameHour;
                log.info("同一天同一小时 d3: {}, d4: {}, same hour: {}", d3, d4, d3 == d4);

                LocalDateTime ldt5 = LocalDateTime.of(2026, 1, 1, 0, 50, 0);
                LocalDateTime ldt6 = LocalDateTime.of(2026, 1, 1, 0, 50, 30);
                long d5 = ldt5.toInstant(ZoneOffset.UTC).toEpochMilli() / sameMinute;
                long d6 = ldt6.toInstant(ZoneOffset.UTC).toEpochMilli() / sameMinute;
                log.info("同一天同一小时同一分钟 d5: {}, d6: {}, same minute: {}", d5, d6, d5 == d6);
        }
</code></pre>


</div>
<div id="MySignature" role="contentinfo">
    <p></p>
<div class="navgood">
<p>作者:仓储大叔,张占岭,<br>
荣誉:微软MVP<br>QQ:853066980</p>

<p><strong>支付宝扫一扫,为大叔打赏!</strong>
<br><img src="https://images.cnblogs.com/cnblogs_com/lori/237884/o_IMG_7144.JPG"></p>
</div><br><br>
来源:https://www.cnblogs.com/lori/p/19774878
頁: [1]
查看完整版本: 算法~时间戳计算两个日期是否为同天同时同分