UNPKG

datum-focus

Version:

Data shape, model, metadata, JSON, JSON Schema, GraphQL, MongoDB query and aggregations, iterator generators

101 lines (80 loc) 2.38 kB
export type TimezoneType = string; export class Timezone { static get local(): Timezone { return new Timezone(0, new Date().getTimezoneOffset()); } static parse(tz: string) { let idx = tz.match(/^((?:Z|[+-])(?:2[0-3]|[01][0-9]):[0-5][0-9])$/) ? 4 : tz.match(/^((?:Z|[+-])(?:2[0-3]|[01][0-9])[0-5][0-9])$/) ? 3 : -1; if (idx === -1) { return new Timezone(0, 0); } const s = tz.substr(0, 1) === "-" ? -1 : 1; let h = parseInt(tz.substr(1, 2), 10); let m = parseInt(tz.substr(idx, 2), 10); if (h !== 0) { h *= s; } else { m *= s; } return new Timezone(h, m); } static sanitize( year: number, month: number, date: number, hours: number = 0, minutes: number = 0, seconds: 0, milliseconds: number = 0 ): Date { const d = new Date(Date.UTC(year, 0, 1)); d.setMonth(month, date); d.setHours(hours, minutes, seconds, milliseconds); return d; } static sign(hours: number, minutes: number) { return hours !== 0 ? Math.sign(hours) : Math.sign(minutes); } static stringify(d: Date) { const dt = [ String(d.getFullYear()), String(d.getMonth() + 1).padStart(2, "0"), String(d.getDate()).padStart(2, "0"), ].join("-"); const tm = [ String(d.getHours()).padStart(2, "0"), String(d.getMinutes()).padStart(2, "0"), String(d.getSeconds()).padStart(2, "0"), ].join(":"); const ms = String(d.getMilliseconds()).padStart(3, "0").substr(0, 3); return `${dt}T${tm}.${ms}`; } constructor(hours: number, minutes: number) { const sign = Timezone.sign(hours, minutes); const total: number = hours < 0 ? hours * 60 + Math.abs(minutes) : hours * 60 + minutes; const abs = Math.abs(total); this.hours = (sign * Math.floor(abs / 60)) % 24; this.minutes = abs % 60; if (this.hours === 0) { this.minutes = sign * this.minutes; } const s = sign < 0 ? "-" : "+"; const h = String(Math.abs(this.hours)).padStart(2, "0"); const m = String(Math.abs(this.minutes)).padStart(2, "0"); this.value = `${s}${h}:${m}`; } readonly hours: number; readonly minutes: number; readonly value: string; format(d: Date) { return Timezone.stringify(d) + this.value; } utc(d: Date) { return new Date(this.format(d)); } }