Hello,
I am looking for a way to generate Posix TZ Strings with given timezone. Is it possible to generate with moment-timezone?
Nope, and not recommended, for the reasons described in the timezone tag wiki on StackOverflow. (Scroll down to the second-to-last section titled "POSIX style time zones")
I'm curious though - what is the use case? Why do you want them?
Also, the advice on the link you gave is highly applicable:
Caution: edit this file at your own risk. We have provided some TZ values that we believe are correct but we offer no guarantees on their validity.
It's up to you to derive the correct POSIX.1 TZ string for any new time zones you want to add. If the politicians in the zone in question mess around with the timing of daylight saving every year, you will have to edit the file to suit every year, too.
And guess what - politicians do indeed do this each and every year!
Hello,
Thanks. We are working on IoT devices which have no TZ database built inside and we have make them timezone-aware, especially for the DST. I am planing to build a service with _moment-timezone_ on _AWS Lambda_ and _API Gateway_ for IoT devices, when devices query with relevant timezone, the service return POSIX-style timezone for them and the firmware in the device will configure itself properly. Is it a good solution or is there any other recommended approaches?
Thanks again.
Ok, I can understand that use case. I'll post some code shortly.
Ok, so here is a whole bunch of code to throw at you. :smile:
A few caveats first:
Ok, here's the code already.
function getPosixStringForCurrentYear(tz) {
var jan = moment.tz({month: 0, day: 1}, tz);
var jun = moment.tz({month: 5, day: 1}, tz);
var janOffset = jan.utcOffset();
var junOffset = jun.utcOffset();
var stdOffset = Math.min(janOffset, junOffset);
var dltOffset = Math.max(janOffset, junOffset);
var std = stdOffset === janOffset ? jan : jun;
var dlt = dltOffset === janOffset ? jan : jun;
var s = formatAbbreviationForPosix(std).concat(formatOffsetForPosix(stdOffset));
if (stdOffset !== dltOffset) {
s = s.concat(formatAbbreviationForPosix(dlt));
if (dltOffset !== stdOffset + 60) {
s = s.concat(formatOffsetForPosix(dltOffset));
}
s = s.concat(',').concat(formatTransitionForPosix(tz, std));
s = s.concat(',').concat(formatTransitionForPosix(tz, dlt));
}
return s;
}
function formatAbbreviationForPosix(m) {
var a = m.format('z');
return /^[\+\-\d]+$/.test(a) ? '<'.concat(a).concat('>') : a;
}
function formatOffsetForPosix(offset) {
var h = -offset / 60 | 0;
var m = Math.abs(offset % 60);
return h + (m === 0 ? '' : ':'.concat(m < 10 ? '0' : '').concat(m));
}
function formatTransitionForPosix(tz, m) {
var zone = moment.tz.zone(tz);
var ts = zone.untils[zone._index(m)];
if (!isFinite(ts)) {
return "J365/25";
}
var transition = moment(ts).utcOffset(-zone.utcOffset(ts - 1));
var n = ((transition.date() - 1) / 7 | 0) + 1;
var s = transition.format('[M]M.[n].d').replace('n', n);
var time = transition.format('[/]H:mm:ss').replace(/\:00$/, '').replace(/\:00$/, '');
if (time !== '/2') {
s = s.concat(time);
}
return s;
}
Some examples:
getPosixStringForCurrentYear('America/New_York') // "EST5EDT,M3.2.0,M11.1.0"
getPosixStringForCurrentYear('Australia/Sydney') // "AEST-10AEDT,M10.1.0,M4.1.0/3"
getPosixStringForCurrentYear('America/Havana') // ""CST5CDT,M3.2.0/0,M11.1.0/1"
getPosixStringForCurrentYear('Europe/London') // "GMT0BST,M3.4.0/1,M10.4.0"
getPosixStringForCurrentYear('Australia/Lord_Howe') // "<+1030>-10:30<+11>-11,M10.1.0,M4.1.0"
getPosixStringForCurrentYear('Pacific/Chatham') // "<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45"
getPosixStringForCurrentYear('Europe/Astrakhan') // "<+04>-4"
Note, I updated the code above to handle some edge cases. Really this should be unit tested. :wink:
THANK YOU SO MUCH!!!!
After some discussion with the moment core team, we've decided not to include this in the moment-timezone API at this time. However, we will move it to a separate utility script and add some unit tests. That way we can be sure we don't break it in future releases. You'd still need to download the script separately to use it.
I understand. Thank you!
Note - there was a bug in the code above in the formatTransitionForPosix function. I have updated it, and the examples.
Awesome! Thank you!
Given Moment's project status update and the age of this issue, I am closing this. You can still use the code sample, but we won't be adding it to the repository in the way I suggested above.
Most helpful comment
Ok, so here is a whole bunch of code to throw at you. :smile:
A few caveats first:
Ok, here's the code already.
Some examples: