将 UTC 时间戳转换为 ISO 格式的其他时区
Convert UTC timestamp to other timezone in ISO format
我正在尝试将 UTC 时间戳转换为德国时间的 ISO 格式时间戳。
输入:2022-04-30T17:30:00.000000Z
预期输出:2022-04-30T19:30:00
这是我目前的工作解决方案,但感觉非常...hacky...至少可以说。
其一,恐怕许多浏览器可能无法将日期正确转换为德国时区。
var inputDateString = "2022-04-30T17:30:00.000000Z";
// Convert to German timezone and formatted as iso date
var output = toIsoString(convertTZ(inputDateString, "Europe/Berlin")).split("+")[0];
console.log("inputDateString:", inputDateString)
console.log("output:", output)
// Ref.:
function convertTZ(date, tzString) {
return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", { timeZone: tzString }));
}
// Ref.:
function toIsoString(date) {
var tzo = -date.getTimezoneOffset(),
dif = tzo >= 0 ? "+" : "-",
pad = function (num) {
return (num < 10 ? "0" : "") + num;
};
return date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + "T" + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds()) + dif + pad(Math.floor(Math.abs(tzo) / 60)) + ":" + pad(Math.abs(tzo) % 60);
}
您是否知道与大多数浏览器兼容的此问题的 better/improved 解决方案?我觉得 JavaScript 必须为这项任务提供更好的解决方案,而不必依赖外部库...
编辑:
作为 toIsoString
函数的替代方法,我还发现了这个:.toLocaleString("sv-SE")
但我认为这对浏览器的支持更差。
如果你不需要保证结果时间戳的格式,你可以使用 toLocaleDateString 加 toLocaleTimeString 用合适的语言标签,例如
function getISOLocal(loc, date = new Date()) {
return `${date.toLocaleDateString('en-CA', {timeZone: loc})}` +
`T${date.toLocaleTimeString('en', {timeZone: loc, hour12:false})}`;
}
console.log('Current local time in:');
['Pacific/Midway',
'America/New_York',
'Europe/Berlin',
'Pacific/Kiritimati'].forEach(
loc => console.log(`${loc} : ${getISOLocal(loc)}`)
);
但请注意,toLocale* 方法的格式取决于实现,并且可能因实现而异,特别是对于不太常见的语言以及语言、选项和主机默认语言的组合。
更好的选择是使用 Intl.DateTimeFormat 和 formatToParts,例如
function getISOLocal(loc, date = new Date()) {
let {year, month, day, hour, minute, second} =
new Intl.DateTimeFormat('en', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
timeZone: loc
}).formatToParts(date).reduce((acc, part) => {
acc[part.type] = part.value;
return acc;
}, Object.create(null));
return `${year}-${month}-${day}T${hour}:${minute}:${second}`
}
console.log('Current local time in:');
['Pacific/Midway',
'America/New_York',
'Europe/Berlin',
'Pacific/Kiritimati'].forEach(
loc => console.log(`${loc} : ${getISOLocal(loc)}`)
);
IE 不支持 timeZone 选项,但也许这无关紧要。
我正在尝试将 UTC 时间戳转换为德国时间的 ISO 格式时间戳。
输入:2022-04-30T17:30:00.000000Z
预期输出:2022-04-30T19:30:00
这是我目前的工作解决方案,但感觉非常...hacky...至少可以说。 其一,恐怕许多浏览器可能无法将日期正确转换为德国时区。
var inputDateString = "2022-04-30T17:30:00.000000Z";
// Convert to German timezone and formatted as iso date
var output = toIsoString(convertTZ(inputDateString, "Europe/Berlin")).split("+")[0];
console.log("inputDateString:", inputDateString)
console.log("output:", output)
// Ref.:
function convertTZ(date, tzString) {
return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", { timeZone: tzString }));
}
// Ref.:
function toIsoString(date) {
var tzo = -date.getTimezoneOffset(),
dif = tzo >= 0 ? "+" : "-",
pad = function (num) {
return (num < 10 ? "0" : "") + num;
};
return date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + "T" + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds()) + dif + pad(Math.floor(Math.abs(tzo) / 60)) + ":" + pad(Math.abs(tzo) % 60);
}
您是否知道与大多数浏览器兼容的此问题的 better/improved 解决方案?我觉得 JavaScript 必须为这项任务提供更好的解决方案,而不必依赖外部库...
编辑:
作为 toIsoString
函数的替代方法,我还发现了这个:.toLocaleString("sv-SE")
但我认为这对浏览器的支持更差。
如果你不需要保证结果时间戳的格式,你可以使用 toLocaleDateString 加 toLocaleTimeString 用合适的语言标签,例如
function getISOLocal(loc, date = new Date()) {
return `${date.toLocaleDateString('en-CA', {timeZone: loc})}` +
`T${date.toLocaleTimeString('en', {timeZone: loc, hour12:false})}`;
}
console.log('Current local time in:');
['Pacific/Midway',
'America/New_York',
'Europe/Berlin',
'Pacific/Kiritimati'].forEach(
loc => console.log(`${loc} : ${getISOLocal(loc)}`)
);
但请注意,toLocale* 方法的格式取决于实现,并且可能因实现而异,特别是对于不太常见的语言以及语言、选项和主机默认语言的组合。
更好的选择是使用 Intl.DateTimeFormat 和 formatToParts,例如
function getISOLocal(loc, date = new Date()) {
let {year, month, day, hour, minute, second} =
new Intl.DateTimeFormat('en', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
timeZone: loc
}).formatToParts(date).reduce((acc, part) => {
acc[part.type] = part.value;
return acc;
}, Object.create(null));
return `${year}-${month}-${day}T${hour}:${minute}:${second}`
}
console.log('Current local time in:');
['Pacific/Midway',
'America/New_York',
'Europe/Berlin',
'Pacific/Kiritimati'].forEach(
loc => console.log(`${loc} : ${getISOLocal(loc)}`)
);
IE 不支持 timeZone 选项,但也许这无关紧要。