Skip to content

Commit

Permalink
fix: Use timeZone in translation function from useTranslations (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
amannn authored Aug 2, 2021
1 parent 8042211 commit ebf75f2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 11 deletions.
Binary file added packages/example/public/favicon.ico
Binary file not shown.
34 changes: 30 additions & 4 deletions packages/use-intl/src/convertFormatsToIntlMessageFormat.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
import {Formats as IntlFormats} from 'intl-messageformat';
import DateTimeFormatOptions from './DateTimeFormatOptions';
import Formats from './Formats';

function setTimeZoneInFormats(
formats: Record<string, DateTimeFormatOptions> | undefined,
timeZone: string
) {
if (!formats) return formats;

// The only way to set a time zone with `intl-messageformat` is to merge it into the formats
// https://github.com/formatjs/formatjs/blob/8256c5271505cf2606e48e3c97ecdd16ede4f1b5/packages/intl/src/message.ts#L15
return Object.keys(formats).reduce(
(acc: Record<string, DateTimeFormatOptions>, key) => {
acc[key] = {
timeZone,
...formats[key]
};
return acc;
},
{}
);
}

/**
* `intl-messageformat` uses separate keys for `date` and `time`, but there's
* only one native API: `Intl.DateTimeFormat`. Additionally you might want to
Expand All @@ -9,11 +30,16 @@ import Formats from './Formats';
* to convert the format before `intl-messageformat` can be used.
*/
export default function convertFormatsToIntlMessageFormat(
formats: Partial<Formats>
formats: Partial<Formats>,
timeZone?: string
): Partial<IntlFormats> {
const formatsWithTimeZone = timeZone
? {...formats, dateTime: setTimeZoneInFormats(formats.dateTime, timeZone)}
: formats;

return {
...formats,
date: formats?.dateTime,
time: formats?.dateTime
...formatsWithTimeZone,
date: formatsWithTimeZone?.dateTime,
time: formatsWithTimeZone?.dateTime
};
}
11 changes: 8 additions & 3 deletions packages/use-intl/src/useTranslations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ export default function useTranslations(namespace?: string) {
getMessageFallback,
locale,
messages: allMessages,
onError
onError,
timeZone
} = useIntlContext();

const cachedFormatsByLocaleRef = useRef<
Expand Down Expand Up @@ -177,7 +178,10 @@ export default function useTranslations(namespace?: string) {
messageFormat = new IntlMessageFormat(
message,
locale,
convertFormatsToIntlMessageFormat({...globalFormats, ...formats})
convertFormatsToIntlMessageFormat(
{...globalFormats, ...formats},
timeZone
)
);
} catch (error) {
return getFallbackFromError(
Expand Down Expand Up @@ -225,7 +229,8 @@ export default function useTranslations(namespace?: string) {
locale,
messagesOrError,
namespace,
onError
onError,
timeZone
]
);

Expand Down
13 changes: 9 additions & 4 deletions packages/use-intl/test/useTranslations.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ function renderMessage(
}

return render(
<IntlProvider locale="en" messages={{message}}>
<IntlProvider
formats={{dateTime: {time: {hour: 'numeric', minute: '2-digit'}}}}
locale="en"
messages={{message}}
timeZone="Europe/London"
>
<Component />
</IntlProvider>
);
Expand Down Expand Up @@ -74,11 +79,11 @@ it('handles date formatting', () => {
screen.getByText('Nov 19, 2020');
});

it('handles time formatting', () => {
renderMessage('{now, time, short}', {
it('applies a time zone for provided formats', () => {
renderMessage('{now, time, time}', {
now: parseISO('2020-11-19T15:38:43.700Z')
});
screen.getByText('4:38 PM');
screen.getByText('3:38 PM');
});

it('handles pluralisation', () => {
Expand Down

0 comments on commit ebf75f2

Please sign in to comment.