File

libs/core/dynamic-form/date/src/iso-date-adapter/iso-date-adapter-testing.ts

Extends

NxDateAdapter

Index

Methods

Constructor

constructor(dateLocale: string)
Parameters :
Name Type Optional
dateLocale string No

Methods

addCalendarDays
addCalendarDays(date: string, days: number)
Parameters :
Name Type Optional
date string No
days number No
Returns : string
addCalendarMonths
addCalendarMonths(date: string, months: number)
Parameters :
Name Type Optional
date string No
months number No
Returns : string
addCalendarYears
addCalendarYears(date: string, years: number)
Parameters :
Name Type Optional
date string No
years number No
Returns : string
clone
clone(date: string)
Parameters :
Name Type Optional
date string No
Returns : string
createDate
createDate(year: number, month: number, date: number)
Parameters :
Name Type Optional
year number No
month number No
date number No
Returns : string
deserialize
deserialize(value: any)
Parameters :
Name Type Optional
value any No
Returns : string | null
format
format(date: string, displayFormat: any)
Parameters :
Name Type Optional
date string No
displayFormat any No
Returns : string
getDate
getDate(date: string)
Parameters :
Name Type Optional
date string No
Returns : number
getDateNames
getDateNames()
Returns : string[]
getDayOfWeek
getDayOfWeek(date: string)
Parameters :
Name Type Optional
date string No
Returns : number
getDayOfWeekNames
getDayOfWeekNames(style: "long" | "short" | "narrow")
Parameters :
Name Type Optional
style "long" | "short" | "narrow" No
Returns : string[]
getFirstDayOfWeek
getFirstDayOfWeek()
Returns : number
getMonth
getMonth(date: string)
Parameters :
Name Type Optional
date string No
Returns : number
getMonthNames
getMonthNames(style: "long" | "short" | "narrow")
Parameters :
Name Type Optional
style "long" | "short" | "narrow" No
Returns : string[]
getNumDaysInMonth
getNumDaysInMonth(date: string)
Parameters :
Name Type Optional
date string No
Returns : number
getYear
getYear(date: string)
Parameters :
Name Type Optional
date string No
Returns : number
getYearName
getYearName(date: string)
Parameters :
Name Type Optional
date string No
Returns : string
invalid
invalid()
Returns : string
isDateInstance
isDateInstance(obj: any)
Parameters :
Name Type Optional
obj any No
Returns : boolean
isValid
isValid(date: string | Dayjs)
Parameters :
Name Type Optional
date string | Dayjs No
Returns : boolean
normalizeFormat
normalizeFormat(format: string | string[])

if the given formats include a localized format we have to map it manually to a dayjs format as dayjs recognizes locale format only for formatting not for parsing see https://github.com/iamkun/dayjs/issues/694#issuecomment-543209946

Parameters :
Name Type Optional
format string | string[] No
Returns : string[]
parse
parse(value: any, format: string | string[], strict: boolean)
Parameters :
Name Type Optional
value any No
format string | string[] No
strict boolean No
Returns : string | null
setLocale
setLocale(locale: string)
Parameters :
Name Type Optional
locale string No
Returns : void
today
today()
Returns : string
toIso8601
toIso8601(date: string)
Parameters :
Name Type Optional
date string No
Returns : string
import { NX_DATE_LOCALE, NxDateAdapter } from '@aposin/ng-aquila/datefield';
import { pad } from '@aposin/ng-aquila/utils';

import { Inject, Optional } from '@angular/core';

import dayjs, { Dayjs } from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import localeData from 'dayjs/plugin/localeData';
import localizedFormat from 'dayjs/plugin/localizedFormat';
import utc from 'dayjs/plugin/utc';

dayjs.extend(localeData);
dayjs.extend(customParseFormat);
dayjs.extend(localizedFormat);
dayjs.extend(utc);

const ISO_STRING_FORMAT = 'YYYY-MM-DD';
const ISO_REGEX = /^([0-9]{4})(-?)(1[0-2]|0[1-9])\2(3[01]|0[1-9]|[12][0-9])$/;

/** Creates an array and fills it with values. */
function range<T>(length: number, valueFunction: (index: number) => T): T[] {
  const valuesArray = Array(length);
  for (let i = 0; i < length; i++) {
    valuesArray[i] = valueFunction(i);
  }
  return valuesArray;
}

/**
 * @docs-private
 */
export class DfIsoDateAdapterTesting extends NxDateAdapter<string> {
  private _localeData:
    | {
        firstDayOfWeek: number;
        longMonths: string[];
        shortMonths: string[];
        dates: string[];
        longDaysOfWeek: string[];
        shortDaysOfWeek: string[];
        narrowDaysOfWeek: string[];
      }
    | undefined;

  constructor(@Optional() @Inject(NX_DATE_LOCALE) dateLocale: string) {
    super();
    this.setLocale(dateLocale || dayjs.locale());
  }

  toIso8601(date: string): string {
    return dayjs.utc(date).format();
  }

  override deserialize(value: any): string | null {
    let date: string | Dayjs | undefined;

    // TODO should we accept that or only take strings?
    if (value instanceof Date) {
      date = dayjs(value).locale(this.locale);
    }
    if (typeof value === 'string') {
      if (!value) {
        return null;
      }
      date = dayjs(value).locale(this.locale);
    }

    if (date && this.isValid(date)) {
      return dayjs(date).locale(this.locale).format(ISO_STRING_FORMAT);
    }

    return super.deserialize(value);
  }

  format(date: string, displayFormat: any): string {
    return this._createDayjs(date).format(displayFormat);
  }

  /**
   * if the given formats include a localized format we have to map
   * it manually to a dayjs format as dayjs recognizes locale
   * format only for formatting not for parsing
   * see https://github.com/iamkun/dayjs/issues/694#issuecomment-543209946
   */
  normalizeFormat(format: string | string[]): string[] {
    const availableLocalFormats = dayjs.Ls[this.locale]?.formats;
    if (!availableLocalFormats) {
      throw new Error(
        `NxIsoDateAdapter: The used locale "${this.locale}" is not available in this day.js instance. Please make sure the locale is imported.`
      );
    }
    let normalizedFormat = format;

    if (!Array.isArray(normalizedFormat)) {
      normalizedFormat = [normalizedFormat];
    }

    normalizedFormat = normalizedFormat.map((formatString) => {
      if (Object.keys(availableLocalFormats).indexOf(formatString) !== -1) {
        return (availableLocalFormats as any)[formatString];
      }

      return formatString;
    });

    return normalizedFormat;
  }

  parse(value: any, format: string | string[], strict: boolean): string | null {
    let obj: Dayjs | undefined;

    const normalizedFormats = this.normalizeFormat(format);
    if (value && typeof value === 'string') {
      if (strict) {
        obj = dayjs(value, normalizedFormats, this.locale, true);
      } else {
        // The non strict parsing of day.js is rather strict when it comes to separators.
        // For example, this format: YYYY-MM-DD still requires the user to type in the -
        // To get a little closer to the behavior of momentjs, the following code extends
        // the list of given formats with versions were all the separators were removed
        const formatsWithoutSeparators = [...normalizedFormats].map((normalizedformat) => {
          return normalizedformat.replace(/[^\w]/g, '');
        });
        obj = dayjs(value, [...formatsWithoutSeparators, ...normalizedFormats], this.locale, false);
      }
    }

    if (obj?.isValid() === false) {
      return '';
    }

    return obj ? obj.format(ISO_STRING_FORMAT) : null;
  }

  isValid(date: string | Dayjs): boolean {
    return dayjs(date).isValid();
  }

  clone(date: string): string {
    return date;
  }

  isDateInstance(obj: any): boolean {
    return obj === '' || (typeof obj === 'string' && ISO_REGEX.test(obj));
  }

  invalid(): string {
    return '';
  }

  getYear(date: string): number {
    return this._createDayjs(date).year();
  }

  getMonth(date: string): number {
    return this._createDayjs(date).month();
  }

  getDate(date: string): number {
    return this._createDayjs(date).date();
  }

  getYearName(date: string): string {
    return this._createDayjs(date).format('YYYY');
  }

  createDate(year: number, month: number, date: number): string {
    // Check for invalid month and date (except upper bound on date which we have to check after
    // creating the Date).
    if (month < 0 || month > 11) {
      throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
    }

    if (date < 1) {
      throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
    }

    // dayjs adds overflows up instead of creating invalid dates so we have to check that here
    const obj = this._createDayjs(this._createString(year, month + 1, date));
    // Check that the date wasn't above the upper bound for the month, causing the month to overflow
    if (obj.month() !== month || obj.year() !== year) {
      throw Error(`Invalid date "${date}" for month with index "${month}".`);
    }

    return obj.format(ISO_STRING_FORMAT);
  }

  getNumDaysInMonth(date: string): number {
    return this._createDayjs(date).daysInMonth();
  }

  getDateNames(): string[] {
    return this._localeData?.dates || [];
  }

  getDayOfWeek(date: string): number {
    return this._createDayjs(date).day();
  }

  getFirstDayOfWeek(): number {
    return this._localeData?.firstDayOfWeek || 0;
  }

  getMonthNames(style: 'long' | 'short' | 'narrow'): string[] {
    const monthNames =
      style === 'long' ? this._localeData?.longMonths : this._localeData?.shortMonths;
    return monthNames || [];
  }

  today(): string {
    return dayjs().format(ISO_STRING_FORMAT);
  }

  addCalendarMonths(date: string, months: number): string {
    return this._createDayjs(date).add(months, 'M').format(ISO_STRING_FORMAT);
  }

  addCalendarYears(date: string, years: number): string {
    return this._createDayjs(date).add(years, 'y').format(ISO_STRING_FORMAT);
  }

  addCalendarDays(date: string, days: number): string {
    return this._createDayjs(date).add(days, 'd').format(ISO_STRING_FORMAT);
  }

  getDayOfWeekNames(style: 'long' | 'short' | 'narrow'): string[] {
    if (style === 'long') {
      return this._localeData?.longDaysOfWeek || [];
    }
    if (style === 'short') {
      return this._localeData?.shortDaysOfWeek || [];
    }
    return this._localeData?.narrowDaysOfWeek || [];
  }

  override setLocale(locale: string) {
    const data = dayjs().locale(locale).localeData();

    this._localeData = {
      firstDayOfWeek: data.firstDayOfWeek(),
      longMonths: data.months(),
      shortMonths: data.monthsShort(),
      dates: range(31, (i) => this._createDayjs(this.createDate(2017, 0, i + 1)).format('D')),
      longDaysOfWeek: data.weekdays(),
      shortDaysOfWeek: data.weekdaysShort(),
      narrowDaysOfWeek: data.weekdaysMin()
    };

    super.setLocale(locale);
  }

  private _createDayjs(value: string) {
    return dayjs.utc(value).locale(this.locale);
  }

  private _createString(year: number, month: number, date: number) {
    return `${year}-${pad(month.toString())}-${pad(date.toString())}`;
  }
}

results matching ""

    No results matching ""