All files / src/lib/forms/adapters date-picker-utc-adapter.ts

100% Statements 60/60
100% Branches 28/28
100% Functions 19/19
100% Lines 56/56

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 1181x       1x       1x     82x 82x     1x 3x     1x 3x     1x 8x   7x 7x   7x     1x 3x     1x 3x     1x 3x     1x 6x     1x 3x     1x 3x     1x 3x         1x 3x     1x 3x     1x 3x     1x 9x     1x 34x   33x 23x   23x 15x             8x     10x       1x 6x 6x   6x 6x     1x 14x   14x 14x 14x   14x   1x  
import {Inject, Injectable, LOCALE_ID, Optional} from '@angular/core';
 
import {DayWithMetadata} from '../interfaces/DayWithMetadata';
import {DateRangeValidationParams} from '../interfaces/DateRangeValidationParams';
import {DateAdapter, getMonths, localize, parseInput, getWeekdays} from '../services/date-picker.service';
 
@Injectable()
// Adapter for UTC dates
export class UTCDateAdapter implements DateAdapter<Date> {
    private readonly languageCode: string;
 
    constructor(@Optional() @Inject(LOCALE_ID) private _locale?: string) {
        this.languageCode = (_locale) ? _locale.split('-')[0] : 'en';
    }
 
    public dayOfFirst(year: number, month: number): number {
        return new Date(year, month, 1).getDay();
    }
 
    public daysInMonth(year: number, month: number): number {
        return new Date(year, month + 1, 0).getDate();
    }
 
    public isDisabled(evalDate: Date, dateRangeParams: DateRangeValidationParams): boolean {
        if (!dateRangeParams) { return false; }
 
        const dayIsBeforeMinDate = (dateRangeParams.minDate) ? evalDate < dateRangeParams.minDate : false;
        const dayIsAfterMaxDate = (dateRangeParams.maxDate) ? evalDate > dateRangeParams.maxDate : false;
 
        return dayIsBeforeMinDate || dayIsAfterMaxDate;
    }
 
    public getMonthInfo(year: number, month: number): Date {
        return new Date(year, month, 15);
    }
 
    public month(date: Date): number {
        return date.getUTCMonth();
    }
 
    public newDateFromArray(year?: number, month?: number, day?: number): Date {
        return new Date(Date.UTC(year, month, day));
    }
 
    public newDateFromValue(value?: any): Date {
        return (value) ? this.processDateInput(value) : this.getZerodDate(new Date());
    }
 
    public prepHeaderDate(date: Date): string {
        return localize(this.languageCode, this.addTimezoneOffset(date), 'EEE, MMM d');
    }
 
    public prepHeaderYear(date: Date): string {
        return localize(this.languageCode, this.addTimezoneOffset(date), 'yyyy');
    }
 
    public sameDay(_calendarDay: DayWithMetadata, _comparator: Date): boolean {
        return _calendarDay.day === _comparator.getUTCDate()
            && _calendarDay.month === _comparator.getUTCMonth()
            && _calendarDay.year === _comparator.getUTCFullYear();
    }
 
    public year(date: Date): number {
        return date.getUTCFullYear();
    }
 
    public weekdays(): string[] {
        return getWeekdays(this.languageCode);
    }
 
    public months(): string[] {
        return getMonths(this.languageCode);
    }
 
    public prepDateStringOutput(input: Date): string {
        return (input) ? new Date(this.processDateInput(input)).toLocaleDateString(this._locale, {timeZone: 'UTC'}) : '';
    }
 
    public processDateInput(input: Date | string): Date {
        if (!input) { return null; }
 
        if (typeof input === 'string') {
            const dateSegments = parseInput(input, this._locale);
 
            if (Array.isArray(dateSegments.splitDate) && dateSegments.splitDate.length === 3 && dateSegments.year) {
                return new Date(Date.UTC(
                    parseInt(dateSegments.year, 10),
                    parseInt(dateSegments.month, 10) - 1,
                    parseInt(dateSegments.day, 10))
                );
            } else {
                // This is a fallback for malformed date string, outcome unknown
                return new Date(input);
            }
        } else {
            return this.getZerodDate(input);
        }
    }
 
    private addTimezoneOffset(date: Date): Date {
        const newDate = new Date(date);
        const timeOffsetInMS = date.getTimezoneOffset() * 60000;
 
        newDate.setTime(date.getTime() + timeOffsetInMS);
        return newDate;
    }
 
    private getZerodDate(date: any): Date {
        const safeDate = (date._isAMomentObject) ? new Date(date) : date;
 
        const day = safeDate.getUTCDate();
        const month = safeDate.getUTCMonth();
        const year = safeDate.getUTCFullYear();
 
        return new Date(Date.UTC(year, month, day));
    }
}