Skip to content

Commit

Permalink
[1.x] [Labs] Add useManualCalc prop to TimezonePicker as speed optimi…
Browse files Browse the repository at this point in the history
…zation (#2564)

* Add useManualCalculation flag for TimezonePicker

* Comments

* Remove useManualCalc fork

* Don't use excess variables and template string
  • Loading branch information
philcchen authored and giladgray committed Jun 11, 2018
1 parent bbdcb2e commit 06f6bbc
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ export function getInitialTimezoneItems(date: Date, includeLocalTimezone: boolea
export function getLocalTimezoneItem(date: Date): ITimezoneItem | undefined {
const timezone = getLocalTimezone();
if (timezone !== undefined) {
const timestamp = date.getTime();
const zonedDate = moment.tz(timestamp, timezone);
const offsetAsString = zonedDate.format("Z");
const { offsetAsString } = getTimezoneMetadata(timezone, date);
return {
iconName: "locate",
key: `${timezone}-local`,
Expand Down
55 changes: 32 additions & 23 deletions packages/labs/src/components/timezone-picker/timezoneMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,47 @@ export interface ITimezoneMetadata {
}

export function getTimezoneMetadata(timezone: string, date: Date): ITimezoneMetadata {
const timestamp = date.getTime();
const zone = moment.tz.zone(timezone);
const zonedDate = moment.tz(timestamp, timezone);
const offset = zonedDate.utcOffset();
const offsetAsString = zonedDate.format("Z");
const abbreviation = getAbbreviation(timezone, timestamp);

const { abbrs, offsets, population, untils } = moment.tz.zone(timezone);
const index = findOffsetIndex(date.getTime(), untils);
const offset = offsets[index] * -1;
return {
abbreviation,
abbreviation: getNonOffsetAbbreviation(abbrs[index]),
offset,
offsetAsString,
population: zone.population,
offsetAsString: getOffsetAsString(offset),
population,
timezone,
};
}

/**
* Get the abbreviation for a timezone.
* We need this utility because moment-timezone's `abbr` will not always give the abbreviated time zone name,
* since it falls back to the time offsets for each region.
* https://momentjs.com/timezone/docs/#/using-timezones/formatting/
* Ignore abbreviations that are simply offsets, i.e. "+14" instead of "PST"
* @param abbreviation
*/
function getAbbreviation(timezone: string, timestamp: number): string | undefined {
const zone = moment.tz.zone(timezone);
if (zone) {
const abbreviation = zone.abbr(timestamp);

// Only include abbreviations that are not just a repeat of the offset
if (abbreviation.length > 0 && abbreviation[0] !== "-" && abbreviation[0] !== "+") {
return abbreviation;
function getNonOffsetAbbreviation(abbreviation: string) {
return isNonOffsetAbbreviation(abbreviation) ? abbreviation : undefined;
}

function isNonOffsetAbbreviation(abbreviation: string) {
return abbreviation != null && abbreviation.length > 0 && abbreviation[0] !== "-" && abbreviation[0] !== "+";
}

function findOffsetIndex(timestamp: number, untils: number[]) {
for (let i = 0; i < untils.length; i++) {
if (i === untils.length - 1 || timestamp < untils[i]) {
return i;
}
}
return 0;
}

function getOffsetAsString(offset: number) {
const offsetVal = Math.abs(offset);
const minutes = offsetVal % 60;
const hours = (offsetVal - minutes) / 60;
const sign = offset >= 0 ? "+" : "-";
return `${sign}${lpad(hours)}:${lpad(minutes)}`;
}

return undefined;
function lpad(num: number) {
return num < 10 ? "0" + num : num;
}

1 comment on commit 06f6bbc

@blueprint-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[1.x] [Labs] Add useManualCalc prop to TimezonePicker as speed optimization (#2564)

Preview: documentation | landing | table | github pages

Please sign in to comment.