Skip to content

Instantly share code, notes, and snippets.

@vabka
Created March 23, 2021 11:55
Show Gist options
  • Save vabka/c1b5e6c8ff7638527366940ae5f113b4 to your computer and use it in GitHub Desktop.
Save vabka/c1b5e6c8ff7638527366940ae5f113b4 to your computer and use it in GitHub Desktop.
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