为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

临摹微笑 2023-01-06 10:48:20

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

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

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

对不起,如果这是一个糟糕的问题

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


查看完整描述

2 回答

?
白衣非少年

TA贡献913条经验 获得超0个赞

如果您有一个始终希望使用 date-fns 解析为 CST(美国中央标准时间)的字符串,则可以包含 date-fns-tz 并在解析时设置时区(我假设 ISO 8601 松散格式没有时区). 请注意,为避免夏令时,您必须选择全年使用 UTC-6 的位置,例如加拿大/萨斯喀彻温省。


// 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 的链接)。


此时字符串已被解析为 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”版本中,您可能会获得偏移量或时区名称(可能取决于主机默认语言和位置,我认为这是使用Intl.DateTimeFormat的 date-fns-tz 的一个怪癖)。


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


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

这将产生如下输出:


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

我认为没有任何方法可以在不将其包含在调用中的情况下为解析和格式化设置特定的偏移量,如“-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}));


查看完整回答
反对 回复 2023-01-06
?
慕桂英4014372

TA贡献1635条经验 获得超13个赞

尝试使用 moment 库来解决您的时间问题:moment.js及其补充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();

}


查看完整回答
反对 回复 2023-01-06
  • 2 回答
  • 0 关注
  • 15 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信