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

@gramps-connect/gramps-date

v0.1.0

Published

Gramps' Date in TypeScript: parse and display dates the way Gramps does, in all 43 of its languages, with calendar conversion and Extended Date/Time Format (EDTF) output.

Readme

@gramps-connect/gramps-date

Gramps' Date in TypeScript: parse and display dates exactly the way Gramps does, in all 43 of its languages, convert between its ten calendars, and turn a date into Extended Date/Time Format (EDTF). No dependencies; runs in browsers and Node.

npm install @gramps-connect/gramps-date
import { formatDate, loadLocale, parseDate, toEdtf } from "@gramps-connect/gramps-date";

const date = parseDate("abt 3 May 1850");  // a GrampsDate struct
formatDate(date);                          // "about 3 May 1850"
toEdtf(date);                              // "1850-05-03~"

await loadLocale("de");                    // other languages load on demand
toEdtf(parseDate("um 1850", { locale: "de" }));  // "1850~"

It was written for Gramps Connect, which receives raw Gramps Date structs from gramps-web-api (e.g. a {"json_path": [..., "date"]} select entry against the fast /query/ endpoints) and needs to render or build them without a per-object round trip through Gramps' own Python date displayer. The story editor uses it to read the dates people type.

What's here

  • types.ts -- the wire-format GrampsDate struct and Modifier/ Quality/Calendar/NewYear enums.
  • calendar.ts -- SDN (Serial/Julian Day Number) conversion for all ten Gramps calendars, and calendar-aware date validation. That includes the lunisolar calendars of Gramps 6.2 -- Chinese, Korean and Vietnamese Lunar, whose months 101-112 are leap months -- over their year tables (lunarTables.generated.ts, from Gramps' lunartables.py). Korea's and Vietnam's calendars are computed for their own meridians, so they have their own tables where they differ from China's.
  • display.ts -- formatDate(date, options): Gramps' DateDisplay, in every format of every language Gramps has (43, from po/LINGUAS plus English): modifiers, quality, compound dates, calendar and new-year suffixes, B.C.E., grammatical month forms (Czech, Finnish, Croatian, Russian, Slovak, Slovenian, Ukrainian), and each lunisolar calendar in its own language's form (locales/lunar.ts: "2024年正月1日", "2024년 정월 1일", "Năm 2024 Tháng Giêng Ngày 1").
  • parse.ts -- parseDate(text, options): Gramps' DateParser, so what a user types ("before 1960", "abt Mar 1854 (Julian)") becomes a structured date, and every displayed date reads back.
  • edtf.ts -- toEdtf(date): the date in Extended Date/Time Format (ISO 8601-2), for a Gregorian date with a real year; nothing, rather than something plausible but wrong, for anything else.
  • entry.ts -- makeDate(input) builds a GrampsDate from structured components; validateDate(date) checks it.
  • locale.ts, locales/ -- the DateLocale interface and the languages. English is built in; the others load on demand (loadLocale(code), availableLocales(), resolveLocaleCode(code)), each its own bundle chunk. Their strings are generated from a live Gramps (locales/<code>.generated.ts); the languages whose displayer lays dates out its own way have hand-written layouts in locales/index.ts.

Keeping up with Gramps

scripts/generate_gramps_locales.py regenerates every language's strings, the lunar year tables and the test fixtures from a Gramps (about 4 seconds, one process per language). Run it after a Gramps update, then npm test. The tests check every format of every language against what Gramps itself displays, against the date sets of Gramps' own unit tests, and that every displayed date parses back.

It needs a Gramps with the lunisolar calendars: 6.2, or until then a checkout of the lunar-calendar pull requests (gramps-project/gramps#2374, which builds on #2375 and #2369), with its translations compiled:

GRAMPS=~/src/gramps-lunar            # the checkout
RES=$(mktemp -d)                     # its resources: data + compiled catalogs
ln -s $GRAMPS/data $RES/gramps
for lang in $(grep -v '^#' $GRAMPS/po/LINGUAS); do
  mkdir -p $RES/locale/$lang/LC_MESSAGES
  msgfmt -o $RES/locale/$lang/LC_MESSAGES/gramps.mo $GRAMPS/po/$lang.po
done
PYTHONPATH=$GRAMPS GRAMPS_RESOURCES=$RES python3 scripts/generate_gramps_locales.py

Where Gramps is wrong -- a displayed date that doesn't read back, a crash, lost input -- gramps-date does the right thing instead, and the case is recorded in GRAMPS_BUGS.md for reporting upstream (src/__tests__/knownGrampsBugs.ts lists the ones whose Gramps text still reads back, so the tests accept ours there).

Provenance and license

This package is a translation of Gramps core's own date model and display logic (gramps/gen/lib/date.py, gramps/gen/lib/gcalendar.py, gramps/gen/datehandler/_datedisplay.py, _datestrings.py) from Python to TypeScript, plus calendar.ts's validation helpers, which follow the same approach gramps-web's own src/gcalendar.js (a prior JS port of the same Python module) already established. Original copyright holders are credited in each file's header, alongside the GPL-2.0-or-later license the original Python source itself carries.

gramps-connect as a whole (including this package) is distributed under AGPL-3.0-or-later, matching gramps-web-api and gramps-web -- GPL-2.0-or-later's "or any later version" clause plus GPLv3/AGPLv3's own mutual-compatibility provisions permit combining GPL-2.0-or-later code into a larger AGPL-3.0-or-later work, the same way gramps-web itself already does for its own gcalendar.js port (one repo-wide AGPL-3.0 LICENSE, despite incorporating GPL-2.0-or-later-derived logic).

Releasing

Tag gramps-date-v<version> (matching package.json) and push it; .github/workflows/release-gramps-date.yml tests and publishes it with provenance.