Skip to content

Commit

Permalink
Improve IANAZone.offset performance
Browse files Browse the repository at this point in the history
  • Loading branch information
mohd-akram committed Sep 8, 2023
1 parent 35a50c2 commit d8f8f69
Showing 1 changed file with 51 additions and 11 deletions.
62 changes: 51 additions & 11 deletions src/zones/IANAZone.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import { formatOffset, parseZoneInfo, isUndefined, objToLocalTS } from "../impl/util.js";
import Zone from "../zone.js";

let hasLongOffset = true;
try {
new Intl.DateTimeFormat("en-US", { timeZoneName: "longOffset" });
} catch (e) {
hasLongOffset = false;
}

let dtfCache = {};
function makeDTF(zone) {
if (!dtfCache[zone]) {
dtfCache[zone] = new Intl.DateTimeFormat("en-US", {
hour12: false,
timeZone: zone,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
era: "short",
});
dtfCache[zone] = new Intl.DateTimeFormat(
"en-US",
hasLongOffset
? {
timeZone: zone,
timeZoneName: "longOffset",
year: "numeric",
}
: {
hour12: false,
timeZone: zone,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
era: "short",
}
);
}
return dtfCache[zone];
}
Expand Down Expand Up @@ -52,6 +68,28 @@ function partsOffset(dtf, date) {
return filled;
}

function longOffset(dtf, ts) {
let formatted;

try {
formatted = dtf.format(ts);
} catch (e) {
return NaN;
}

const idx = formatted.search(/GMT([+-][0-9][0-9]:[0-9][0-9](:[0-9][0-9])?)?/);
const sign = formatted.charCodeAt(idx + 3);

if (isNaN(sign)) return 0;

return (
(44 - sign) *
(Number(formatted.slice(idx + 4, idx + 6)) * 60 +
Number(formatted.slice(idx + 7, idx + 9)) +
Number(formatted.slice(idx + 10, idx + 12) / 60))
);
}

let ianaZoneCache = {};
/**
* A zone identified by an IANA identifier, like America/New_York
Expand Down Expand Up @@ -145,6 +183,8 @@ export default class IANAZone extends Zone {

/** @override **/
offset(ts) {
if (hasLongOffset) return longOffset(makeDTF(this.name), ts);

const date = new Date(ts);

if (isNaN(date)) return NaN;
Expand Down

0 comments on commit d8f8f69

Please sign in to comment.