Home > Software engineering >  Get Date from epochMilli and timezone offset in seconds using javascript
Get Date from epochMilli and timezone offset in seconds using javascript

Time:12-15

I have the following returned from an event,

"epochMilli": 1669288500000,
"timezoneOffsetInSeconds": -18000

I need to use this and convert it to a date to get day, month and year using JavaScript.

I wasn't able to find any function in JavaScript to do this. I found the same in Java:

OffsetDateTime offsetdatetime = Instant.ofEpochSecond(time).atOffset(ZoneOffset.ofTotalSeconds(offset));
LocalDate localdate = offsetDateTime.toLocalDate();

How to accomplish the same in JavaScript?

CodePudding user response:

i'd suggest using a library such as luxon to do get the time in a different time zone.

You can create a FixedTimeZone object to represent the zone in question, passing in the offset in minutes.

We can now create a DateTime in that zone, using DateTime.fromMillis, and passing the zone object to the function.

The year, month, day values can be retrieved from their respective properties.

const { DateTime, FixedOffsetZone } = luxon;

const epochMilli = 1669288500000;
const timezoneOffsetInSeconds = -18000;

const zone = new FixedOffsetZone(timezoneOffsetInSeconds / 60)
const dt = DateTime.fromMillis(epochMilli, { zone });

console.log('Year:', dt.year);
console.log('Month:', dt.month);
console.log('Day:', dt.day);

console.log('Date (formatted):', dt.toFormat('yyyy-MM-dd HH:mm:ss'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/3.0.1/luxon.min.js" integrity="sha512-6ZJuab/UnRq1muTChgrVxJhSgygmL2GMLVmSJN7pcBEqJ1dWPbqN9CiZ6U3HrcApTIJsLnMgXYBYgtVkJ8fWiw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

CodePudding user response:

Assuming you want the year/month/day according to the time zone with the provided offset, you can do this fairly easily. The key is to only use the UTC* methods of the Date object, and to adjust the milliseconds by the offset before calling any of those methods. This is NOT clear code... it'd need to be exhaustively commented to explain to readers that it's not actually a UTC value being read, but rather you're abusing Date to pretend it's a UTC value in order to read the date.

function getDateInOffsetTimeZone(epochMilli, offsetSeconds) {
  const adjustedMilli = epochMilli   offsetSeconds * 1000;
  const date = new Date(adjustedMilli);
  return { year: date.getUTCFullYear(), month: date.getUTCMonth()   1, day: date.getUTCDate() };
}

getDateInOffsetTimeZone(1669288500000, -18000);
// => { year: 2022, month: 11, day: 24 }

Or you could write this in Temporal, the improved, coming-soon date/time API for JavaScript, which provides a clearer way to get the date without manually calculating the offset and lying about using UTC.

import { Temporal } from '@js-temporal/polyfill';

function getDateInOffsetTimeZone(epochMilli, offsetSeconds) {
  const instant = Temporal.Instant.fromEpochMilliseconds(epochMilli);
  const offsetSign = offsetSeconds < 0 ? '-' : ' ';
  const offsetAsTime = new Temporal.PlainTime().add({ seconds: Math.abs(offsetSeconds) });
  const offsetString = `${offsetSign}${offsetAsTime.toString()}`;
  return instant.toZonedDateTimeISO(offsetString).toPlainDate();
}

getDateInOffsetTimeZone(1669288500000, -18000);
// => a Temporal.PlainDate object with { year: 2022, month: 11, day: 24 }

Note that the same UTC-abuse trick works in Temporal too, although as noted above I wouldn't recommend this because it's potentially confusing to readers.

function getDateInOffsetTimeZone(epochMilli, offsetSeconds) {
  const adjustedMilli = epochMilli   offsetSeconds * 1000;
  const instant = Temporal.Instant.fromEpochMilliseconds(adjustedMilli);
  return instant.toZonedDateTimeISO('UTC').toPlainDate();
}

getDateInOffsetTimeZone(1669288500000, -18000);
// => a Temporal.PlainDate object with { year: 2022, month: 11, day: 24 }
  • Related