- moment.js の後継っぽい日時うにょるやつ
- 書き方は dayjs のほうが moment.js に近いし人気ある
- immutable で API がきれいなのと、TZ の取り回しが直感的らしい
- date-fns が JS Date オブジェクトの helper 的な拡張なのに対して、こっちは独自の DateTime オブジェクトを内部的に取り回すぽい
JS の日時操作ライブラリを比較する: date-fns のインターフェイスがイカす
JavaScriptの日時ライブラリを比較してみた
個人的には「TZ 含めて全部入り」として使うなら luxon が良さそうに見えてる。date-fns の「関数型 x JS Date の素材の味そのまま」アプローチは「面白いけど、日付処理として使いやすいとは言い切れない」という感想。
ここと A quick tour でだいたいわかる。
$ npm i luxon
$ npm i -D @types/luxon
import { Settings, DateTime } from 'luxon'
// こいつを bootstrap 的な場所に書いて TZ 固定
Settings.defaultLocale = 'ja'
Settings.defaultZone = 'Asia/Tokyo'
DateTime.local().zoneName; //=> 'Asia/Tokyo'
// あるいは export してこっちを使い回すようにするとか
export const Luxon = DateTime
/**
* datetime-local input の value 値に変換するやつ
*/
export const datetime2string = (dt: DateTime) => (
`${dt.toISO()}`.substring(0, 16)
)
/**
* なんらか「よくある日付形式」を受けて datetime を返す
*
* - string: serialized された ISO 形式と判断して fromISO で返す
* - number: millisecond と解釈して fromMillis で返す
* - Date: instanceof Date が true なら fromJSDate して返す
* - その他: date が falsy だったり、上記以外なら now を返す
*/
export const any2datetime = (date: any) => {
if (date && typeof date === 'string') {
return Luxon.fromISO(date)
}
if (date && typeof date === 'number') {
return Luxon.fromMillis(date)
}
if (date && date instanceof Date) {
return Luxon.fromJSDate(date)
}
return Luxon.now()
}
- 基本 DateTime で操作して
.toISO()
や.toUnixInteger()
で吐く感じ- 演算系は
.plus()
.minus()
.diff()
あたりでいい - 入出力は
.toObject()
や.fromObject()
が使いやすそう - 数値からなら
.utc(2022, 1, 1)
とか.local(2022, 1, 1)
とか .startOf('day')
でその日の始まり (0 時 0 分 0 秒) とかにしてくれる
- 演算系は
- date-fns と違い標準 Date を返却しないので 全体通して
new Date()
を使わない で固めたほうがいい気がする- とはいえ JS Date を返したいなら
.toJSDate()
もあるので好みかも
- とはいえ JS Date を返したいなら
- TZ は基本
.setZone('America/New_York')
みたいな感じでよさそう- locale は
.setLocale('ja')
でいいのかな?
- locale は
DateTime.now().toLocaleString(
DateTime.DATETIME_SHORT // 2022/8/29 0:00
)
const yesterday = DateTime.fromISO('2023-06-21T09:00:00.000')
const today = DateTime.fromISO('2023-06-22T09:00:00.000')
const tomorrow = DateTime.fromISO('2023-06-23T09:00:00.000')
yesterday.diff(today).as('days') // -1
today.diff(today).as('days') // 0
tomorrow.diff(today).as('days') // 1
// 今日 ひく 昨日、で、今日が昨日に何日分勝っているか、みたいなイメージ
today.diff(yesterday).as('day') // 1
today.diff(tomorrow).as('day') // -1
yesterday.diffNow() // 負
tomorrow.diffNow() // 正