[英]date-fns | How do I format to UTC
It looks like when I use the format()
function, it automatically convert the original UTC time into my timezone (UTC+8).看起来当我使用
format()
function 时,它会自动将原始 UTC 时间转换为我的时区(UTC+8)。 I have been digging through their docs for hours and couldn't seem to find a way to default it to UTC time.我一直在研究他们的文档几个小时,似乎找不到将其默认为 UTC 时间的方法。
import { parseISO, format } from "date-fns";
const time = "2019-10-25T08:10:00Z";
const parsedTime = parseISO(time);
console.log(parsedTime); // 2019-10-25T08:10:00.000Z
const formattedTime = format(parsedTime, "yyyy-MM-dd kk:mm:ss");
console.log(formattedTime); // 2019-10-25 16:10:00 <-- 8 HOURS OFF!!
I have tried to use the package data-fns-tz
and use something like我尝试使用 package
data-fns-tz
并使用类似的东西
format(parsedTime, "yyyy-MM-dd kk:mm:ss", {timeZone: "UTC"});
still no luck.仍然没有运气。
Please help!请帮忙!
2019-10-25 08:10:00
2019-10-25 16:10:00
You were almost there.你快到了。 This works for me:
这对我有用:
import { parseISO } from "date-fns";
import { format, utcToZonedTime } from "date-fns-tz";
const time = "2019-10-25T08:10:00Z";
const parsedTime = parseISO(time);
console.log(parsedTime); // 2019-10-25T08:10:00.000Z
const formatInTimeZone = (date, fmt, tz) =>
format(utcToZonedTime(date, tz),
fmt,
{ timeZone: tz });
const formattedTime = formatInTimeZone(parsedTime, "yyyy-MM-dd kk:mm:ss xxx", "UTC");
console.log(formattedTime); // 2019-10-25 08:10:00 +00:00
The date-fns[-tz] libraries stick to the built-in Date
data type that carries no TZ info . date-fns[-tz] 库坚持使用不携带 TZ 信息的内置
Date
数据类型。
Some functions treat it as a moment-in-time, but some like format
treat it more like a struct of calendaric components — year 2019, ..., day 25, hour 08, ....一些函数将其视为时间点,但有些函数将其视为日历组件的结构
format
年,...,第 25 天,第 8 小时,...。
Now the trouble is a Date
is internally only a moment in time.现在问题是
Date
在内部只是一个时刻。 Its methods provide a mapping to/from calendaric components in local time zone .它的方法在本地时区提供到/来自日历组件的映射。
So to represent a different time zone, date-fns-tz/utcToZonedTime
temporarily produces Date
instances which represent the wrong moment in time — just to get its calendaric components in local time to be what we want!因此,为了表示不同的时区,
date-fns-tz/utcToZonedTime
临时生成代表错误时间点的Date
实例——只是为了让它在本地时间的日历组件成为我们想要的!
And the date-fns-tz/format
function's timeZone input affects only the template chars that print the time zone ( XX..X
, xx..x
, zz..z
, OO..O
).并且
date-fns-tz/format
函数的 timeZone 输入仅影响打印时区的模板字符( XX..X
, xx..x
, zz..z
, OO..O
)。
See https://github.com/marnusw/date-fns-tz/issues/36 for some discussion of this "shifting" technique (and of real use cases that motivated them)...请参阅https://github.com/marnusw/date-fns-tz/issues/36了解有关这种“转移”技术(以及激发它们的真实用例)的一些讨论......
It's a bit low-level & risky, but the specific way I composed them above — formatInTimeZone()
— is I believe a safe recipe.这有点低级和风险,但我在上面编写它们的具体方式
formatInTimeZone()
——我相信是一个安全的方法。
Note笔记
The following solution will not work for all time zones, so if timezone accuracy is critical for your application you might want to try something like the answer from Beni.以下解决方案不适用于所有时区,因此如果时区准确性对您的应用程序至关重要,您可能想尝试类似 Beni 的答案。 See this link for more info
有关更多信息,请参阅此链接
I had the exact same question today and did some research to see if anyone has come up with anything better since this question was posed.我今天有完全相同的问题,并做了一些研究,看看自从提出这个问题以来是否有人提出了更好的办法。 I came across this solution which fit my needs and stylistic preference:
我遇到了这个适合我的需求和风格偏好的解决方案:
import { format, addMinutes } from 'date-fns';
function formatDate(date) {
return format(addMinutes(date, date.getTimezoneOffset()), 'yyyy-MM-dd HH:mm:ss');
}
getTimezoneOffset
returns the number of minutes needed to convert that date to UTC. getTimezoneOffset
返回将该日期转换为 UTC 所需的分钟数。 In PST (-0800 hours) it would return 480 whereas for somebody on CST (+0800 hours) it would return -480.在 PST(-0800 小时)中,它将返回 480,而对于 CST(+0800 小时)中的某人,它将返回 -480。
I would suggest using the built-in Date
util:我建议使用内置的
Date
util:
const date = new Date("2019-10-25T08:10:00Z");
const isoDate = date.toISOString();
console.log(`${isoDate.substr(0, 10)} ${isoDate.substr(11, 8)}`);
Outputs:输出:
2019-10-25 08:10:00
Not a general solution for any format, but no external libraries required.不是任何格式的通用解决方案,但不需要外部库。
I had the same problem.我有同样的问题。 What I do is remove the timezone from the ISO string and then use that time with date-fns:
我所做的是从 ISO 字符串中删除时区,然后将该时间与 date-fns 一起使用:
let time = "2019-10-25T08:10:00Z".slice(0, -1)
The above is a time with no time zone, and because there is no timezone date-fns assumes the local timezone, so when you do:上面是一个没有时区的时间,并且因为没有时区 date-fns 假定本地时区,所以当你这样做时:
format(parseISO(time), 'h:mm a')
you get: 8:10 AM , or whatever format you prefer.你会得到: 8:10 AM ,或者你喜欢的任何格式。 You just have to be careful with the string that you are slicing.
你只需要小心你正在切片的字符串。 If its always the same format then it should work.
如果它总是相同的格式,那么它应该可以工作。
I did something like this using date/fns and native date methods我使用日期/fns 和本机日期方法做了类似的事情
import format from 'date-fns/format'; import parseISO from 'date-fns/parseISO'; export const adjustForUTCOffset = date => { return new Date( date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), ); }; const formatDate = (dateString) = > { const date = parseISO(dateString); const dateWithOffset = adjustForUTCOffset(date) return format(dateWithOffset, 'LLL dd, yyyy HH:mm') }
I guess我猜
To construct the date as UTC before parsing would be helpful.在解析之前将日期构造为 UTC 会很有帮助。
import { parseISO, format } from "date-fns";
const time = "2019-10-25T08:10:00Z";
const parsedTime = parseISO(new Date(Date.UTC(time)));
const formattedTime = format(parsedTime, "yyyy-MM-dd kk:mm:ss");
like this.像这样。
try尝试
const formatDate = new Date().toISOString().substr(0, 19).replace('T', ' ');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.