15

I have a log file with some timestamps

2020-12-03 08:30:00
2020-12-03 08:40:00
...

I know from the log provider's documentation that the timestamps are written in UTC (although not using ISO format)

Now I want to parse them with date-fns :

const toParse = "2020-12-03 08:40:00"
parse(toParse, 'yyyy-MM-dd HH:mm:ss', new Date()).toISOString()

And because the locale of my computer is in UTC+1 here is what I see:

> "2020-12-03T07:40:00Z"

expected:

> "2020-12-03T08:40:00Z".

Here is the hack I currently use to tell date-fns to parse as UTC :

const toParse = "2020-12-03 08:40:00"
parse(toParse + '+00', 'yyyy-MM-dd HH:mm:ss' + 'X', new Date()).toISOString()

And as expected,

> "2020-12-03T08:40:00Z".

Is there any proper way of doing this using date-fns? Looking for an equivalent to moment's moment.utc()

3
  • You may want to take a look at developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… You know the offset to adjust the stored date to your time zone. Date-fns-tz has support for Intl.DateTimeFormat. Commented Dec 7, 2020 at 14:22
  • 1
    Either way you should indicate what timezone a datetime value has. You can sinplify your hack: parseIso(toParse+'Z').toISOString() Commented Dec 7, 2020 at 15:37
  • 1
    If "2020-12-03 08:40:00" is parsed as UTC +1, the Z time is 07:40:00Z, not 09:40. :-) Commented Dec 7, 2020 at 20:29

4 Answers 4

14

I don't know about "proper", but you can use zonedTimeToUtc to treat a timestamp as having any offset or timezone you like, including UTC, e.g.

// Setup
var {parse} = require('date-fns');
var {zonedTimeToUtc} = require('date-fns-tz');

// Parse an ISO 8601 timestamp recognised by date-fns
let loc = 'UTC';
let s1   = '2020-12-03 08:30:00';
let utcDate =  zonedTimeToUtc(s1, loc);

// Show UTC ISO 8601 timestamp
console.log(utcDate.toISOString()); // "2020-12-03T08:30:00.000Z"

// Parse non–standard format yyyyMMdd
let s2 = '20210119';
let fIn = 'yyyyMMdd';
let d = zonedTimeToUtc(parse(s2, fIn, new Date()), loc);
console.log(d.toISOString()); // "2021-01-19T00:00:00.000Z"```

You can test it at npm.runkit.com/date-fns.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks that's what I was looking for! However your code does not make use of fIn (fortunately in this example it parses at UTC but the log could have a less friendly format). zonedTimeToUtc(parse(s, fIn, new Date()), loc); works.
@YannP—yes, if the format isn't one recognised by date-fns then you need to add parse. I find the requirement for a Date to always be passed to parse an inexplicable design decision.
Totally agree. I had to add a comment to my pull request to explain why it's "needed"...
5

I think you are looking for parseJSON, which supports a number of formats (but does not let you specify the source format).

Converts a complete ISO date string in UTC time, the typical format for transmitting a date in JSON, to a JavaScript Date instance.

import { parseJSON } from 'date-fns';
const utcDate = parseJSON('2020-12-03 08:40:00');

// Thu Dec 03 2020 19:40:00 GMT+1100 (Australian Eastern Daylight Time)

3 Comments

Yes, parseJSON from date-fns finally worked! I got date strings from SQLite that are in UTC, without explicit timezone. Parsing those date strings using date-fns parse or vanilla JS Date resulted in a modified Date, as a non-UTC timezone was assumed.
This should be the accepted answer, no need for date-fns-tz...
Yes, but you can't use parseJSON('2020-12-03') if you only have a date-only format.
3

Example of using parse and zonedTimeToUtc

 it('should parse polish date', async () => {
    expect.assertions(1)
    const dateWithoutTime = '29 gru 2003'

    const parsed = parse(dateWithoutTime, 'd LLL yyyy', new Date(), {
      locale: pl,
    })

    const dateUTC = zonedTimeToUtc(parsed, 'UTC')

    expect(dateUTC.toISOString()).toStrictEqual('2003-12-29T00:00:00.000Z')
  })

Comments

0

Use the UTC plugin for date-fns:

<script type="module">
  import {parse} from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm'
  import {utc} from 'https://cdn.jsdelivr.net/npm/@date-fns/[email protected]/+esm'
 
  console.log(parse("2020-12-03 08:40:00", "yyyy-MM-dd HH:mm:ss", new Date(), {
    in: utc
  }));
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.