Skip to content

Commit

Permalink
chore(cdk): TuiDay improvement of localization (#1139)
Browse files Browse the repository at this point in the history
* chore(cdk): `TuiDay` add static method `parseRawDateString`

* chore(cdk): `TuiDay` new `getFormattedDay` method (with localization support)

* chore(cdk): `TuiDay` add assert inside `parseRawDateString`
  • Loading branch information
nsbarsukov committed Dec 23, 2021
1 parent 03cfda9 commit 4349a45
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 11 deletions.
79 changes: 69 additions & 10 deletions projects/cdk/date-time/day.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {tuiAssert} from '@taiga-ui/cdk/classes';
import {TuiDayOfWeek, TuiMonthNumber} from '@taiga-ui/cdk/enums';
import {TuiDayLike} from '@taiga-ui/cdk/interfaces';
import {TuiDateMode} from '@taiga-ui/cdk/types';
import {padStart} from '@taiga-ui/cdk/utils/format';
import {inRange, normalizeToIntNumber} from '@taiga-ui/cdk/utils/math';

import {DATE_FILLER_LENGTH} from './date-fillers';
import {DAYS_IN_WEEK, MIN_DAY, MONTHS_IN_YEAR} from './date-time';
import {TuiMonth} from './month';
import {TuiYear} from './year';
Expand Down Expand Up @@ -122,17 +124,50 @@ export class TuiDay extends TuiMonth {
);
}

static parseRawDateString(
date: string,
dateMode: TuiDateMode = 'DMY',
): {day: number; month: number; year: number} {
tuiAssert.assert(
date.length === DATE_FILLER_LENGTH,
'[parseRawDateString]: wrong date string length',
);

switch (dateMode) {
case 'YMD':
return {
day: parseInt(date.slice(8, 10), 10),
month: parseInt(date.slice(5, 7), 10) - 1,
year: parseInt(date.slice(0, 4), 10),
};

case 'MDY':
return {
day: parseInt(date.slice(3, 5), 10),
month: parseInt(date.slice(0, 2), 10) - 1,
year: parseInt(date.slice(6, 10), 10),
};

default:
case 'DMY':
return {
day: parseInt(date.slice(0, 2), 10),
month: parseInt(date.slice(3, 5), 10) - 1,
year: parseInt(date.slice(6, 10), 10),
};
}
}

// TODO: Move month and year related code corresponding classes
/**
* Parsing a string with date with normalization
*
* @param yearMonthDayString date string in format of DD.MM.Yyyy
* @param rawDate date string
* @param dateMode date format of the date string (DMY | MDY | YMD)
* @return normalized date
*/
static normalizeParse(yearMonthDayString: string): TuiDay {
const day = parseInt(yearMonthDayString.slice(0, 2), 10);
const month = parseInt(yearMonthDayString.slice(3, 5), 10) - 1;
const year = parseInt(yearMonthDayString.slice(6, 10), 10);
static normalizeParse(rawDate: string, dateMode: TuiDateMode = 'DMY'): TuiDay {
const {day, month, year} = this.parseRawDateString(rawDate, dateMode);

return TuiDay.normalizeOf(year, month, day);
}
Expand All @@ -144,9 +179,7 @@ export class TuiDay extends TuiMonth {
* @throws exceptions if any part of the date is invalid
*/
static jsonParse(yearMonthDayString: string): TuiDay {
const day = parseInt(yearMonthDayString.slice(8, 10), 10);
const month = parseInt(yearMonthDayString.slice(5, 7), 10) - 1;
const year = parseInt(yearMonthDayString.slice(0, 4), 10);
const {day, month, year} = this.parseRawDateString(yearMonthDayString, 'YMD');

if (!TuiYear.isValidYear(year)) {
throw new Error('Invalid year: ' + year);
Expand Down Expand Up @@ -186,6 +219,8 @@ export class TuiDay extends TuiMonth {
}

/**
* @deprecated use {@link getFormattedDay} instead
* TODO remove in 3.0
* Formatted whole date
*/
get formattedDay(): string {
Expand Down Expand Up @@ -335,8 +370,32 @@ export class TuiDay extends TuiMonth {
return new TuiDay(years, months, days);
}

toString(): string {
return this.formattedDay;
/**
* Returns formatted whole date
*/
getFormattedDay(dateFormat: TuiDateMode, separator: string): string {
tuiAssert.assert(
separator.length === 1,
'Separator should consist of only 1 symbol',
);

const dd = this.formattedDayPart;
const mm = this.formattedMonthPart;
const yyyy = this.formattedYear;

switch (dateFormat) {
case 'YMD':
return `${yyyy}${separator}${mm}${separator}${dd}`;
case 'MDY':
return `${mm}${separator}${dd}${separator}${yyyy}`;
case 'DMY':
default:
return `${dd}${separator}${mm}${separator}${yyyy}`;
}
}

toString(dateFormat: TuiDateMode = 'DMY', separator: string = '.'): string {
return this.getFormattedDay(dateFormat, separator);
}

toJSON(): string {
Expand Down
93 changes: 92 additions & 1 deletion projects/cdk/date-time/test/day.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ describe('TuiDay', () => {
});

describe('normalizeParse return parsed date', () => {
describe('from a valid string', () => {
describe('from a valid string (dd.mm.yyyy)', () => {
it("'20.10.2018'", () => {
const result = TuiDay.normalizeParse('20.10.2018');

Expand Down Expand Up @@ -303,6 +303,41 @@ describe('TuiDay', () => {
expect(result.day).toBe(1);
});
});
describe('from yyyy.mm.dd string', () => {
it("'2021/12/22'", () => {
const result = TuiDay.normalizeParse('2021/12/22', 'YMD');

expect(result.year).toBe(2021);
expect(result.month).toBe(11);
expect(result.day).toBe(22);
});

it("'1900.05.01'", () => {
const result = TuiDay.normalizeParse('1900.05.01', 'YMD');

expect(result.year).toBe(1900);
expect(result.month).toBe(4);
expect(result.day).toBe(1);
});
});

describe('from mm.dd.yyyy string', () => {
it("'03/10/1956'", () => {
const result = TuiDay.normalizeParse('03/10/1956', 'MDY');

expect(result.year).toBe(1956);
expect(result.month).toBe(2);
expect(result.day).toBe(10);
});

it("'01.02.0988'", () => {
const result = TuiDay.normalizeParse('01.02.0988', 'MDY');

expect(result.year).toBe(988);
expect(result.month).toBe(0);
expect(result.day).toBe(2);
});
});
});

describe('jsonParse', () => {
Expand Down Expand Up @@ -921,6 +956,62 @@ describe('TuiDay', () => {
expect(y2000m6d15.dayLimit(null, y1900m6d10)).toBe(y1900m6d10);
});
});

describe('toString returns', () => {
describe('(DMY mode, default)', () => {
it("'10.07.1900' for TuiMonth {year: 1900, month: 6, day: 10}", () => {
expect(y1900m6d10.toString()).toBe('10.07.1900');
});

it("'15.05.2000' for TuiMonth {year: 2000, month: 4, day: 15}", () => {
expect(y2000m4d15.toString()).toBe('15.05.2000');
});

it("'16.09.2000' for TuiMonth {year: 2000, month: 8, day: 16}", () => {
expect(y2000m8d16.toString()).toBe('16.09.2000');
});

it("'15.07.2100' for TuiMonth {year: 2100, month: 6, day: 15}", () => {
expect(y2100m6d15.toString()).toBe('15.07.2100');
});
});

describe("(MDY mode, '/' as separator)", () => {
it("'07/10/1900' for TuiMonth {year: 1900, month: 6, day: 10}", () => {
expect(y1900m6d10.toString('MDY', '/')).toBe('07/10/1900');
});

it("'05/15/2000' for TuiMonth {year: 2000, month: 4, day: 15}", () => {
expect(y2000m4d15.toString('MDY', '/')).toBe('05/15/2000');
});

it("'09/16/2000' for TuiMonth {year: 2000, month: 8, day: 16}", () => {
expect(y2000m8d16.toString('MDY', '/')).toBe('09/16/2000');
});

it("'07/15/2100' for TuiMonth {year: 2100, month: 6, day: 15}", () => {
expect(y2100m6d15.toString('MDY', '/')).toBe('07/15/2100');
});
});

describe("(YMD mode, '-' as separator)", () => {
it("'1900-07-10' for TuiMonth {year: 1900, month: 6, day: 10}", () => {
expect(y1900m6d10.toString('YMD', '-')).toBe('1900-07-10');
});

it("'2000-05-15' for TuiMonth {year: 2000, month: 4, day: 15}", () => {
expect(y2000m4d15.toString('YMD', '-')).toBe('2000-05-15');
});

it("'2000-09-16' for TuiMonth {year: 2000, month: 8, day: 16}", () => {
expect(y2000m8d16.toString('YMD', '-')).toBe('2000-09-16');
});

it("'2100-07-15' for TuiMonth {year: 2100, month: 6, day: 15}", () => {
expect(y2100m6d15.toString('YMD', '-')).toBe('2100-07-15');
});
});
});
});
});
});

0 comments on commit 4349a45

Please sign in to comment.