简体   繁体   English

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

[英]Express time as CST in javascript - date-fns

I am using date-fns to format dates我正在使用 date-fns 来格式化日期

If I pass a date that ends in Z, it knows that it is UTC, and I can format(date, "yyyy-MM-dd") and it will be in local computer time.如果我传递一个以 Z 结尾的日期,它知道它是 UTC,我可以format(date, "yyyy-MM-dd") ,它将是本地计算机时间。

If the date I want to express in local computer time is originally CST, is there something to add at the end instead of the Z, that will be understood by the format function as a CST date?如果我想以本地计算机时间表示的日期最初是 CST,那么最后是否需要添加一些东西而不是 Z,这将被格式 function 理解为 CST 日期?

Sorry if this is a bad question对不起,如果这是一个不好的问题

Edit: is there a way to do zonedTimeToUtc(myDate, 'UTC-6') in date-fns?编辑:有没有办法在 date-fns 中执行zonedTimeToUtc(myDate, 'UTC-6') (instead of using a time zone name ) (而不是使用时区名称

Try using moment libraries to solve your time problems: moment.js , and its complement moment-timezone.js尝试使用矩库来解决您的时间问题: moment.js及其补充moment-timezone.js

To output the current time converted to CST timezone:将 output 当前时间转换为 CST 时区:

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

06:43:34 CST 06:43:34 CST

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

06:43:35 CST -06:00 06:43:35 CST -06:00

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

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

Or maybe use a function as below:或者也许使用 function 如下:

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();
}

If you have a string that you always want parsed as CST (US central standard time) using date-fns, you can include date-fns-tz and set the timezone when parsing (I've assumed an ISO 8601 loose format without the timezone).如果您有一个始终希望使用 date-fns 解析为 CST(美国中央标准时间)的字符串,您可以包含 date-fns-tz 并在解析时设置时区(我假设 ISO 8601 松散格式没有时区)。 Note that to avoid DST, you have to pick a location that is UTC-6 all year round, eg Canada/Saskatchewan.请注意,为避免 DST,您必须选择全年 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);

This leaves you somewhat at the mercy of the administrators of Saskatchewan, who might change the offset or introduce DST.这让您在某种程度上受到萨斯喀彻温省管理员的摆布,他们可能会更改偏移量或引入 DST。 An alternative is to append the exact offset you want to the timestamp and include it in the parse tokens:另一种方法是 append 您想要时间戳的确切偏移量并将其包含在解析标记中:

// 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);

The advantage of the second method is that it doesn't require date-fns-tz and you aren't beholden to historic or future changes to Saskatchewan's offset (or that of any other IANA location).第二种方法的优点是它不需要 date-fns-tz 并且您不会受制于萨斯喀彻温省偏移量(或任何其他 IANA 位置)的历史或未来变化。

Apparently there is a UTC module in development that will allow setting specific offsets like -6 rather than using IANA locations (can't find a link to that comment atm).显然,有一个 UTC 模块正在开发中,它允许设置特定的偏移量,例如 -6,而不是使用 IANA 位置(找不到指向该评论 atm 的链接)。

At this point the string has been parsed as GMT-6, but is still just a plain Date (ie just a time value with no idea of the timezone that was associated with the original string).此时字符串已被解析为 GMT-6,但仍然只是一个普通的日期(即只是一个时间值,不知道与原始字符串关联的时区)。

Once you have the date you can then show it as CST for output.获得日期后,您可以将其显示为 output 的 CST。 To use an IANA location for the offset in call to format , you have to use format from date-fns-tz, not plain date-fns, otherwise it will just use the host system offset.要在调用format时使用 IANA 位置作为偏移量,您必须使用 date-fns-tz 中的格式,而不是普通的 date-fns,否则它将只使用主机系统偏移量。

Note that the value in the format call is just setting the value to use for the offset string, it doesn't do anything to the actual date and time, that adjustment has already been applied by utcToZonedTime .请注意,格式调用中的值只是设置用于偏移字符串的值,它对实际日期和时间没有任何作用,该调整已由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}));

I prefer the -0600 version as it avoids questions of whether DST is observed or not (and is really what the code is doing).我更喜欢 -0600 版本,因为它避免了是否观察到 DST 的问题(并且确实是代码正在做的事情)。 Also, in the "z" version you might get the offset or the timezone name (probably depending on the host default language and location, which is a quirk of date-fns-tz using Intl.DateTimeFormat I think).此外,在“z”版本中,您可能会获得偏移量或时区名称(可能取决于主机默认语言和位置,我认为这是使用Intl.DateTimeFormat的 date-fns-tz 的一个怪癖)。

You can also manually add the timezone using a format string like:您还可以使用如下格式字符串手动添加时区:

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

which will produce an output like:这将产生一个 output 像:

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

I don't think there is any way to set a specific offset like "-0600" for both parsing and formatting without including it in the call.我认为没有任何方法可以为解析格式化设置像“-0600”这样的特定偏移量,而不会将其包含在调用中。 I think moment.js and luxon allow it.我认为 moment.js 和 luxon 允许它。

For completeness, here's some code you can run at npm.runkit.com since there's no CDN for the current date-fns version to allow the code to run here.为了完整起见,您可以在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}));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM