0

I have found many examples on the internet of converting from seconds or milliseconds to a JavaScript Date, but only a few for converting from days to a Date object. When I tried these examples in my own code (with my own values), I was unable to replicate their results.

My API returns an integer value representing days since UNIX epoch. I need to find a way to convert this to a JavaScript date object, so that I can display it in a human readable format.

For example:

new Date(18521 * 86400 * 1000)
// multiply by 86400 (seconds in a day), then by 1000 to convert to milliseconds.

At the time of writing, the date is 9/17/2020 MMDDYYYY, and 18522 days have passed since UNIX epoch. However, when I try to retrieve yesterday's UNIX date 18521 using the date constructor with some math (mentioned above), I get the incorrect date: Sep 15 2020. I would expect to get (Sep 16 2020) since I have only subtracted one day, but for some reason that is not the case.

Is there anything I am doing incorrectly here? What should I change to make my code work?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Jaeheon Shim
  • 491
  • 5
  • 14
  • 1
    18522 is Septemeber 16th, not Septemeber 17th EDT. What does your GMT offset timestamp say? – jmargolisvt Sep 17 '20 at 19:53
  • 4
    It might be a time zone issue. Remember that unix epoch is in UTC. – Cully Sep 17 '20 at 19:53
  • If the issue is that you're always off by one day from what you want, just add a day. Though do consider the timezone issue. You might, for example, get the date you want if you tried at a certain time of day (because it happens to line up with the UTC). – Cully Sep 17 '20 at 19:54
  • @Cully I was about to go with that solution, but I wanted to absolutely make sure that it would work in all scenarios – Jaeheon Shim Sep 17 '20 at 19:55
  • @jmargolisvt -4 – Jaeheon Shim Sep 17 '20 at 19:55
  • That makes sense then. Add 4 hours to that time stamp and you're in the next day UTC. – jmargolisvt Sep 17 '20 at 19:56
  • @jmargolisvt that worked, thank you! – Jaeheon Shim Sep 17 '20 at 19:57
  • 1
    "My API returns an integer value representing days since UNIX epoch" ---> if you control that API endpoint I would strongly suggest that you return a more appropriate and accurate value - that will obviate the need for the rigmarole of conversion. Besides, you cannot have "days" from epoch without also having a timezone. and would it represent the start of a day, or the end of the day? in other words: the API as it currently stands is likely going to lead to confusion, plus you're adding further layers of complications to manage that. In short: I would change the API if I control it. – BenKoshy Sep 17 '20 at 23:04

1 Answers1

1

The way you're doing it is correct. There are always 8.64e7 ms in an ECMAScript UTC day and ECMASCript and Java have the same epoch. The way you're doing it sets the UTC date to the correct value (which is the right way to do it), not the local date. The default toString shows the local date so if the host is set to a negative offset, it will show one day earlier.

So get the UTC date instead:

new Date(18521 * 8.64e7).toISOString() //2020-09-16T00:00:00.000Z.

If you want to do this with a local date, then create a date for Jan 1970 and set the "date" parameter to the day count plus 1 (because January starts on 1 not 0):

console.log('UTC  : ' + new Date(18521 * 8.64e7).toISOString() +
  '\nLocal: ' + new Date(1970, 0, 18521 + 1).toDateString());
RobG
  • 142,382
  • 31
  • 172
  • 209