0

A response I'm getting from the server is a 'local' timestamp. Which would mean my local time expressed as UTC milliseconds, but without the UTC offset.

For example: 1537747200000 is Mon Sep 24 2018 00:00:00 UTC Mon Sep 24 2018 03:00:00 EEST (my local time), but in my context, this date is actually Mon Sep 24 2018 00:00:00 EEST, so the utc value with my timezone.

I would now like to display this using moment and moment-timezone if needed.

So what I would like to know is how to create a new moment object that takes in "LOCAL milliseconds"? so I'd pass 1537747200000 and my local time zone if needed, and I could display it as Mon Sep 24 2018 00:00:00 EEST


I found that using moment timezone + utcOffset does the trick, but I don't really know if this is a good approach. utc offset docs says this:

Setting the UTC offset by supplying minutes. Note that once you set an offset, it's fixed and won't change on its own (i.e there are no DST rules). If you want an actual time zone -- time in a particular location, like America/Los_Angeles, consider moment-timezone.


Another approach would be to format the moment to ISOString moment(1537747200000).toISOString() and then parse the resulting string, without the timezone information (the 'z'). When parsing a string, you can parse it in another timezone. moment.tz(moment(1537747200000).toISOString().slice(0, -1), tz). But this requires that I parse->format->parse the value, so it's a lot of extra operations.


const [one, two, thr] = ["exp","tr","appr"];
const display = (toAdd, id) => document.getElementById(id).innerHTML += `<br/> ${toAdd}`;


const formatString = "MMM D, YYYY HH:mm z";
const tz = moment.tz.guess();
const millis_24_sep_00_00_utc = moment.utc("24-09-2018", "DD-MM-YYYY", true).valueOf(); //1537747200000
const isoString = moment(millis_24_sep_00_00_utc).toISOString();

//exp
display(tz, one);
display(millis_24_sep_00_00_utc, one);
const ex = moment.tz(millis_24_sep_00_00_utc, tz).utc().format("MMM D, YYYY HH:mm")
display(`${ex} ${moment().tz(tz).zoneAbbr()} <- local tz`, one);

//tr
[
  moment(millis_24_sep_00_00_utc).tz(tz),
  moment.utc(new Date(millis_24_sep_00_00_utc)).tz(tz),
  moment.tz(millis_24_sep_00_00_utc, tz).utc(),
  moment.tz(isoString, tz),
]
.forEach(mom => display(mom.format(formatString), two));

//some approaches
[
//setting utcOffset to 0
  moment.tz(millis_24_sep_00_00_utc, tz).utcOffset(0),
//iso string to transform millis -> string -> parse the string in another tz
  moment.tz(isoString.slice(0, -1), tz),
]
.forEach(mom => display(mom.format(formatString), thr));
<!DOCTYPE html>
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.21/moment-timezone-with-data.js"></script>
  <title>Test</title>
</head>
<body>
 <div id="exp">EXPECTED</div>
 <hr/>
 <div id="tr">TRIES</div>
 <hr/>
 <div id="appr">APPROACHES</div>
</body>

</html>
knee pain
  • 600
  • 3
  • 19
  • From what source are you getting a local-time timestamp value like that? System timestamp values are almost always UTC epochal offsets. – Pointy Sep 24 '18 at 13:06
  • Yeah, I know that, but in this case is somewhat like this: saved local timestamp, and then the milliseconds taken out of it, without offset information. I know this isn't usual. – knee pain Sep 24 '18 at 13:08
  • Unfortunately if you have a timestamp without a timezone and you don't know the offset through independent means, then you can only guess at the offset. They range from +14 (LNT, TOST) to -11 (NUT, SST). :-( – RobG Sep 25 '18 at 22:23

1 Answers1

0

It's unusual to provide a millisecond time value that has been offset. But if your time values are offset by +3 hours then you can subtract 3 hours worth of milliseconds (1.08e7) and use it as a UTC time value.

E.g. A time value of 1537747200000 typically represents 2018-09-24T00:00:00.000Z. If that time value actually represents 2018-09-24T00:00:00.000+0300, then the equivalent UTC time value is:

1537747200000 - 1.08e7 = 1537736400000;

Working example:

var d = new Date(1537747200000 - 1.08e7);
console.log(`Zulu: ${d.toISOString()}\nLocal: ${d.toString()}`);
RobG
  • 142,382
  • 31
  • 172
  • 209
  • It is unusual indeed. The thing here is that I can't really hardcode the 3 hours worth of milliseconds, since it may not always be in this timezone – knee pain Sep 25 '18 at 12:28