Javascript 倒计时与 php 的错误计算

Javascript false calculation for countdown vs php

我正在尝试制作一个倒数计时器。我正在与 PHP 和 Javascript 合作。我面临的问题是时差显示比 php 晚了一段时间。如果 PHP 显示 19 小时,则 Javascript 显示 16 小时。

我的函数显示与PHP

的时差
$timestamp = strtotime($time['expiration']) - time();

function convert_timestamp_to_date($timestamp)
{
  $date1 = new DateTime("@0");
  $date2 = new DateTime("@$timestamp");
  if ($date1->diff($date2)->d < 1) {
    return $date1->diff($date2)->format('%h Hours');
  } else {
    return $date1->diff($date2)->format('%a Days');
  }
}

我的函数显示与Javascript

的时差
// $job['job_expiration'] = 2020-05-13 15:24:22

function countdownTimer() {
    const difference = +new Date("<?php echo $job['job_expiration']; ?>") - +new Date();
    let remaining = "Time's up!";

    if (difference > 0) {
        const parts = {
            days: Math.floor(difference / (1000 * 60 * 60 * 24)),
            hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
            minutes: Math.floor((difference / 1000 / 60) % 60),
            seconds: Math.floor((difference / 1000) % 60)
        };

        remaining = Object.keys(parts)
            .map(part => {
                if (!parts[part]) return;
                return `${parts[part]} ${part}`;
            })
            .join(" ");
    }

    document.getElementById("countdown").innerHTML = remaining;
}

countdownTimer();
setInterval(countdownTimer, 1000);

看来是时差问题。

如果您在 Date() 中输入“2020-05-13 15:24:22”之类的字符串,它会假定该字符串在计算机的时区内。

例如,我的电脑处于太平洋夏令时 (GMT - 7) 时区:

let date1 = new Date("2020-05-13 10:56:50");
console.log(date1); // '2020-05-13T17:56:50.000Z'

请注意,7 小时后 Date 将我的太平洋夏令时转换为 UTC。

如果你简单地调用 Date() 而不带任何参数,你将获得 UTC 时区的当前日期和时间:

let date2 = new Date();
console.log(date2); // '2020-05-12T17:57:36.088Z'

从示例中很难确定,但很可能 PHP 时间:

<?php echo $job['job_expiration']; ?>

在服务器的时区,但 JavaScript 在具有不同时区的客户端计算机上是 运行。

关于处理时区的建议

避免弄乱时区的一个好规则是始终以 UTC 格式存储和操作日期,然后将它们转换为本地时间仅供显示。

如果您使用字符串作为 new Date 的参数,请确保该字符串采用 UTC 时间:

let date = new Date('2020-05-12T17:56:50.000Z');

结尾的 'Z' 表示此日期字符串采用 UTC ("zulu") 时区。