Skip to content

Commit

Permalink
feat: time format with timezone
Browse files Browse the repository at this point in the history
  • Loading branch information
jungpaeng committed Oct 3, 2023
1 parent 9d26e79 commit 51c2d4f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
5 changes: 3 additions & 2 deletions packages/core/src/use-translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export function useTranslation(namespace?: string) {
message: allMessage,
locale,
formats: globalFormats,
timeZone,
onError,
getMessageFallback,
} = useIntlContext();
Expand Down Expand Up @@ -154,7 +155,7 @@ export function useTranslation(namespace?: string) {
messageFormat = new IntlMessageFormat(
message,
locale,
convertFormatToIntlMessageFormat({ ...globalFormats, ...format }),
convertFormatToIntlMessageFormat({ ...globalFormats, ...format }, timeZone),
);
} catch (_error) {
const error = _error as SystemError;
Expand Down Expand Up @@ -192,6 +193,6 @@ export function useTranslation(namespace?: string) {
return getFallbackFromError(IntlErrorCode.FORMATTING_ERROR, error.message);
}
},
[getMessageFallback, globalFormats, locale, messageOrError, namespace, onError],
[getMessageFallback, globalFormats, locale, messageOrError, namespace, onError, timeZone],
);
}
33 changes: 29 additions & 4 deletions packages/core/src/utils/convert-format-to-intl-message-format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,35 @@ import { type Formats as IntlFormat } from 'intl-messageformat';

import { type Format } from '../types/format';

export function convertFormatToIntlMessageFormat(format: Partial<Format>): Partial<IntlFormat> {
export function convertFormatToIntlMessageFormat(
format: Partial<Format>,
timeZone?: string,
): Partial<IntlFormat> {
const formatsWithTimeZone = timeZone
? { ...format, dateTime: getFormatWithTimeZone(format.dateTime, timeZone) }
: format;

return {
...format,
date: format?.dateTime,
time: format?.dateTime,
...formatsWithTimeZone,
date: formatsWithTimeZone?.dateTime,
time: formatsWithTimeZone?.dateTime,
};
}

function getFormatWithTimeZone(
dateTimeFormat: Record<string, Intl.DateTimeFormatOptions> | undefined,
timeZone: string,
) {
if (dateTimeFormat == null) return dateTimeFormat;

// https://github.com/formatjs/formatjs/blob/2567b932c5d18b097a43842563046c20ce0c49f1/packages/intl/src/message.ts#L15
return Object.keys(dateTimeFormat).reduce(
(prev: Record<string, Intl.DateTimeFormatOptions>, curr) => {
return {
...prev,
[curr]: { timeZone, ...dateTimeFormat[curr] },
};
},
{},
);
}
11 changes: 10 additions & 1 deletion packages/core/test/use-translation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function renderMessage(message: string, values?: TranslationValue, format?: Part
}

return render(
<IntlProvider message={{ message }} locale="en">
<IntlProvider message={{ message }} locale="en" timeZone="Asia/Seoul">
<Component />
</IntlProvider>,
);
Expand Down Expand Up @@ -62,6 +62,15 @@ describe('use-translation', () => {
screen.getByText('Coupon expires at 9:00 AM');
});

it('should be print time with timezone', () => {
renderMessage(
'Coupon expires at {expires, time, time}',
{ expires: new Date('2023-10-01') },
{ dateTime: { time: { hour: 'numeric', minute: '2-digit' } } },
);
screen.getByText('Coupon expires at 9:00 AM');
});

it('should be print select format', () => {
renderMessage('{ gender, select, male {He} female {She} other {They} } will respond shortly.', {
gender: 'male',
Expand Down

0 comments on commit 51c2d4f

Please sign in to comment.