将日期转换为 UTC 时间戳

时间:2021-07-30 13:11:39

标签: javascript date datetime

我有一个有时间的约会,就像这样

const date = {year: 2020, month: 12, day: 31};
const time = {hours: 16, minutes: 2};

如何根据时区获得该时间的 UTC 表示? (不使用任何库)

convetToUTC(date, time, "Europe/Moscow") // => <UTC timestamp>
convetToUTC(date, time, "America/New_York") // => <UTC timestamp>

示例

convetToUTC(
  {year: 2021, month: 7, day: 30}, 
  {hours: 16, minutes: 15}, 
  "Europe/Moscow"
) // => 1627650900

convetToUTC(
  {year: 2021, month: 7, day: 30}, 
  {hours: 16, minutes: 15}, 
  "America/New_York"
) // => 1627676100

2 个答案:

答案 0 :(得分:1)

支持 Achempion 的响应,我修复了时区偏移计算。应从 UTC 日期中减去时区日期。这种差异的结果应该在几分钟内。

然后您需要将分钟偏移量转换回毫秒并从日期中减去它。

/**
* Calculates the timezone offset of a particular time zone.
* @param {String} timeZone - a database time zone name
* @param {Date} date - a date for determining if DST is accounted for
* @return {Number} returns an offset in minutes
* @see https://stackoverflow.com/a/68593283/1762224
*/
const getTimeZoneOffset = (timeZone = 'UTC', date = new Date()) => {
  const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));
  const tzDate = new Date(date.toLocaleString('en-US', { timeZone }));
  return (tzDate.getTime() - utcDate.getTime()) / 6e4;
}

const defaultDateConfig = { year: 0, month: 0, date: 0 };
const defaultTimeConfig = { hours: 0, minutes: 0, seconds: 0 };

const convetToUTC = (dateConfig, timeConfig, timeZone) => {
  const { year, month, date } = { ...defaultDateConfig, ...dateConfig };
  const { hours, minutes, seconds } = { ...defaultTimeConfig, ...timeConfig };
  const d = new Date(Date.UTC(year, month - 1, date, hours, minutes, seconds));
  const offsetMs = getTimeZoneOffset(timeZone, d) * 6e4;
  return (d.getTime() - offsetMs) / 1e3;
};

// Main
const date = { year: 2021, month: 7, date: 30 };
const time = { hours: 16, minutes: 15 };

console.log(convetToUTC(date, time, 'America/New_York')); // 1627676100
console.log(convetToUTC(date, time, 'Europe/Moscow'));    // 1627650900

答案 1 :(得分:-1)

const dateWithTimeZone = (timeZone, year, month, day, hour, minute, second) => {
  let date = new Date(Date.UTC(year, month, day, hour, minute, second));

  let utcDate = new Date(date.toLocaleString('en-US', { timeZone: "UTC" }));
  let tzDate = new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
  let offset = utcDate.getTime() - tzDate.getTime();

  date.setTime( date.getTime() + offset );

  return date;
};

dateWithTimeZone("America/New_York", 2021, 7 - 1, 30, 16, 15, 0).getTime() / 1000)
// => 1627676100

dateWithTimeZone("Europe/Moscow", 2021, 7 - 1, 30, 16, 15, 0).getTime() / 1000)
// => 1627650900

7 - 1 用于说明该函数接受月份的索引,而不是月份的数字