我具有以下已编写的功能,可以将msSinceEpoch
转换为新西兰日期(与IE11兼容)...
const MAGICNUMBER = 13;
const toNewZealand = (msSinceEpoch) => {
const [day, month, year, time] = new Date(msSinceEpoch).toLocaleString("en-NZ", {
hour12: false, timeZone: "UTC"
}).split(/[/,]/); // timeZone UTC is the only format support on IE11
const [hours, minutes, seconds] = time.trim().split(":");
return new Date(~~year, ~~month - 1, ~~day, ~~hours + MAGICNUMBER, ~~minutes, ~~seconds)
};
// usage....
console.log(
toNewZealand(new Date().getTime())
)
但是,它包含一个与新西兰的夏时制时间无关的魔术数字(+12或+13)。
所以这变得很复杂,如何获得相对于新西兰夏令时正确的数字(+12或+13)。
我最初的尝试只是计算它是在9月的最后一个星期日还是4月的第一个星期日之间,但是后来我意识到第二个我在代码中的任何地方都使用了new Date()
构造函数,它将创建一个日期相对于他们的系统时间,并打破数学。
TL; DR从时代开始将UTC毫秒转换为与新西兰夏令时设置兼容的新西兰时间。
编辑:由于捆绑软件的大小,也对使用Moment或任何其他库来解决此问题不感兴趣。
答案 0 :(得分:0)
解决了这个问题,尝试使其尽可能地易于阅读,基本上尝试根据当前UTC DateTime所在的位置添加12或13,如果通过添加12或13我们处于下一个夏令时,则添加备用代替.... IE,如果加12,我们就属于+13领土。...加+13。 IE,如果加上+13,我们就属于+12领土。...相反,加上+12。
新西兰的夏令时发生在9月的最后一个星期日和4月的第一个星期日。
这是解决方案。...
const UTCFromMS = (ms) => {
return new Date(new Date(ms).toUTCString().replace(" GMT", ""))
};
const addHours = (dte, hrs) => {
return new Date(
dte.getFullYear(),
dte.getMonth(),
dte.getDate(),
dte.getHours() + hrs,
dte.getMinutes(),
dte.getMilliseconds()
);
};
const toNewZealand = (ms) => {
return addNewZealandDaylightSavings(UTCFromMS(ms));
};
const getPreviousSunday = (dte) => {
return new Date(
dte.getFullYear(),
dte.getMonth(),
dte.getDate() - dte.getDay(),
1,
0,
0
);
};
const getNextSunday = (dte) => {
return new Date(
dte.getFullYear(),
dte.getMonth(),
dte.getDay() === 0 ? dte.getDate() : dte.getDate() + (7 - dte.getDay()),
1,
0,
0
)
};
const standardHours = 12;
const daylightHours = 13;
const addNewZealandDaylightSavings = (dte) => {
const lastSundaySeptember = getPreviousSunday(
new Date(dte.getFullYear(), 8, 30)
);
const firstSundayApril = getNextSunday(
new Date(dte.getFullYear(), 3, 1)
);
// If its before firstSundayApril, add 13, if we went over 1am, add 12.
if(dte <= firstSundayApril) {
const daylightNz = addHours(dte, daylightHours);
if(daylightNz >= firstSundayApril) {
return addHours(dte, standardHours);
}
return daylightNz
}
// if its before lastSundaySeptember, add 12 if we went over 1am add 13.
if(dte <= lastSundaySeptember) {
const standardNz = addHours(dte, standardHours);
if(standardNz >= lastSundaySeptember) {
return addHours(dte, daylightHours);
}
return standardNz;
}
return addHours(dte, daylightHours);
};
console.log(toNewZealand(new Date().getTime()).toString());
// the above line should always output the current DateTime in New Zealand, replace the argument with any epoch milliseconds and it should still always give you the correct time.