I want to show the moment-timezone list in ascending order in a drop-down menu. By default, those are sorted in alphabetical order. But, my requirement is to sort them by GMT in ascending order.
before soring:
[
'(GMT+00:00) Africa/Abidjan',
'(GMT+00:00) Africa/Accra',
'(GMT+03:00) Africa/Addis_Ababa',
'(GMT+01:00) Africa/Algiers',
'(GMT+03:00) Africa/Asmara',
'(GMT+03:00) Africa/Asmera',
'(GMT+00:00) Africa/Bamako',
'(GMT+01:00) Africa/Bangui',
]
after sorting:
[
'(GMT+00:00) Africa/Abidjan',
'(GMT+00:00) Africa/Accra',
'(GMT+00:00) Africa/Bamako',
'(GMT+01:00) Africa/Algiers',
'(GMT+01:00) Africa/Bangui',
'(GMT+03:00) Africa/Addis_Ababa',
'(GMT+03:00) Africa/Asmera',
'(GMT+03:00) Africa/Asmara',
]
I want to show the moment-timezone list in ascending order in a drop-down menu. By default, those are sorted in alphabetical order. But, my requirement is to sort them by GMT in ascending order.
before soring:
[
'(GMT+00:00) Africa/Abidjan',
'(GMT+00:00) Africa/Accra',
'(GMT+03:00) Africa/Addis_Ababa',
'(GMT+01:00) Africa/Algiers',
'(GMT+03:00) Africa/Asmara',
'(GMT+03:00) Africa/Asmera',
'(GMT+00:00) Africa/Bamako',
'(GMT+01:00) Africa/Bangui',
]
after sorting:
[
'(GMT+00:00) Africa/Abidjan',
'(GMT+00:00) Africa/Accra',
'(GMT+00:00) Africa/Bamako',
'(GMT+01:00) Africa/Algiers',
'(GMT+01:00) Africa/Bangui',
'(GMT+03:00) Africa/Addis_Ababa',
'(GMT+03:00) Africa/Asmera',
'(GMT+03:00) Africa/Asmara',
]
Share
Improve this question
edited Feb 5, 2020 at 14:37
Ashik
asked Feb 5, 2020 at 14:26
AshikAshik
3,44812 gold badges39 silver badges65 bronze badges
2
- actually, it is a large array. so I didn't give it. anyway now it is edited. I think it make sense now. – Ashik Commented Feb 5, 2020 at 14:39
- You may want to consider accepting Clément's answer - it naturally makes use of a function that does exactly what you want. – WoJ Commented Sep 19, 2023 at 20:01
4 Answers
Reset to default 5Shorter than yours, Ashik. No need to access the timezone from the array twice
const getTimeZoneList = moment.tz.names()
.map(t => `(GMT${moment.tz(t).format("Z")}) ${t}`);
const sortByZone = (a,b) => {
let [ahh,amm] = a.split("GMT")[1].split(")")[0].split(":");
let [bhh,bmm] = b.split("GMT")[1].split(")")[0].split(":");
return (+ahh*60+amm) - (+bhh*60+bmm)
};
console.log(getTimeZoneList.sort(sortByZone))
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/moment-timezone/0.5.27/moment-timezone-with-data-2012-2022.min.js"></script>
Solution for the case if we have Moment.js timezone Array of objects(name, value) , or any other Timezone Array of objects with GMT values HARDCODED with us and we want to apply sort on them on GMT values.
export const Timezones = [
{
name: "(GMT-7:00) America/Denver",
value: "America/Denver"
},
{
name: "(GMT+3:00) Africa/Asmara",
value: "Africa/Asmara"
},
{
name: "(GMT-11:00) Pacific/Midway",
value: "Pacific/Midway"
}
];
Then we can sort this Array by
timezones.sort( this.pare );
pare( a, b ) {
var first = a.name.substring(a.name.indexOf('T')+1,a.name.indexOf(")"));
first.replace(/^"+:"+$/g, '');
var second = b.name.substring(b.name.indexOf('T')+1,b.name.indexOf(")"));
first.replace(/^"+:"+$/g, '');
if ( parseFloat(first) < parseFloat(second) ){
return -1;
}
if ( parseFloat(first) > parseFloat(second) ){
return 1;
}
return 0;
}
More simply, there is the utcOffset()
method that provides the offset pared to GMT:
const result = moment.tz.names()
.sort((a, b) => moment.tz(a).utcOffset() - moment.tz(b).utcOffset())
.map(timezone => `(GMT${moment.tz(timezone).format("Z")}) ${timezone}`)
console.log(result)
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/moment-timezone/0.5.27/moment-timezone-with-data-2012-2022.min.js"></script>
You can get the sorted list by doing this
const timeZones = moment.tz.names();
const getTimeZoneList = () =>
timeZones.map(
(t, i) => `(GMT${moment.tz(timeZones[i]).format("Z")}) ${timeZones[i]}`
);
const sortByGmt = () => {
const timeZone = getTimeZoneList();
return timeZone.sort((a, b) => {
const re = /^\(GMT([+-]\d{1,2}):(\d{1,2})\).*$/;
const aOffset = parseFloat(a.replace(re, "$1.$2"));
const bOffset = parseFloat(b.replace(re, "$1.$2"));
return aOffset < bOffset ? -1 : aOffset > bOffset ? 1 : 0;
});
};
console.log(sortByGmt())
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/moment-timezone/0.5.27/moment-timezone-with-data-2012-2022.min.js"></script>