在 javascript 中将时间表示为 CST - date-fns

Express time as CST in javascript - date-fns

我正在使用 date-fns 来格式化日期

如果我传递一个以 Z 结尾的日期,它知道它是 UTC,我可以 format(date, "yyyy-MM-dd") 它会是本地计算机时间。

如果我想用本地计算机时间表示的日期本来是CST,是否可以在末尾添加一些东西而不是Z,格式函数会将其理解为CST日期?

抱歉,如果这是一个糟糕的问题

编辑:有没有办法在 date-fns 中执行 zonedTimeToUtc(myDate, 'UTC-6')? (而不是使用时区 name

尝试使用时刻库​​来解决您的时间问题:moment.js, and its complement moment-timezone.js

要输出转换为 CST 时区的当前时间:

moment().tz('America/Chicago').format('hh:mm:ss z')

06:43:34 CST

moment().tz('America/Chicago').format('hh:mm:ss z Z')

06:43:35 CST -06:00

moment().tz('America/Chicago').format()

2020-08-13T15:52:09-06:00

或者使用如下函数:

const calcTime = (cityOffset) => {
  var now = new Date();
  // convert to msec and add local time zone offset and get UTC time in msec
  var utc = now.getTime() + (now.getTimezoneOffset() * 60000);

  // create new Date object for different city using supplied offset
  var newTime = new Date(utc + (3600000 * cityOffset));

  return newTime.toLocaleString();
}

如果您始终希望使用 date-fns 将字符串解析为 CST(美国中部标准时间),则可以包含 date-fns-tz 并在解析时设置时区(我已经假定没有时区的 ISO 8601 松散格式)。请注意,为了避免夏令时,您必须选择一个全年都是 UTC-6 的位置,例如Canada/Saskatchewan.

// Setup
var {parse} = require('date-fns');
var {zonedTimeToUtc, utcToZonedTime, format } = require('date-fns-tz');

// Parse using location for offset
let loc = 'Canada/Saskatchewan';
let s   = '2020-08-14 13:05:52';
let fIn = 'yyyy-MM-dd HH:mm:ss';
let utcDate =  zonedTimeToUtc(s, loc);
// Show local equivalent
console.log(utcDate);

这让您在某种程度上受到萨斯喀彻温省管理员的摆布,他们可能会更改偏移量或引入 DST。另一种方法是将您想要的确切偏移量附加到时间戳并将其包含在解析标记中:

// Parse using string for offset
let tz = '-06';
let utcDate2 =  parse(s + ' ' + tz,  fIn + ' X', new Date());
// Show local equivalent, should be same as above
console.log(utcDate2);

第二种方法的优点是它不需要 date-fns-tz,并且您不会受制于萨斯喀彻温省偏移量(或任何其他 IANA 位置的偏移量)的历史或未来更改。

显然有一个 UTC 模块正在开发中,它允许设置特定的偏移量,例如 -6 而不是使用 IANA 位置(无法找到该注释 atm 的 link)。

此时字符串已被解析为 GMT-6,但仍然只是一个普通日期(即只是一个时间值,不知道与原始字符串关联的时区)。

获得日期后,您可以将其显示为 CST 以进行输出。要在调用 format 时使用 IANA 位置作为偏移量,您必须使用来自 date-fns-tz 的格式,而不是普通的 date-fns,否则它只会使用主机系统偏移量。

请注意,格式调用中的值只是设置用于偏移字符串的值,它不会对实际日期和时间做任何事情, 已经应用了该调整utcToZonedTime.

// Adjust to CST
let dCST = utcToZonedTime(utcDate2, loc);
// Format strings:
let fOut1 = 'yyyy-MM-dd HH:mm:ss XXX'; // -0600
let fOut2 = 'yyyy-MM-dd HH:mm:ss z';   // CST
// Format using location
console.log(format(dCST, fOut1, {timeZone: loc}));
console.log(format(dCST, fOut2, {timeZone: loc}));

我更喜欢 -0600 版本,因为它避免了 DST 是否被遵守的问题(这确实是代码在做什么)。此外,在“z”版本中,您可能会获得偏移量或时区名称(可能取决于主机默认语言和位置,这是使用 [=56= 的 date-fns-tz 的怪癖]我觉得)。

您也可以使用如下格式字符串手动添加时区:

let fOut = 'yyyy-MM-dd HH:mm:ss \'-0600\'';

这将产生如下输出:

"2020-08-14 13:05:52 GMT-0600"

我认为没有任何方法可以在不将其包含在调用中的情况下为两个 parsing and formatting 设置特定的偏移量,例如“-0600”。我认为 moment.js 和 luxon 允许它。

为了完整起见,这里有一些您可以 运行 在 npm.runkit.com 的代码,因为当前 date-fns 版本没有 CDN 允许代码在此处 运行。

var {parse} = require('date-fns');
var {zonedTimeToUtc, utcToZonedTime, format } = require('date-fns-tz');

// Parse using location for offset
let loc = 'Canada/Saskatchewan';
let s   = '2020-08-14 13:05:52';
let fIn = 'yyyy-MM-dd HH:mm:ss';
let utcDate =  zonedTimeToUtc(s, loc);
// Show local equivalent
console.log(utcDate);

// Parse using string for offset
let tz = '-06';
let utcDate2 =  parse(s + ' ' + tz,  fIn + ' X', new Date());
// Show local equivalent, should be same as above
console.log(utcDate2);

// Format using location:
let fOut1 = 'yyyy-MM-dd HH:mm:ss XXX'; // -0600
let fOut2 = 'yyyy-MM-dd HH:mm:ss z';   // CST
let dCST = utcToZonedTime(utcDate2, loc);
console.log(format(dCST, fOut1, {timeZone: loc}));
console.log(format(dCST, fOut2, {timeZone: loc}));