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

feat[ATLAS-104]: Introducing Date & Time Module #54

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
32aa462
add formatDate - DateTime Module
RgnDunes Jan 18, 2024
763e7e0
add formatDateTime - DateTime Module
RgnDunes Jan 18, 2024
a616f42
add formatTime - DateTime Module
RgnDunes Jan 18, 2024
ab60331
add add & subtract - DateTime Module
RgnDunes Jan 18, 2024
0e341d6
add getFirstDayOfWeek, getQuarter, getWeek, getWeekdays - DateTime Mo…
RgnDunes Jan 18, 2024
a8087d5
add isAfter, isBefore, isLeapYear, isSameDay, isValidDate
RgnDunes Jan 18, 2024
e8fd26b
add getRelativeTime - DateTime Module
RgnDunes Jan 18, 2024
868db86
add parseDate, parseDateWithFormat, localeDateFormats - DateTime Module
RgnDunes Jan 18, 2024
87386cf
[fix]: syntax errors
RgnDunes Jan 18, 2024
661f50d
add dateTime module export
RgnDunes Jan 18, 2024
555f445
Create cuddly-eggs-design.md
RgnDunes Jan 18, 2024
31f8f7a
add locale check and state support for locale estimation
RgnDunes Jan 18, 2024
3770970
push build
RgnDunes Jan 18, 2024
2559974
update build
RgnDunes Jan 18, 2024
bbbebf5
remove build
RgnDunes Jan 18, 2024
14cdb79
add support for intlOptions
RgnDunes Jan 18, 2024
8df37a8
[fix]: eslint errors
RgnDunes Jan 18, 2024
499b653
Merge remote-tracking branch 'origin/master' into ATLAS-104-date-modu…
RgnDunes Jan 22, 2024
b819ee5
add parseDateTime
RgnDunes Jan 22, 2024
f2f36d0
add stringToDate desc in utils
RgnDunes Jan 22, 2024
1374936
migrated dateTime module to i18nify-js package
RgnDunes Jan 22, 2024
00ebcc6
refactor parseDateTime module
RgnDunes Jan 23, 2024
34f49b0
minor fixes
RgnDunes Jan 24, 2024
db96b5b
Merge remote-tracking branch 'origin/master' into ATLAS-104-date-modu…
RgnDunes Jan 24, 2024
ce8f59a
remove extra files
RgnDunes Jan 29, 2024
10fd174
[chore]: update date module api contracts
RgnDunes Feb 14, 2024
462add3
Merge remote-tracking branch 'origin/master' into ATLAS-104-date-modu…
RgnDunes Feb 14, 2024
da36410
[fix]: fix invalid parameter in formatDate
RgnDunes Feb 14, 2024
727a19f
[chore]: assign default empty object to intlOptions in parseDateTime
RgnDunes Feb 14, 2024
140f42e
docs[ATLAS-104]: Adding Documentation for Date & Time Module (#56)
RgnDunes Feb 14, 2024
e591663
test[ATLAS-104]: Adding Unit Tests for Date & Time Module (#55)
RgnDunes Feb 14, 2024
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
5 changes: 5 additions & 0 deletions .changeset/cuddly-eggs-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@razorpay/i18nify-js": patch
---

feat[ATLAS-104]: Introducing Date & Time Module
440 changes: 440 additions & 0 deletions packages/i18nify-js/README.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18nify-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
],
"phoneNumber": [
"./lib/esm/phoneNumber/index.d.ts"
],
"dateTime": [
"./lib/esm/dateTime/index.d.ts"
]
}
},
Expand Down
1 change: 1 addition & 0 deletions packages/i18nify-js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './modules/core';
export * from './modules/currency';
export * from './modules/phoneNumber';
export * from './modules/dateTime';
97 changes: 97 additions & 0 deletions packages/i18nify-js/src/modules/.internal/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
export const COUNTRY_CODES_TO_LOCALE: { [key: string]: string } = {
AE: 'ar-AE',
AL: 'sq-AL',
AM: 'hy-AM',
AR: 'es-AR',
AU: 'en-AU',
AW: 'nl-AW',
BB: 'en-BB',
BD: 'bn-BD',
BM: 'en-BM',
BN: 'ms-BN',
BO: 'es-BO',
BS: 'en-BS',
BW: 'en-BW',
BZ: 'en-BZ',
CA: 'en-CA',
CH: 'de-CH',
CN: 'zh-CN',
CO: 'es-CO',
CR: 'es-CR',
CU: 'es-CU',
CZ: 'cs-CZ',
DK: 'da-DK',
DO: 'es-DO',
DZ: 'ar-DZ',
EG: 'ar-EG',
ET: 'am-ET',
EU: 'en-EU',
FJ: 'en-FJ',
GB: 'en-GB',
GH: 'en-GH',
GI: 'en-GI',
GM: 'en-GM',
GT: 'es-GT',
GY: 'en-GY',
HK: 'en-HK',
HN: 'es-HN',
HR: 'hr-HR',
HT: 'ht-HT',
HU: 'hu-HU',
ID: 'id-ID',
IL: 'he-IL',
IN: 'en-IN',
JM: 'en-JM',
KE: 'en-KE',
KG: 'ky-KG',
KH: 'km-KH',
KY: 'en-KY',
KZ: 'kk-KZ',
LA: 'lo-LA',
LK: 'si-LK',
LR: 'en-LR',
LS: 'en-LS',
MA: 'ar-MA',
MD: 'ro-MD',
MK: 'mk-MK',
MM: 'my-MM',
MN: 'mn-MN',
MO: 'zh-MO',
MU: 'en-MU',
MV: 'dv-MV',
MW: 'en-MW',
MX: 'es-MX',
MY: 'ms-MY',
NA: 'en-NA',
NG: 'en-NG',
NI: 'es-NI',
NO: 'no-NO',
NP: 'ne-NP',
NZ: 'en-NZ',
PE: 'es-PE',
PG: 'en-PG',
PH: 'en-PH',
PK: 'en-PK',
QA: 'ar-QA',
RU: 'ru-RU',
SA: 'ar-SA',
SC: 'en-SC',
SE: 'sv-SE',
SG: 'en-SG',
SL: 'en-SL',
SO: 'so-SO',
SS: 'en-SS',
SV: 'es-SV',
SZ: 'en-SZ',
TH: 'th-TH',
TT: 'en-TT',
TZ: 'sw-TZ',
US: 'en-US',
UY: 'es-UY',
UZ: 'uz-UZ',
YE: 'ar-YE',
ZA: 'en-ZA',
KW: 'ar-KW',
BH: 'ar-BH',
OM: 'ar-OM'
}
63 changes: 63 additions & 0 deletions packages/i18nify-js/src/modules/dateTime/__tests__/add.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import add from '../add';

describe('dateTime - add', () => {
// Basic Functionality Tests
test('adds days to a date', () => {
const startDate = new Date(2024, 0, 1); // Jan 1, 2024
expect(add(startDate, {value: 10, unit: 'days'})).toEqual(new Date(2024, 0, 11));
});

test('adds months to a date', () => {
const startDate = new Date(2024, 0, 1); // Jan 1, 2024
expect(add(startDate,{value: 2, unit: 'months'})).toEqual(new Date(2024, 2, 1));
});

test('adds years to a date', () => {
const startDate = new Date(2024, 0, 1); // Jan 1, 2024
expect(add(startDate, {value: 1, unit: 'years'})).toEqual(new Date(2025, 0, 1));
});

test('handles negative values', () => {
const startDate = new Date(2024, 0, 10);
expect(add(startDate, {value: -5, unit: 'days'})).toEqual(new Date(2024, 0, 5));
});

test('handles adding zero', () => {
const startDate = new Date(2024, 1, 13);
expect(add(startDate, {value: 0, unit: 'months'})).toEqual(startDate);
});

test('handles leap years', () => {
const startDate = new Date(2024, 1, 29); // Feb 29, 2024
expect(add(startDate, {value: 1, unit: 'years'})).toEqual(new Date(2025, 1, 28)); // Feb 28, 2025
});

test('handles month-end dates', () => {
const startDate = new Date(2024, 0, 31); // Jan 31, 2024
expect(add(startDate, {value: 1, unit: 'months'})).toEqual(new Date(2024, 1, 29)); // Feb 29, 2024
});

// Invalid Inputs
test('throws error for invalid date string', () => {
expect(() => add('invalid-date', {value: 1, unit: 'days'})).toThrow(
'Error: Date format not recognized',
);
});

test('throws error for invalid value', () => {
const startDate = new Date(2024, 0, 1);
expect(() => add(startDate, {value: NaN, unit: 'days'})).toThrow(
'Error: Invalid value passed!',
);
expect(() => add(startDate, {value: Infinity, unit: 'days'})).toThrow(
'Error: Invalid value passed!',
);
});

// Type Checking
test('handles Date object and date string inputs', () => {
const startDate = new Date(2024, 0, 1);
const startDateString = '2024-01-01';
expect(add(startDate, {value: 1, unit: 'days'})).toEqual(add(startDateString, {value: 1, unit: 'days'}));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import formatDate from '../formatDate';
import { DateFormatOptions } from '../types';

describe('dateTime - formatDate', () => {
// Basic Functionality Tests
test.each([
['2024-01-01', 'en-US', undefined, '1/1/2024'], // US format
['2024-01-01', 'en-GB', undefined, '01/01/2024'], // UK format
[
'2024-02-29',
'en-US',
{
day: '2-digit',
month: '2-digit',
year: 'numeric',
} as DateFormatOptions,
'02/29/2024',
], // Leap year with specific format
])(
'formats date "%s" with locale "%s" and options %o to "%s"',
(date, locale, options, expected) => {
expect(formatDate(date, {locale: locale, intlOptions: options})).toBe(expected);
},
);

test('formats end of year date', () => {
expect(formatDate('2024-12-31', {locale: 'en-US'})).toBe('12/31/2024');
});

test('handles invalid date strings', () => {
expect(() => formatDate('invalid-date', {locale: 'en-US'})).toThrow();
});

// Locale and Option Variations
test('formats date with different locales', () => {
const date = '2024-03-01';
expect(formatDate(date, {locale: 'fr-FR'})).not.toBe(formatDate(date, {locale: 'de-DE'}));
});

test('formats date with different options', () => {
const date = '2024-03-01';
const options1 = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
} as DateFormatOptions;
const options2 = {
year: '2-digit',
month: 'numeric',
day: 'numeric',
} as DateFormatOptions;

expect(formatDate(date, {locale: 'en-US', intlOptions: options1})).not.toBe(
formatDate(date, {locale: 'en-US', intlOptions: options2}),
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import formatDateTime from '../formatDateTime';
import { DateTimeFormatOptions } from '../types';

describe('dateTime - formatDateTime', () => {
// Basic Functionality Tests
test.each([
['2024-01-01T12:00:00', 'en-US', undefined, '1/1/2024, 12:00:00 PM'], // US format with time
['2024-01-01T00:00:00', 'en-GB', { hour12: false }, '01/01/2024, 00:00:00'], // UK format with midnight time
['2024-02-29T15:30:00', 'en-US', { hour12: false }, '2/29/2024, 15:30:00'], // Leap year with 24-hour format
])(
'formats date "%s" with locale "%s" and options %o to "%s"',
(date, locale, options, expected) => {
expect(formatDateTime(date, {locale: locale, intlOptions :options})).toBe(expected);
},
);

test('formats end of year date with time', () => {
expect(formatDateTime('2024-12-31T23:59:59', {locale: 'en-US'})).toBe(
'12/31/2024, 11:59:59 PM',
);
});

test('handles invalid date strings', () => {
expect(() => formatDateTime('invalid-date', {locale: 'en-US'})).toThrow();
});

// Locale and Option Variations
test('formats date and time with different locales', () => {
const date = '2024-03-01T20:00:00';
expect(formatDateTime(date, {locale: 'fr-FR'})).not.toBe(
formatDateTime(date, {locale: 'de-DE'}),
);
});

test('formats date and time with different options', () => {
const date = '2024-03-01T20:00:00';
const options1 = {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: true,
} as DateTimeFormatOptions;
const options2 = {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
} as DateTimeFormatOptions;
expect(formatDateTime(date, {locale: 'en-US', intlOptions :options1})).not.toBe(
formatDateTime(date, {locale: 'en-US', intlOptions: options2}),
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import formatTime from '../formatTime';
import { DateTimeFormatOptions } from '../types';

describe('formatTime function', () => {
// Basic Functionality Tests
test.each([
['2024-01-01T12:00:00', 'en-US', undefined, '12:00:00 PM'], // US format 12-hour clock
['2024-01-01T00:00:00', 'en-GB', { hour12: false }, '00:00:00'], // UK format 24-hour clock
['2024-01-01T15:30:00', 'en-US', { hour12: false }, '15:30:00'], // US format 24-hour clock
])(
'formats time "%s" with locale "%s" and options %o to "%s"',
(date, locale, options, expected) => {
expect(formatTime(date, {locale, intlOptions :options})).toBe(expected);
},
);

test('formats midnight time', () => {
expect(formatTime('2024-01-01T00:00:00', {locale: 'en-US'})).toBe('12:00:00 AM');
});

test('formats end of day time', () => {
expect(formatTime('2024-01-01T23:59:59', {locale: 'en-US'})).toBe('11:59:59 PM');
});

test('formats time with different options', () => {
const date = '2024-03-01T20:00:00';
const options1 = {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: true,
} as Omit<DateTimeFormatOptions, 'dateStyle'>;
const options2 = {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
} as Omit<DateTimeFormatOptions, 'dateStyle'>;
expect(formatTime(date, {locale: 'en-US', intlOptions :options1})).not.toBe(
formatTime(date, {locale: 'en-US', intlOptions: options2}),
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import getQuarter from '../getQuarter';

describe('dateTime - getQuarter', () => {
test('returns 1 for dates in the first quarter', () => {
expect(getQuarter('2024-01-01')).toBe(1); // Beginning of Q1
expect(getQuarter('2024-02-15')).toBe(1); // Middle of Q1
expect(getQuarter('2024-03-31')).toBe(1); // End of Q1
});

test('returns 2 for dates in the second quarter', () => {
expect(getQuarter('2024-04-01')).toBe(2); // Beginning of Q2
expect(getQuarter('2024-05-15')).toBe(2); // Middle of Q2
expect(getQuarter('2024-06-30')).toBe(2); // End of Q2
});

test('returns 3 for dates in the third quarter', () => {
expect(getQuarter('2024-07-01')).toBe(3); // Beginning of Q3
expect(getQuarter('2024-08-15')).toBe(3); // Middle of Q3
expect(getQuarter('2024-09-30')).toBe(3); // End of Q3
});

test('returns 4 for dates in the fourth quarter', () => {
expect(getQuarter('2024-10-01')).toBe(4); // Beginning of Q4
expect(getQuarter('2024-11-15')).toBe(4); // Middle of Q4
expect(getQuarter('2024-12-31')).toBe(4); // End of Q4
});

test('handles string and Date inputs', () => {
expect(getQuarter('2024-04-15')).toBe(2); // String input
expect(getQuarter(new Date('2024-04-15'))).toBe(2); // Date object input
});

test('throws an error for invalid date inputs', () => {
expect(() => getQuarter('invalid-date')).toThrow(
'Date format not recognized',
);
});
});
Loading
Loading