35

I want to get a ISO-8601 format of last hour:minute:secounds from the current day using date-fns lib:

I'm using: endOfDay(new Date());

Fri Sep 14 2018 23:59:59 GMT-0300

So add toISOString() to get it in ISO format: endOfDay(new Date()).toISOString()

Result: 2018-09-15T02:59:59.999Z

When I need:

2018-09-14T23:59:59.999Z

Joel
  • 974
  • 2
  • 10
  • 18
  • I believe it is because your date is in UTC. Maybe trying to calculate the timezone offset, and applying that to your date would work. For example, you are GMT-0300; 3 hours ahead of UTC. To get the time for your timezone, you'd need to go back three hours. Although, this is all based on 10 minutes of research. I'm no date formatting expert :) – Wingnod Sep 14 '18 at 15:23

2 Answers2

41

2018-09-14T23:59:59.999Z is not the end of day computed by endOfDay(new Date());. It is 3 hours earlier. The "Z" means UTC and your local time zone has the offset to UTC -0300.

By executing endOfDay you get a date value, which you can use in comparisons and other computations with other date values. It is a complete date with time in the local time zone.

Do you want to retain the same day number in the formatted string? You can format the date to an ISO 8601 string in your local time zone:

format(endOfDay(new Date()), 'yyyy-MM-dd\'T\'HH:mm:ssXX')
// Prints "2018-09-14T23:59:59.999-0300" in Brazil (BRT)

formatISO(endOfDay(new Date()))
// Prints "2018-09-14T23:59:59.999-03:00" in Brazil (BRT)

Do you want to get the end of the day with the same number as today in UTC? If you disregard the actual end of your day in relation to other dates, you can just concatenate the "last second of the day" with "Z" to it:

format(new Date(), 'yyyy-MM-dd') + 'T23:59:59.999Z'
// Prints "2018-09-14T23:59:59.999Z" anywhere on Earth

NOTE: If you use date-fns 1.x, use formats yyyy-MM-DD[T]HH:mm:ssZZ and yyyy-MM-DD in the patterns above. The syntax changed in 2.x versions. See also the supported patterns, which you can switch to your version of date-fns.

Ferdinand Prantl
  • 5,281
  • 34
  • 35
  • 7
    RangeError: Use `yyyy` instead of `YYYY` (in `YYYY-MM-DD[T]HH:mm:ssZZ`) for formatting years... – shs May 02 '21 at 18:18
  • 1
    Thanks for mentioning this, @shs! It appears to be a breaking change in date-fns 2.x, where `Y` [became the week-numbering year](https://date-fns.org/v2.24.0/docs/format), while the calendar year was changed to `y` . `Y` meant calendar year [in date-fns 1.x](https://date-fns.org/v1.30.1/docs/format). – Ferdinand Prantl Oct 05 '21 at 00:17
  • 1
    For future refrence. If you read the above answer of Ferdinand, you will notice he has used `format` and if you were to use the exact same in your project and `console.log` then the output would be something like this: `2022-08-08[1659985199999]23:59:59`. Notice instead of `T` inbetween the date and time as a delimitor you have the literal timestamp. To fix this just import `formatISO`. – Ali Mustafa Aug 08 '22 at 15:08
  • 1
    Thanks, @AliMustafa! Yes, `formatISO` is the simplest way to get an ISO 860 output. – Ferdinand Prantl Aug 18 '22 at 18:10
6
format(endOfDay(new Date()), "yyyy-MM-dd'T'HH:mm:ss'Z'")

This method worked for me

  • 2
    Nope. This prints the current local time with a literal 'Z'. That is not correct. Looks like we now have a native ISO formatting function. `var formatISO = require('date-fns/formatISO'); formatISO(new Date());` will give what we're after. – ankush981 Jul 29 '22 at 06:07