React Native の DateTimePicker のカレンダーをローカライズされた形で表示させたいケースがあると思います。
iOS に限り、 locale
というプロパティでローカライズできるようです。
https://github.com/react-native-datetimepicker/datetimepicker
地域や言語の情報は expo-localization
を使って取得します。
expo-localization
をインストールします。
shell
npx expo install expo-localization
Expo の Localization については以下のドキュメントに詳細があります。
https://docs.expo.dev/versions/latest/sdk/localization/
取得部分のコードは以下のとおりです。
Sample.ts
import { getLocales } from 'expo-localization';
const locales = getLocales();
const languageTag = locales[0].languageTag;
console.log('locales:', locales[0].languageTag);
日本語環境の場合、locales: ja-JP
のように表示されます。
設定 > 一般 > 言語と地域 > 地域
を「アメリカ合衆国」に変更したら、 ja-US
になります。 -
で区切られた後ろ側が「地域」になるわけですね。前半は「言語」なので、設定で言語を「英語」にすると、 en-US
になります。
en-US
の場合、カレンダーは June 2023
のようにアメリカっぽく表示されます。
日付は Jun 26, 2023
で表示されてますね。
DateTimePicker
のコードは以下のようにしています。
DateTimePicker.tsx
<DateTimePicker
testID="dateTimePickerStart"
value={registerDate}
mode="date"
display="default"
onChange={onRegisterDateChange}
locale={languageTag}
/>
ダイアログ全体のコードは以下のようになっています。自分の作っているアプリの特性が前面に出ていますが、その辺は無視して、参考にできる部分をつまみ食いしていただければと思います。
Component.tsx
import { convertUTCToLocalISOString } from '../../lib/utils/timeUtil';
import DateTimePicker, { type DateTimePickerEvent } from '@react-native-community/datetimepicker';
import { getLocales } from 'expo-localization';
import React, { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import Dialog from 'react-native-dialog';
interface DocumentingDialogProps {
documentingDialogVisible: boolean;
setDocumentingDialogVisible: React.Dispatch<React.SetStateAction<boolean>>;
}
export default function DocumentingDialog({
documentingDialogVisible,
setDocumentingDialogVisible,
}: DocumentingDialogProps) {
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const locales = getLocales();
const languageTag = locales[0].languageTag;
const [registerDate, setRegisterDate] = useState<Date>(new Date());
const onRegisterDateChange = (event: DateTimePickerEvent, selectedDate?: Date) => {
const currentDate = selectedDate !== undefined ? selectedDate : registerDate;
setRegisterDate(currentDate);
console.log('locales:', locales[0].languageTag);
};
return (
<Dialog.Container visible={documentingDialogVisible}>
<Dialog.Title>努力を記録する</Dialog.Title>
<Dialog.Description>
登録する日:{convertUTCToLocalISOString(registerDate.toISOString(), timezone)}
</Dialog.Description>
<View style={styles.datePickerWrapper}>
<DateTimePicker
testID="dateTimePickerStart"
value={registerDate}
mode="date"
display="default"
onChange={onRegisterDateChange}
locale={languageTag}
/>
</View>
<Dialog.Button
label="Cancel"
onPress={() => {
setDocumentingDialogVisible(false);
}}
/>
<Dialog.Button
label="OK"
onPress={async () => {
// await documentResults(tasks);
setDocumentingDialogVisible(false);
}}
/>
</Dialog.Container>
);
}
const styles = StyleSheet.create({
datePickerWrapper: {
justifyContent: 'center',
alignItems: 'center',
marginVertical: 30,
},
});