npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fancy-date

v0.11.0

Published

架空の暦を扱う

Downloads

1,240

Readme

fancy-date

Build Status

インストール

bun add fancy-date

API 利用例

import { Calendar } from 'fancy-date'

const g = Calendar.Gregorian

Calendar には、Gregorian / Julian / 定気法 / Maya / エジプト民用暦 / コプト暦などのサンプル暦が入っている。各暦は FancyDate インスタンスなので、同じ API で parse、format、span、add/sub を使える。

token の意味、format / find / span での使い分け、precise や循環 token の詳しい扱いは docs/manual.md にまとめている。

タイ暦は近似モデルと固有規則モデルを分けている。Calendar.タイ太陰太陽暦 は平均モデル、Calendar.タイ太陰太陽暦天文 は観測近似、Calendar.タイ太陰太陽暦公式 はタイ固有の年型判定と civil month table を使う規則モデルである。規則モデルでは通常年354日、7月加日の年355日、8月を重複する年384日を区別する。1903〜2460年は参照実装との照合範囲で、2461年以後は同じ算術規則を連続適用する proleptic 計算として扱う。これは将来のタイ政府公表年表を保証するものではない。

const thai = Calendar.タイ太陰太陽暦公式
const utc = Date.parse('2026-07-14T17:00:00Z')

thai.format(utc, 'y-M-d')
// '2569-閏8-1'

thai.thaiLunisolar(utc).is_leap
// true

一般化の仕様案は docs/lunisolar-generalization-proposal.md を参照。

教会暦とComputus

Computus は、実際の月を SATELLITE として公開するものではなく、教会暦上の満月と復活祭を求める独立した計算規則である。計算に使う伝統と、結果を表示する市民暦は分けて指定できる。

const easter = churchFeastDates(Calendar.Gregorian, 2024).find(({ id }) => id === 'easter-sunday')

easter.label
// '復活祭'

churchFeastNotes(Calendar.Gregorian, easter.utc)
// ['復活祭']

Julian系の教会暦をGregorianの日付で表示する場合は、systemcalendarSystem を別に指定する。

churchFeastDates(Calendar.Gregorian, 2024, {
  system: 'julian',
  calendarSystem: 'gregorian',
})

parse / format

parse() は暦表現を UTC ミリ秒へ変換し、format() は UTC ミリ秒や暦オブジェクトを文字列へ戻す。

const utc = g.parse('2024年3月10日')

g.format(utc, 'Gy年MM月dd日(E)')
// '西暦2024年03月10日(日)'

書式は y/M/d/H/m/s/S のような階層 token と、G 元号、E 曜日、yC60/dC60 干支などの暦 token を組み合わせる。G を含めない古い年は、符号付き通年として出る。

const nabonassar = Calendar.Julian.parse('紀元前747年2月26日')

Calendar.Julian.format(nabonassar, 'Gy年MM月dd日')
// '紀元前747年02月26日'

Calendar.Julian.format(nabonassar, 'y年M月d日')
// '-746年2月26日'

span / add / sub

span([from, to]) は相対表現を返す。span_obj() は再適用可能な Span (差分mapと labelnext_attimeout)を返す。周期・暦注tokenを precise に指定した場合だけは、加算不能な SpanMeasure を返す。span_msec() は anchor 付き Span を実ミリ秒へ戻す。

const from = g.parse('2024年1月1日 0時0分0秒', 'y年M月d日 H時m分s秒')
const to = g.parse('2025年3月10日 4時5分6秒', 'y年M月d日 H時m分s秒')

g.span([from, to], { precise: 'm' })
// '1年2ヶ月9日4時間5分後'

g.span([from, to], { precise: 'w' })
// '1年10週後'

precise の階層 token は y/M/d/H/m/s/SY/w/Dw は週年 Y と組になり、D は年初からの日番号として y と組になる。ただし SpanDiff の表示順は地球的な大きさ順 y/M/w/d/H/m/s/S に固定し、D 精度の測定結果も通常の日数 d へ正規化する。

g.add(from, '1年2ヶ月9日4時間5分後')
// 2025年3月10日 4時5分

g.sub(to, '1年2ヶ月9日4時間5分後')
// 2024年1月1日 0時0分

yC60/yC12/yC10/yC9/dC60/dC12/dC10/dC9/dC7/dC28/R6/LM27 などの周期・暦注 token は、干支・曜日・宿・六曜のようなラベル差を表す。日時加算としては曖昧なので、add() / sub() では使わない。旧 a/c/b/A/C/ByC/yCB/yCS/dC/dCB/dCS も互換 alias として使える。

find

find([from, to], conditions) は範囲内で条件に合う暦境界を探す。探索 step は条件から推定される。 periods([from, to], { step }) は同じ探索規則で、指定 step の Tempo 範囲を列挙する。

const between = [g.parse('2020年1月1日'), g.parse('2020年3月1日')]

g.find(between, [{ dC60o: '甲子' }]).map((utc) => g.format(utc, 'yyyy年MM月dd日 dC60o'))
// ['2020年01月22日 甲子']

g.periods(between, { step: 'M' }).map((month) => g.format(month.last_at, 'yyyy年MM月'))
// ['2020年01月', '2020年02月']

note 条件は note() の表示名から探す。正規表現も使える。

g.find([g.parse('2020年3月1日'), g.parse('2020年10月1日')], [{ note: /春分|秋分/ }])

必要なら step を明示できる。 無制限の範囲では limit を指定し、昇順なら from、降順なら to を有限値にする。

g.find([g.parse('2020年3月1日'), g.parse('2020年3月2日')], [{ H: '12' }], {
  step: 'H',
})

g.find([g.parse('2020年1月23日'), Infinity], [{ dC60o: '甲子' }], { limit: 1 })
// 次の甲子日

g.find([-Infinity, g.parse('2020年3月1日')], [{ dC60o: '甲子' }], {
  order: -1,
  limit: 1,
})
// 前の甲子日

parse_span / format_span / labels

parse_span() は相対表現を正規化した Span にし、format_span()SpanLike を現在の暦の表記へ整える。SpanLike は文字列または加算可能tokenの差分mapで、正数は未来方向を表す。

const custom = new FancyDate(g).labels({ w: '週目', dC: '日巡り' }).init()

custom.span([from, to], { precise: 'w' })
// '1年10週目後'

const span = custom.parse_span('1年2ヶ月後')
// { y: 1, M: 2, label: '1年2ヶ月後' }

custom.add(from, { y: 1, M: 2 })

custom.span_obj(g.parse('2024年1月2日'), from, { precise: 'dC60' })
// { precision: 'dC60', value: 1, label: '1日巡り後' }

const anchored = g.parse_span('1ヶ月後', { at: from })
g.span_msec(anchored)
// from から1ヶ月後までの実ミリ秒

g.span_add('3日後', '1日前').label
// '2日後'

g.span_add('1ヶ月後', '31日前').label
// '1ヶ月後31日前'

custom.format_span_parts({ y: 1, M: 2 })
// [{ text: '1年' }, { text: '2ヶ月' }, { text: '後' }]

custom.span_sub({ dC60: '乙丑' }, { dC60: '甲子' })
// { d: 1, label: '1日後' }

labels() は fallback の単位表記を差し替える。notation() の第3要素で token ごとの相対表現を定義している場合は、そちらが優先される。algo() は互換 alias として残している。

サンプル暦

Calendar.エジプト民用暦.format(Calendar.エジプト民用暦.parse('1年1月1日'), 'Gy年Mod日')
// 'ナボナサル紀元1年トート1日'

Calendar.コプト暦.format(Calendar.コプト暦.parse('1739年1月1日'), 'Gy年Mod日')
// 'コプト暦1739年トウト1日'

開発者向け情報

今後の検討メモ・調査結果・実装ログは docs/development-notes.md に、数詞ライブラリの設計案は docs/numeral-design.md にまとめている。