提问人:user22476690 提问时间:11/1/2023 最后编辑:user22476690 更新时间:11/1/2023 访问量:86
如何在 Javascript 中查找特定时区中给定日历日期和时间的 Unix 时间戳?
How to find Unix timestamp of a given calendar date and time in a specific time zone in Javascript?
问:
使用 Intl 等 API,我可以获取任何时区中任何 Unix 时间戳的日期和时间。我怎样才能反其道而行之?
我希望能够将 (YYYY-MM-DD)、(HH:MM:SS) 和 (IANA 时区) 的任何特定三元组(不一定与固定时区偏移量相对应)转换为 Unix 时间戳。我不是只想转换当前时间戳(这是微不足道的)或寻找以我有一个 Javascript Date 对象为前提的解决方案;我们只有日历日期、当地时间和时区。<calendar-date>
<local-time>
<time-zone>
诸如添加时区偏移量之类的解决方案不能可靠地工作(例如,在夏令时的情况下)。我曾希望 Intl 能够轻松计算这个问题。
答:
0赞
mplungjan
11/1/2023
#1
这对你有用吗?
这不是微不足道的
/**
* Converts a calendar date and local time to a Unix timestamp.
*
* @param {string} calendarDate - The calendar date in the format 'YYYY-MM-DD'.
* @param {string} localTime - The local time in the format 'HH:mm:ss'.
* @param {string} timeZone - The IANA time zone identifier.
* @returns {number} The Unix timestamp in seconds.
*/
const convertToUnixTimestamp = (calendarDate, localTime, timeZone) => {
const [hourStr, minuteStr, secondStr] = localTime.split(':');
let hour = parseInt(hourStr, 10);
const minute = parseInt(minuteStr, 10);
const second = parseInt(secondStr, 10);
const dateTimeString = `${calendarDate}T00:00:00`;
// Set the locale to 'en-US' for consistent formatting
const dtf = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZoneName: 'short',
timeZone
});
// Format the date portion of the datetime string
const formattedDate = dtf.format(new Date(dateTimeString));
// Determine if it's in the afternoon based on the hour
const isAfternoon = hour >= 12;
// Replace "AM" or "PM" without appending when needed
const formattedDateTime = formattedDate.replace(
/(AM|PM)/,
isAfternoon ? 'PM' : 'AM'
);
// Subtract 12 from the hour if it's in the afternoon (PM)
if (isAfternoon) {
hour -= 12;
}
// Combine the formatted date with the provided local time
const formattedDateTimeWithTime = formattedDateTime.replace(
/\d{2}:\d{2}:\d{2}/,
`${hour.toString().padStart(2, '0')}:${minuteStr}:${secondStr}`
);
// Create a Date object with the formatted datetime string
const date = new Date(formattedDateTimeWithTime);
console.log(formattedDateTimeWithTime, "->", date);
// Get the Unix timestamp in seconds
const unixTimestamp = Math.floor(date.getTime() / 1000);
return unixTimestamp;
};
// Example usages:
const calendarDate = '2023-04-15';
let timeZone = 'America/New_York';
let localTime = '00:30:00'; // Example with '00'
let unixTimestamp = convertToUnixTimestamp(calendarDate, localTime, timeZone);
console.log(unixTimestamp);
localTime = '15:30:00'; // Example with military time
unixTimestamp = convertToUnixTimestamp(calendarDate, localTime, timeZone);
console.log(unixTimestamp);
timeZone = 'Europe/Amsterdam'; // another IANA timezone
localTime = '15:30:00';
unixTimestamp = convertToUnixTimestamp(calendarDate, localTime, timeZone);
console.log(unixTimestamp);
评论
2赞
user22476690
11/1/2023
感谢您努力尝试实际回答这个问题!不幸的是,这个答案存在以下问题:1)重新解析日期字符串;这种格式不适用于所有 Date 实现,例如在 Hermes (React Native) 中;也许可以通过进一步修改以使格式适合ISO8601来补救,但更重要的是,2) 我不明白这如何在边缘情况下正确处理 DST,IIUC 这假设连续的日子具有相同的偏移量,这几乎总是正确的。
1赞
mplungjan
11/1/2023
#2
Luxon版本适合您吗?
// const { DateTime } = require('luxon');
// Define your input values
const calendarDate = '2023-04-15';
const localTime = '12:30:00';
const timeZone = 'America/New_York'; // Example timezone, replace with your desired IANA timezone
// Combine calendar date and local time
const dateTimeString = `${calendarDate}T${localTime}`;
// Create a Luxon DateTime object in the specified timezone
const luxonObj = luxon.DateTime.fromISO(dateTimeString, { zone: timeZone }); // remove luxon. if you have required DateTime
console.log(luxonObj)
// Get the Unix timestamp
const unixTimestamp = luxonObj.toSeconds();
console.log(unixTimestamp);
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/3.4.3/luxon.min.js"></script>
评论
new Date('1983-04-23T12:34:56+06:00').getTime()
...?!如果你能创建一个对象,那么你就只需要这样了。你的输入是什么样的,你到底卡在哪里?Date
getTime
Date
Date
Date
Date
Date
Date
Intl