date-fns | How do I format to UTC

后端 未结 5 578
逝去的感伤
逝去的感伤 2020-12-17 10:42

Problem

It looks like when I use the format() function, it automatically convert the original UTC time into my timezone (UTC+8). I have been digging t

5条回答
  •  悲&欢浪女
    2020-12-17 11:10

    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
    

    Behind the scenes

    The date-fns[-tz] libraries stick to the built-in Date data type that carries no TZ info.
    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, ....

    Now the trouble is a Date is internally only a moment in time. 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!

    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).

    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)...
    It's a bit low-level & risky, but the specific way I composed them above — formatInTimeZone() — is I believe a safe recipe.

提交回复
热议问题