Open1
国際化対応、DatePicker、Timezone留意点
Supabase(date型)を使用した場合の、フロントエンド側の処理(多言語アプリ)
Dateオブジェクトの振る舞い(Timezone)
日本標準時での 2023-05-07は、UTC で見ると 2023 年 5 月 6 日の 15 時+9時間という考え方です。new Date('2023-05-07') で Date オブジェクトを作成すると、ブラウザはこの文字列をローカルタイムゾーンで解釈し、UTC で見たときの 2023 年 5 月 6 日の 15 時として Date オブジェクトを作成します。
DatePickerライブラリを使用すると、単純な文字列ではうけつけてくれないので、Dateオブジェクトの振る舞いを正しく理解した、処理が必要になります。
なにも配慮をしないと、DatePickerで2023年05月07日を選択したとき、選択後に表示されるDateInputフィールドの表示が、2023/05/06というおかしなことになる。
以下、対応後のコード
Postロジック
jsxの一部
onChange={(date) => handleDateChange(date,"add")}
handleDateChange関数
const handleDateChange = (date:Date|null,editStatus:"add"|"edit"):void =>{
if(editStatus === "add"){
if (date) {
const dateInLocalTimezone = new Date(date.getTime() - (date.getTimezoneOffset() * 60000));
setInputComment({
...inputComment,
date: dateInLocalTimezone.toISOString().substring(0, 10),
});
} else {
setInputComment({
...inputComment,
date: null,
});
}
// Edit comment date
} else {
if (date) {
const dateInLocalTimezone = new Date(date.getTime() - (date.getTimezoneOffset() * 60000));
dispatch(updateEditedComment({
...editedComment,
date: date ? dateInLocalTimezone.toISOString().substring(0, 10) : '',
})
)
}
}
}
表示ロジック
APIで受け取った、DateStringの変換
const switchDateFormatInList = (dateString: string):string => {
const localDate = new Date(dateString)
const offset = localDate.getTimezoneOffset() // ブラウザのローカルタイムとUTCとの差を分単位で取得
const utcTimestamp = Date.parse(dateString) // UTCのタイムスタンプを取得
// ブラウザのローカルタイムを計算して、フォーマットを整える
const localTimestamp = utcTimestamp - (offset * 60 * 1000)
const localDateObj = new Date(localTimestamp)
const year = localDateObj.getFullYear()
const month = ('00' + (localDateObj.getMonth() + 1)).slice(-2)
const day = ('00' + localDateObj.getDate()).slice(-2)
if (locale === 'ja-JP') {
return `${year}/${month}/${day}`
} else {
return `${month}/${day}/${year}`
}
}