@sytexa/tzdb
Version:
Always up to date list of time zones, with grouping and major cities
75 lines (61 loc) • 2.05 kB
JavaScript
import timeZoneNames from "../time-zones-names.json";
import { getZoneOffset } from "./utils/timeZone.js";
export default function getUngroupedTimeZones(opts) {
const includeUtc = !!opts && opts.includeUtc;
const baseZoneName = (opts && opts.baseZone) || "UTC";
return timeZoneNames
.reduce(
function (acc, timeZoneName) {
const currentOffset = getZoneOffset(timeZoneName);
// We build on the latest Node.js version, Node.js embed IANA databases
// it might happen that the environment that will execute getTimeZones() will not know about some
// timezones. So we ignore the timezone at runtim
// See https://github.com/vvo/tzdb/issues/43
if (currentOffset === false) {
return acc;
}
const simpleZone = {
name: timeZoneName,
currentTimeOffsetInMinutes: currentOffset,
};
acc.push({
...simpleZone,
currentTimeFormat: format(
simpleZone,
{ baseZoneName },
),
});
return acc;
},
includeUtc ? [utcTimezone] : [],
)
.sort((a, b) => {
return compareNumbers(a, b) || compareStrings(a.name, b.name);
});
}
function compareNumbers(x, y) {
return x.currentTimeOffsetInMinutes - y.currentTimeOffsetInMinutes;
}
function compareStrings(x, y) {
if (typeof x === "string" && typeof y === "string") {
return x.localeCompare(y);
}
return 0;
}
function format(
{ name, currentTimeOffsetInMinutes },
{ baseZoneName = "UTC" },
) {
const offsetInHours = getOffsetHoursString(currentTimeOffsetInMinutes);
return `(${baseZoneName} ${offsetInHours}) ${name.replace(/_/g, " ")}`;
}
function getOffsetHoursString(offsetInMinutes) {
const absOffsetInMinutes = Math.abs(offsetInMinutes);
const hours = absOffsetInMinutes / 60;
return `${offsetInMinutes >= 0 ? "+" : "-"}${hours}`;
}
const utcTimezone = {
name: "UTC",
currentTimeOffsetInMinutes: 0,
currentTimeFormat: "(UTC) Coordinated Universal Time",
};