Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HXCS-3381 fix date widget #9482

Merged
merged 4 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 29 additions & 25 deletions lib/core/src/lib/common/utils/date-fns-utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ describe('DateFnsUtils', () => {
});
});


it('should format a date correctly', () => {
const date = new Date('2023-09-22T12:00:00Z');
const dateFormat = 'yyyy-MM-dd';
Expand All @@ -53,27 +52,18 @@ describe('DateFnsUtils', () => {
});

it('should parse datetime', () => {
const parsed = DateFnsUtils.parseDate(
'09-02-9999 09:10 AM',
'dd-MM-yyyy hh:mm aa'
);
const parsed = DateFnsUtils.parseDate('09-02-9999 09:10 AM', 'dd-MM-yyyy hh:mm aa');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all these format changes has been done automatically by linter when I did the commit

expect(isValid(parsed));
expect(parsed.toISOString()).toBe('9999-02-09T09:10:00.000Z');
});

it('should format datetime with custom moment format', () => {
const parsed = DateFnsUtils.formatDate(
new Date('9999-12-30T10:30:00.000Z'),
'MM-DD-YYYY HH:mm A'
);
const parsed = DateFnsUtils.formatDate(new Date('9999-12-30T10:30:00.000Z'), 'MM-DD-YYYY HH:mm A');
expect(parsed).toBe('12-30-9999 10:30 AM');
});

it('should parse moment datetime ISO', () => {
const parsed = DateFnsUtils.parseDate(
'1982-03-13T10:00:00Z',
'YYYY-MM-DDTHH:mm:ssZ'
);
const parsed = DateFnsUtils.parseDate('1982-03-13T10:00:00Z', 'YYYY-MM-DDTHH:mm:ssZ');
expect(parsed.toISOString()).toBe('1982-03-13T10:00:00.000Z');
});

Expand All @@ -87,27 +77,18 @@ describe('DateFnsUtils', () => {
});

it('should parse alternative ISO datetime', () => {
const result = DateFnsUtils.parseDate(
'1982-03-13T10:00:000Z',
`yyyy-MM-dd'T'HH:mm:sssXXX`
);
const result = DateFnsUtils.parseDate('1982-03-13T10:00:000Z', `yyyy-MM-dd'T'HH:mm:sssXXX`);

expect(result.toISOString()).toBe('1982-03-13T10:00:00.000Z');
});

it('should parse the datetime with zone', () => {
const result = DateFnsUtils.parseDate(
'1982-03-13T10:00:000+01:00',
`yyyy-MM-dd'T'HH:mm:sssXXX`
);
const result = DateFnsUtils.parseDate('1982-03-13T10:00:000+01:00', `yyyy-MM-dd'T'HH:mm:sssXXX`);
expect(result.toISOString()).toBe('1982-03-13T09:00:00.000Z');
});

it('should parse datetime with zone in moment format', () => {
const result = DateFnsUtils.parseDate(
'1982-03-13T10:00:00+0100',
`YYYY-MM-DDTHH:mm:ssZZ`
);
const result = DateFnsUtils.parseDate('1982-03-13T10:00:00+0100', `YYYY-MM-DDTHH:mm:ssZZ`);
expect(result.toISOString()).toBe('1982-03-13T09:00:00.000Z');
});

Expand All @@ -132,4 +113,27 @@ describe('DateFnsUtils', () => {
expect(resultLocal).toBeInstanceOf(Date);
expect(resultUtc).toBeInstanceOf(Date);
});

it('should convert UTC dates to have the same day, month, year displayed in different timezone', () => {
const dateUTC = new Date('Wed Jan 01 2020 00:00:00 GMT+0000');
const dateUSA = new Date('Tue Dec 31 2019 16:00:00 GMT-0800');
const dateJapan = new Date('Wed Jan 01 2020 09:00:00 GMT+0900');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same instant in different timezones

const forceUtcDateUTC = DateFnsUtils.forceUtc(dateUTC);
const forceUtcDateUSA = DateFnsUtils.forceUtc(dateUSA);
const forceUtcDateJapan = DateFnsUtils.forceUtc(dateJapan);
const forceLocalDateUTC = DateFnsUtils.forceUtc(forceUtcDateUTC);
const forceLocalDateUSA = DateFnsUtils.forceUtc(forceUtcDateUSA);
const forceLocalDateJapan = DateFnsUtils.forceUtc(forceUtcDateJapan);

expect(forceUtcDateUTC).toEqual(forceUtcDateUSA);
expect(forceUtcDateUSA).toEqual(forceUtcDateJapan);
expect(forceLocalDateUTC).toEqual(forceLocalDateUSA);
expect(forceLocalDateUSA).toEqual(forceLocalDateJapan);
expect(forceUtcDateUSA.getDate()).toBe(1);
expect(forceUtcDateUSA.getMonth()).toBe(0);
expect(forceUtcDateUSA.getFullYear()).toBe(2020);
expect(forceLocalDateJapan.getDate()).toBe(1);
expect(forceLocalDateJapan.getMonth()).toBe(0);
expect(forceLocalDateJapan.getFullYear()).toBe(2020);
});
});
24 changes: 16 additions & 8 deletions lib/core/src/lib/common/utils/date-fns-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@
* limitations under the License.
*/

import { format, parse, parseISO, isValid, isBefore, isAfter, lightFormat } from 'date-fns';
import { format, parse, parseISO, isValid, isBefore, isAfter } from 'date-fns';
Copy link
Contributor Author

@wideLandscape wideLandscape Mar 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lightFormat doesn't return the desired output when dealing with -XX:XXGMT timezones (eg: USA)

import { ar, cs, da, de, enUS, es, fi, fr, it, ja, nb, nl, pl, ptBR, ru, sv, zhCN } from 'date-fns/locale';

const panDate = (num: number = 1): string => {
let text = num.toString();
while (text.length < 2) {
text = '0' + text;
}
return text;
};

export class DateFnsUtils {
static getLocaleFromString(locale: string): Locale {
Expand Down Expand Up @@ -203,18 +210,19 @@ export class DateFnsUtils {
return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}

static forceLocal(date: string | Date): Date {
if (typeof date === 'string'){
static forceLocal(date: Date | string): Date {
Copy link
Contributor Author

@wideLandscape wideLandscape Mar 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forceLocal and forceUtc are meant to display the same date over different timezone.
So, giving a UTC date , the output might be a different Date. But since that date is localized automatically by the browser, the text displayed will be the same.
Eg: 03-24-1983T00:00:00Z localized to USA timezone is 03-23-1983T16:00:00 (notice the absence of Z, and different day and hours values). Instead forceUtc/forceLocal will convert the date to 03-24-1983T00:00:00, different value but same text when displayed

if (typeof date === 'string') {
date = parseISO(date);
}
return new Date(lightFormat(date, 'yyyy-MM-dd'));
const localDate = `${date.getUTCFullYear()}-${panDate(date.getUTCMonth() + 1)}-${panDate(date.getUTCDate())}T00:00:00.000`;
return new Date(localDate);
}

static forceUtc(date: string | Date): Date {
if (typeof date === 'string'){
static forceUtc(date: Date | string): Date {
if (typeof date === 'string') {
date = parseISO(date);
}
return new Date(lightFormat(date, 'yyyy-MM-dd').concat('T00:00:00.000Z'));
const utcDate = `${date.getFullYear()}-${panDate(date.getMonth() + 1)}-${panDate(date.getDate())}T00:00:00.000Z`;
return new Date(utcDate);
}

}
Loading