Created
March 23, 2021 11:55
-
-
Save vabka/c1b5e6c8ff7638527366940ae5f113b4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class CalendarDate { | |
private readonly date: Date; | |
constructor(date: Date) { | |
this.date = new Date(date); | |
} | |
public static today(): CalendarDate { | |
return new CalendarDate(new Date()); | |
} | |
public static parseUTC(value: string): CalendarDate { | |
return new CalendarDate(new Date(value)); | |
} | |
public static create(year: number, month: number, day: number): CalendarDate { | |
return new CalendarDate(new Date(year, month - 1, day)); | |
} | |
/* | |
Parses dd.MM.yyyy and dd.MM.yy format of dates | |
@returns parsed date or null, when invalid format | |
*/ | |
public static parseRussian(value: string): CalendarDate | null { | |
const tokens = value.split('.'); | |
if (tokens.length === 3) { | |
const day = parseInt(tokens[0], 10); | |
const month = parseInt(tokens[1], 10); | |
let year = parseInt(tokens[2], 10); | |
if (year < 100) year += 2000; | |
return new CalendarDate(new Date(year, month - 1, day)); | |
} | |
return null; | |
} | |
public get year(): number { | |
return this.date.getFullYear(); | |
} | |
public get month(): number { | |
return this.date.getMonth() + 1; | |
} | |
public get day(): number { | |
return this.date.getDate(); | |
} | |
public compare(other: CalendarDate): 'greater' | 'equal' | 'less' { | |
if (this.year > other.year) return 'greater'; | |
if (this.year < other.year) return 'less'; | |
if (this.month > other.month) return 'greater'; | |
if (this.month < other.month) return 'less'; | |
if (this.day > other.day) return 'greater'; | |
if (this.day < other.day) return 'less'; | |
return 'equal'; | |
} | |
public addYears(value: number): CalendarDate { | |
const copy = new Date(this.year + value, this.month - 1, this.day); | |
return new CalendarDate(copy); | |
} | |
public addMonths(value: number): CalendarDate { | |
const copy = new Date(this.year, this.month - 1 + value, this.day); | |
return new CalendarDate(copy); | |
} | |
public addDays(value: number): CalendarDate { | |
const copy = new Date(this.year, this.month - 1, this.day + value); | |
return new CalendarDate(copy); | |
} | |
public ge(other: CalendarDate): boolean { | |
const comp = this.compare(other); | |
return comp === 'greater' || comp === 'equal'; | |
} | |
public le(other: CalendarDate): boolean { | |
const comp = this.compare(other); | |
return comp === 'less' || comp === 'equal'; | |
} | |
public gt(other: CalendarDate): boolean { | |
const comp = this.compare(other); | |
return comp === 'greater'; | |
} | |
public lt(other: CalendarDate): boolean { | |
const comp = this.compare(other); | |
return comp === 'less'; | |
} | |
public equal(other: CalendarDate): boolean { | |
const comp = this.compare(other); | |
return comp === 'equal'; | |
} | |
public toDate(): Date { | |
return new Date(this.date); | |
} | |
/* | |
Implementation of gregorian->JDN conversion | |
<br> | |
https://ru.wikipedia.org/wiki/Юлианская_дата#Вычисление_юлианской_даты_по_дате_календаря | |
@return Julian Day Number of date | |
*/ | |
public getJDN(): number { | |
const a = Math.floor((14 - this.month) / 12); | |
const y = this.year + 4800 - a; | |
const m = this.month + 12 * a - 3; | |
return ( | |
this.day + | |
Math.floor((153 * m + 2) / 5) + | |
365 * y + | |
Math.floor(y / 4) - | |
Math.floor(y / 100) + | |
Math.floor(y / 400) - | |
32045 | |
); | |
} | |
public formatAsRussia(): string { | |
return `${this.day.toString().padStart(2, '0')}.${this.month.toString().padStart(2, '0')}.${this.year}`; | |
} | |
public formatUTC(): string { | |
return `${this.year}-${this.month.toString().padStart(2, '0')}-${this.day.toString().padStart(2, '0')}`; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment