没有正确计算停机时间

时间:2019-11-28 07:16:20

标签: javascript html date datetime

我正在创建一个倒计时网站。我希望它从当前时间倒数我的庆祝日期2019-11-29 00:00:00。我希望时区在澳大利亚布里斯班时区。但是,似乎它一直在计算直到我的庆祝日期不对的时间。有人可以告诉我我做错了什么吗?时间到了0,我该如何摆脱倒数计时,将其替换为<a href="party.html">Its celebration time</a>

function dateDiff(a, b) {
    // Some utility functions:
    const getSecs = dt => (dt.getHours() * 24 + dt.getMinutes()) * 60 + dt.getSeconds();
    const getMonths = dt => dt.getFullYear() * 12 + dt.getMonth();

    // 0. Convert to new date objects to avoid side effects
    a = new Date(a);
    b = new Date(b);
    if (a > b) [a, b] = [b, a]; // Swap into order 
    
    // 1. Get difference in number of seconds during the day:
    let diff = getSecs(b) - getSecs(a);
    if (diff < 0) {
        b.setDate(b.getDate()-1); // go back one day
        diff += 24*60*60; // compensate with the equivalent of one day
    }
    // 2. Get difference in number of days of the month
    let days = b.getDate() - a.getDate();
    if (days < 0) {
        b.setDate(0); // go back to (last day of) previous month
        days += b.getDate(); // compensate with the equivalent of one month
    }
    // 3. Get difference in number of months
    const months = getMonths(b) - getMonths(a); 
    return {
        years: Math.floor(months/12),
        months: months % 12,
        days, 
        hours: Math.floor(diff/3600),
        minutes: Math.floor(diff/60) % 24,
        seconds: diff % 60
    };
}

// Date to start on
var celebrationDate = new Date("2019-11-29 00:00:00").toLocaleString("en-US", {timeZone: "Australia/Brisbane"});

// Update the count every 1 second
!function refresh () {
    const diff = dateDiff(new Date().toLocaleString("en-US", {timeZone: "Australia/Brisbane"}), celebrationDate);
    document.getElementById("day-val").innerHTML = diff[Object.keys(diff)[2]];
    document.getElementById("hour-val").innerHTML = diff[Object.keys(diff)[3]];
    document.getElementById("min-val").innerHTML = diff[Object.keys(diff)[4]];
    document.getElementById("sec-val").innerHTML = diff[Object.keys(diff)[5]];
    setTimeout(refresh, 1000)
}()
<div id="day-val"></div><div>Days</div><br>
<div id="hour-val"></div><div>Hours</div><br>
<div id="min-val"></div><div>Minutes</div><br>
<div id="sec-val"></div><div>Seconds</div>

2 个答案:

答案 0 :(得分:0)

使用普通javascript的解决方案:

  1. 获取客户的时区偏移量
  2. 计算// package.json { ..., "jest": { "setupFilesAfterEnv": "<rootDir>/test-setup.js" } } client offset之间的差异
  3. 计算"Australian/Brisbane" offset剩余的时间
  4. 格式化结果以显示它

示例:

targetDate - currentDate - offsetDiff

您还应该选中moment.js,因为它具有许多有用的功能。

moment.js的示例:

const minToMS = min => min * 60 * 1000

const getCountDownFromMS = diff => {
    const milliseconds = diff % 1000
    diff = (diff - milliseconds) / 1000
    const seconds = diff % 60
    diff = (diff - seconds) / 60
    const minutes = diff % 60
    diff = (diff - minutes) / 60
    const hours = diff % 24
    diff = (diff - hours) / 24
    const days = diff
    return {
        days,
        hours,
        minutes,
        seconds,
        milliseconds
    }
}

const targetDate = new Date('2019-11-29 00:00:00')
// Getting offset with getTimezoneOffset is not reliable, using a database to get time zone offset is needed, like IANA Time Zone Database.
// moment.js internally uses IANA db 
const tzOffset = targetDate.getTimezoneOffset() // Client browsers timezone offset in minutes
const target_tzOffset = -600 // Australia Brisbane timezone offset in minutes
const offset = minToMS(tzOffset - target_tzOffset)
const msLeft = targetDate - new Date() - offset
const result = getCountDownFromMS(msLeft)

答案 1 :(得分:0)

如果您正在使用moment.js

您可以使用diffduration函数,如下所示:

const now = moment();
const celebrationDate= moment("2019-11-30 00:00:00");

// this will get the difference between now and celebrationDate
const celebrationDateDiff = expiration.diff(now);

// convert it into duration
const duration = moment.duration(celebrationDateDiff);

然后您可以像这样访问倒计时:

duration.days() // will return the number of days
duration.hours() // will return the number of remaining  hours
duration.minutes() // will return the number of remaining minutes