@drewsonne/maya-dates
v1.3.11
Published
Typescript package to manipulate dates in the Maya Calendar
Maintainers
Readme
@drewsonne/maya-dates
A typescript library for interacting with and modifying both the Maya Long Count (LC) and Calendar Round (CR) dates.
Table of Contents
Node.js Support
This library supports Node.js versions 20, 22, and 24 (LTS). Development is done on Node 24.
Quickstart
npm install @drewsonne/maya-datesimport { LongCountFactory } from '@drewsonne/maya-dates';
// Long Count from Initial Series on east side of Stele E, Quirigua
const lc = new LongCountFactory().parse('9.17.0.0.0');
console.log(`${lc.buildFullDate()}`);This should print 13 Ajaw 18 Kumk'u 9.17. 0. 0. 0.
Instructions
Most implementations will consist of creating a fullDate, and passing it to an operation.
Date Creation
Creating a fullDate can be done either by:
- using a factory class (
LongCountFactory,CalendarRoundFactory,FullDateFactory) and calling itsparse(raw_string)function, whereraw_stringis a LC, CR, or CR and LC combination encoded as a string. To specify missing values in a fullDate, using*. For example,
import {
Wildcard,
isWildcard,
LongCountFactory,
CalendarRoundFactory,
FullDateFactory
} from '@drewsonne/maya-dates';
const wildcard = new Wildcard();
const partial_lc = new LongCountFactory().parse('9.17.0.0.*');
const partial_cr = new CalendarRoundFactory().parse('13 Ajaw * Kumk\'u');
const partial_date = new FullDateFactory().parse('13 Ajaw * Kumk\'u 9.17.0.0.*');
console.log(`LC: ${isWildcard(partial_lc.kIn)}`);
console.log(`CR: ${isWildcard(partial_cr.haab.coeff)}`);
console.log(`Full Date: ${isWildcard(partial_date.lc.kIn)}`);- passing explicit values into a model factory or class (
getCalendarRound,LongCount,FullDate).
import {
getCalendarRound,
getHaab,
getTzolkin,
getHaabMonth,
getTzolkinDay,
coefficientParser as _,
FullDate,
LongCount
} from '@drewsonne/maya-dates';
const calendarRound = getCalendarRound(
getTzolkin(_(13), getTzolkinDay('Ajaw')),
getHaab(_(18), getHaabMonth('Kumk\'u'))
);
const lc = new LongCount(0, 0, 0, 17, 9);
const fullDate = new FullDate(calendarRound, lc);
console.log(`${lc}`);
console.log(`${calendarRound}`);
console.log(`${fullDate}`);Operations
Once a full date object has been created, you can either add an integer to a fullDate
using shift(number), or filling in missing values in wildcards. The
operations module provides operators to expand a fullDate with a wildcard into all possible
values for dates matching that wildcard pattern.
<<<<<<< HEAD
Migration Guide
Modern Import Syntax
This version introduces the exports field for better encapsulation and tree-shaking support.
Recommended: Named imports from package root
import { LongCountFactory, CalendarRoundFactory, FullDateFactory } from "@drewsonne/maya-dates";Backwards Compatible (deprecated): Deep imports
// ⚠️ DEPRECATED: Still works for backwards compatibility
import LongCountFactory from "@drewsonne/maya-dates/lib/factory/long-count";
import CalendarRoundFactory from "@drewsonne/maya-dates/lib/factory/calendar-round";Note: Deep imports via /lib/* are supported for backwards compatibility but may be removed in a future major version. Please migrate to named imports from the package root.
Benefits of Modern Imports
- ✅ Better tree-shaking (smaller bundle sizes)
- ✅ Cleaner, more maintainable code
- ✅ Future-proof for ESM support
- ✅ Consistent with modern npm package standards =======
Common Patterns
Parsing Maya Dates
Parse different Maya date formats:
import {
LongCountFactory,
CalendarRoundFactory,
FullDateFactory
} from '@drewsonne/maya-dates';
// Parse a Long Count date
const lcFactory = new LongCountFactory();
const longCount = lcFactory.parse('9.17.0.0.0');
// Parse a Calendar Round date
const crFactory = new CalendarRoundFactory();
const calendarRound = crFactory.parse('13 Ajaw 18 Kumk\'u');
// Parse a Full Date (Calendar Round + Long Count)
const fdFactory = new FullDateFactory();
const fullDate = fdFactory.parse('13 Ajaw 18 Kumk\'u 9.17.0.0.0');
console.log(`Long Count: ${longCount}`);
console.log(`Calendar Round: ${calendarRound}`);
console.log(`Full Date: ${fullDate}`);Gregorian to Long Count Conversion
Convert between Gregorian dates and Maya Long Count:
import { LongCount, LongCountFactory } from '@drewsonne/maya-dates';
// Convert from JavaScript Date object
const date = new Date('2012-12-21');
const lc1 = LongCount.fromGregorian(date);
console.log(`Date object = ${lc1}`);
// Output: "Date object = 13. 0. 0. 0. 0"
// Convert from ISO 8601 date string
const lc2 = LongCount.fromGregorian('2012-12-21');
console.log(`ISO 8601 = ${lc2}`);
// Output: "ISO 8601 = 13. 0. 0. 0. 0"
// Alternative: Convert from Julian Day Number directly
const lc3 = LongCount.fromJulianDay(2456283);
console.log(`JDN 2456283 = ${lc3}`);
// Output: "JDN 2456283 = 13. 0. 0. 0. 0"
// Convert Long Count to Gregorian (reverse direction)
const lcFactory = new LongCountFactory();
const longCountDate = lcFactory.parse('13.0.0.0.0');
const gregorian = longCountDate.gregorian;
console.log(`Long Count ${longCountDate} = ${gregorian.day}/${gregorian.month}/${gregorian.year} ${gregorian.era}`);
// Output: "Long Count 13. 0. 0. 0. 0 = 21/12/2012 CE"
// Roundtrip conversion example
const original = lcFactory.parse('9.17.0.0.0');
const asGregorian = original.gregorian;
const backToLC = LongCount.fromJulianDay(asGregorian.julianDay);
console.log(`Original: ${original}, Roundtrip: ${backToLC}`);
// Both will be identical: " 9.17. 0. 0. 0"Available conversion methods:
LongCount.fromGregorian(date | isoString, correlation?)- Convert from Date object or ISO 8601 date string (date only)LongCount.fromJulianDay(jdn, correlation?)- Convert from Julian Day NumberLongCount.fromMayanDayNumber(mdn, correlation?)- Convert from Maya Day NumberlongCount.gregorian- Convert Long Count to Gregorian (getter property)longCount.julianDay- Get Julian Day Number for Long Count (getter property)
Working with Wildcards
Use wildcards to represent partial or unknown dates:
import {
LongCountFactory,
isWildcard,
LongCountWildcard
} from '@drewsonne/maya-dates';
// Create a partial date with a wildcard
const partialLc = new LongCountFactory().parse('9.17.0.0.*');
// Check if a component is a wildcard
if (isWildcard(partialLc.kIn)) {
console.log('The k\'in position is a wildcard');
}
// Expand wildcards to get all possible dates
const wildcard = new LongCountWildcard(partialLc);
const allDates = wildcard.run();
console.log(`Found ${allDates.length} possible dates`);Date Arithmetic
Perform arithmetic operations on Maya dates:
import { LongCountFactory, LongCount, DistanceNumber } from '@drewsonne/maya-dates';
const lc = new LongCountFactory().parse('9.17.0.0.0');
// Add days using plus() with a DistanceNumber
const oneDay = new DistanceNumber(1);
const nextDate = lc.plus(LongCount.fromDistanceNumber(oneDay)).equals();
console.log(`Next day: ${nextDate}`);
// Add multiple days
const manyDays = new DistanceNumber(365);
const futureDate = lc.plus(LongCount.fromDistanceNumber(manyDays)).equals();
console.log(`365 days later: ${futureDate}`);
// Subtract days using minus()
const hundredDays = new DistanceNumber(100);
const pastDate = lc.minus(LongCount.fromDistanceNumber(hundredDays)).equals();
console.log(`100 days earlier: ${pastDate}`);
// Get the full Calendar Round for a Long Count
const fullDate = lc.buildFullDate();
console.log(`Full date: ${fullDate}`);
// Shift Calendar Round dates
const shifted = fullDate.cr.shift(20);
console.log(`Calendar Round shifted by 20 days: ${shifted}`);Alternative Spellings (i18n)
Support alternative spellings and transliterations of Maya calendar terms:
import {
CalendarRoundFactory,
getI18nManager,
LocaleDefinition
} from '@drewsonne/maya-dates';
// Register alternative spellings
const i18n = getI18nManager();
const altSpellings: LocaleDefinition = {
locale: 'alternative',
name: 'Alternative Spellings',
tzolkinDays: {
'Ajaw': { canonical: 'Ajaw', alternatives: ['Ahau', 'Ajau'] }
},
haabMonths: {
'Kumk\'u': { canonical: 'Kumk\'u', alternatives: ['Kumku', 'Cumku'] }
}
};
i18n.registerLocale(altSpellings);
// Parse dates using alternative spellings
const factory = new CalendarRoundFactory();
const cr1 = factory.parse('4 Ahau 8 Kumku'); // Alternative
const cr2 = factory.parse('4 Ajaw 8 Kumk\'u'); // Canonical
// Both produce the same result
console.log(cr1.toString()); // "4 Ajaw 8 Kumk'u"
console.log(cr2.toString()); // "4 Ajaw 8 Kumk'u"For more details, see I18n Documentation and the i18n example.
Migration Guide
Upgrading from v1.x
If you're upgrading from version 1.x, you'll need to update your import statements.
Before (v1.x):
import LongCountFactory from "@drewsonne/maya-dates/lib/factory/long-count";
import {Wildcard, isWildcard} from "@drewsonne/maya-dates/lib/wildcard";
import {getCalendarRound} from "@drewsonne/maya-dates/lib/cr/calendar-round";After (v2.x):
import {
LongCountFactory,
Wildcard,
isWildcard,
getCalendarRound
} from '@drewsonne/maya-dates';Key Changes:
- All exports are now available from the package root (
@drewsonne/maya-dates) - No need to specify
/lib/paths or know internal directory structure - Factory classes are now named exports instead of default exports
- All class and function exports use named exports for better tree-shaking
Migration Steps:
- Replace all
/lib/...imports with root-level imports - Change default imports to named imports for factory classes
- Group related imports together in a single import statement
- Test your code to ensure all imports resolve correctly
7cb1fe3 (Add modern import examples, Common Patterns section, and runnable examples)
Development
See docs/development/workflow.md for the development workflow and contribution guidelines.
Building
npm run build # Compile TypeScript to JavaScript
npm run build:check # Type check without emitting filesTesting
npm test # Run all tests
npm run test:coverage # Run tests with coverage reportDocumentation
npm run docs:start # Start Docusaurus dev server
npm run docs:build # Build static documentation site
npm run docs:serve # Serve built documentation locallyDocumentation
Full documentation is built with Docusaurus and includes API reference generated from TypeDoc. You can browse the documentation at https://drewsonne.github.io/maya-dates/.
