date-fns |如何格式化为UTC

时间:2019-10-25 15:08:56

标签: javascript date datetime date-fns

问题

当我使用format()函数时,它会自动将原始UTC时间转换为我的时区(UTC + 8)。我已经花了好几个小时来研究他们的文档,而且似乎找不到将其默认为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!!

我尝试使用软件包data-fns-tz并使用类似的东西

format(parsedTime, "yyyy-MM-dd kk:mm:ss", {timeZone: "UTC"});

仍然没有运气。

请帮助!

预期产量

2019-10-25 08:10:00

实际输出

2019-10-25 16:10:00

8 个答案:

答案 0 :(得分:17)

注意
以下解决方案并非在所有时区都适用,因此,如果时区精度对您的应用程序至关重要,则您可能需要尝试类似Beni的答案。有关更多信息,请参见此link

我今天有完全相同的问题,并且做了一些研究,看自从提出这个问题以来,是否有人提出了更好的建议。我遇到了this解决方案,它适合我的需求和风格偏好:

import { format, addMinutes } from 'date-fns';

function formatDate(date) {
  return format(addMinutes(date, date.getTimezoneOffset()), 'yyyy-MM-dd HH:mm:ss');
}

说明

getTimezoneOffset返回将日期转换为UTC所需的分钟数。在PST(-0800小时)中,它将返回480,而对于在CST上的人(+0800小时),它将返回-480。

答案 1 :(得分:5)

您快到了。这对我有用:

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

幕后

date-fns [-tz]库坚持使用carries no TZ info内置的Date数据类型。
有些函数将其视为即时信息,但有些函数format则将其视为日历元素的结构-2019年,...,第25天,小时08,....

现在的麻烦是,Date在内部仅是片刻。它的方法提供了与本地时区中的日历组件的映射。

因此,为了表示不同的时区,date-fns-tz/utcToZonedTime临时生成了Date实例,它们表示错误的时刻-只是为了使其本地时间的日历成分成为我们想要什么!

date-fns-tz/format函数的timeZone输入仅影响 打印时区的模板字符(XX..Xxx..xzz..z,{ {1}}。

请参见https://github.com/marnusw/date-fns-tz/issues/36,以了解有关这种“转换”技术(以及激发它们的实际用例)的某些讨论...
这有点低级且有风险,但是我在上面OO..O编写它们的特定方式是我认为是安全的食谱。

答案 2 :(得分:3)

我使用 date/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')
}

答案 3 :(得分:1)

我建议使用内置的Date实用程序:

const date = new Date("2019-10-25T08:10:00Z");
const isoDate = date.toISOString();

console.log(`${isoDate.substr(0, 10)} ${isoDate.substr(11, 8)}`);

输出:

2019-10-25 08:10:00

不是任何格式的通用解决方案,但不需要外部库。

答案 4 :(得分:0)

我有同样的问题。我要做的是从ISO字符串中删除时区,然后将该时间与date-fns一起使用:

let time = "2019-10-25T08:10:00Z".slice(0, -1)

上面是一个带有to时区的时间,并且因为没有时区,所以date-fns假定为本地时区,所以当您这样做时:

format(parseISO(time), 'h:mm a')

您将获得:上午8:10 ,或您喜欢的任何格式。您只需要注意要切片的字符串。如果其格式始终相同,则应该可以使用。

答案 5 :(得分:0)

尝试

const formatDate = new Date().toISOString().substr(0, 19).replace('T', ' ');

答案 6 :(得分:0)

我是这样做的

const now = new Date()
  const date = format(
    new Date(now.toISOString().slice(0, -1)),
    'yyyy-MM-dd HH:mm:ss'
  )

我刚刚从 ISO 字符串中删除了 Z。我不确定它是否能解决这个问题issue

答案 7 :(得分:0)

我猜

在解析之前将日期构造为 UTC 会很有帮助。

import { parseISO, format } from "date-fns";

const time = "2019-10-25T08:10:00Z";

const parsedTime = new Date(Date.UTC(time));
const formattedTime = format(parsedTime, "yyyy-MM-dd kk:mm:ss");

像这样。