All files / src/types UtcDate.ts

100% Statements 58/58
100% Branches 44/44
100% Functions 12/12
100% Lines 58/58

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                      1x     31x 31x 31x 31x 31x       1x       2x       1x       3x 3x 3x 3x 3x 3x       7x       1x       4x 4x 4x 2x 2x                   2x 2x 2x 2x 2x 2x 2x       2x 2x 2x 2x 2x 2x 2x       13x 2x 11x 2x 9x 1x 8x 1x 7x 1x 6x 1x 5x 1x 4x 1x 3x 1x 2x 1x 1x       1x                                    
import type { ITypeBuilder } from '../typeBuilder';
import type { Flattable } from '../types/Flattable';
 
type UtcDateComponents = {
    year: number;
    month: number;
    day: number;
    hour: number;
    minute: number;
};
 
export class UtcDate implements Flattable<UtcDate.Flatten> {
 
    public constructor(
        public readonly year: number,
        public readonly month: number,
        public readonly day: number,
        public readonly hour: number,
        public readonly minute: number
    ) {}
 
    public static get now(): UtcDate {
        return UtcDate.fromDate(new Date());
    }
 
    public get toDate(): Date {
        return new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute));
    }
 
    public get toIsoDate(): string {
        return this.toDate.toISOString();
    }
 
    public get encoded(): string {
        const year = this.year.toString();
        const month = this.month <= 9 ? `0${this.month}` : this.month.toString();
        const day = this.day <= 9 ? `0${this.day}` : this.day.toString();
        const hour = this.hour <= 9 ? `0${this.hour}` : this.hour.toString();
        const minute = this.minute <= 9 ? `0${this.minute}` : this.minute.toString();
        return `${year}-${month}-${day}-${hour}-${minute}`;
    }
 
    public static fromDate(date: Date): UtcDate {
        return new UtcDate(date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes());
    }
 
    public static fromIsoDate(date: string): UtcDate {
        return UtcDate.fromDate(new Date(date));
    }
 
    public static decode(encodedDate: string): UtcDate {
        const regex = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})-(?<hour>\d{2})-(?<minute>\d{2})$/gu;
        const match = regex.exec(encodedDate);
        if (match?.groups === undefined)
            return new UtcDate(0, 0, 0, 0, 0);
        return new UtcDate(
            Number.parseInt(match.groups.year),
            Number.parseInt(match.groups.month),
            Number.parseInt(match.groups.day),
            Number.parseInt(match.groups.hour),
            Number.parseInt(match.groups.minute)
        );
    }
 
    public setted(components: Partial<UtcDateComponents>): UtcDate {
        const date = new Date(Date.UTC(this.year, this.month, this.day, this.hour, this.minute));
        date.setUTCFullYear(components.year ?? date.getUTCFullYear());
        date.setUTCMonth((components.month ?? date.getUTCMonth()) - 1);
        date.setUTCDate(components.day ?? date.getUTCDate());
        date.setUTCHours(components.hour ?? date.getUTCHours());
        date.setUTCMinutes(components.minute ?? date.getUTCMinutes());
        return UtcDate.fromDate(date);
    }
 
    public advanced(components: Partial<UtcDateComponents>): UtcDate {
        const date = new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute));
        date.setUTCFullYear(date.getUTCFullYear() + (components.year ?? 0));
        date.setUTCMonth(date.getUTCMonth() + (components.month ?? 0));
        date.setUTCDate(date.getUTCDate() + (components.day ?? 0));
        date.setUTCHours(date.getUTCHours() + (components.hour ?? 0));
        date.setUTCMinutes(date.getUTCMinutes() + (components.minute ?? 0));
        return UtcDate.fromDate(date);
    }
 
    public compare(other: UtcDate): 'less' | 'equal' | 'greater' {
        if (this.year < other.year)
            return 'less';
        else if (this.year > other.year)
            return 'greater';
        if (this.month < other.month)
            return 'less';
        else if (this.month > other.month)
            return 'greater';
        if (this.day < other.day)
            return 'less';
        else if (this.day > other.day)
            return 'greater';
        if (this.hour < other.hour)
            return 'less';
        else if (this.hour > other.hour)
            return 'greater';
        if (this.minute < other.minute)
            return 'less';
        else if (this.minute > other.minute)
            return 'greater';
        return 'equal';
    }
 
    public get flatten(): UtcDate.Flatten {
        return this.encoded;
    }
}
 
// istanbul ignore next
export namespace UtcDate {
 
    export type Flatten = string;
 
    export class TypeBuilder implements ITypeBuilder<Flatten, UtcDate> {
 
        public build(value: Flatten): UtcDate {
            return UtcDate.decode(value);
        }
    }
 
    export const builder = new TypeBuilder();
}