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

@gooddadmike/ifc-js

v1.0.4

Published

International Fixed Calendar conversion library — Gregorian to IFC and back

Readme

@gooddadmike/ifc-js 📅

A lightweight JavaScript library for converting dates between the normal Gregorian calendar and the International Fixed Calendar (IFC).


What is the International Fixed Calendar? 🗓️

Imagine knowing the day of the week for any date without checking. The first of every month is always a Sunday. The last is always a Saturday. Every month is exactly 4 weeks. No uneven lengths. No drifting holidays.

    ... June → ☀️ Sol → July ...

And there is an extra month of summer right in the middle.

The Gregorian calendar has months of different lengths so every month starts on a different weekday and a month is "about 30 days". The IFC fixes this with 13 months of exactly 28 days each.

Bonus Days 🎁

The IFC has two special days called intercalary days. Intercalary means inserted between — these days exist outside the normal week structure. They have no weekday name and do not belong to any week.

  • 🎆 Year Day (Dec 29) — the last day of every year. It sits after December 28th, outside the week, before the new year begins. Think of it as New Years Eve given its own special status outside the normal calendar.

  • ☀️ Leap Day (Jun 29) — appears only in leap years, after June 28th. Like Year Day it has no weekday. It is a midsummer holiday that shows up once every four years, completely outside the flow of the week.


Live Demos 🚀

Both demos are built entirely on this package via CDN. View source to see the reference implementation.

🕐 IFC Desk Clock

Open Desk Clock →

Keep it open on a spare monitor or tablet. Glancing at both dates together is how the IFC date starts to feel real rather than abstract. The same way setting a watch to military time gradually builds the mental mapping until it becomes second nature.

📅 IFC Calendars

Open Calendars →

An interactive dual calendar. Find any date on either side and the equivalent date in the other calendar is shown instantly. Browse by month and year independently on each side.

📱 Kiosk Mode

Add ?kiosk=true to either URL to hide the navigation bar for a cleaner display experience:

https://gooddadmike.github.io/ifc-js/desk-clock.html?kiosk=true
https://gooddadmike.github.io/ifc-js/calendars.html?kiosk=true

On iOS, tap the share button in Safari and choose Add to Home Screen to pin it as a full-screen app icon. Combined with kiosk mode it makes a clean desk clock or calendar reference with no browser chrome.


How the Math Works 🧮

To get the day of year for any Gregorian date, add up the days in each month before it then add the day of the month. March 22nd for example: January has 31 days, February has 28 days in a normal year, so 31 + 28 + 22 = day 81.

Now divide by 28. Each IFC month is exactly 28 days so this tells you which month you are in. Day 81 divided by 28 is 2 remainder 25 — IFC month 3 (March), day 25. That is how March 22nd Gregorian becomes IFC March 25th. A 1 day adjustment has to be made after Leap Day.


Install 📦

npm install @gooddadmike/ifc-js

For the CLI:

npm install -g @gooddadmike/ifc-js

CLI 💻

# Today's date in IFC
ifc

# Gregorian to IFC
ifc 2024-06-17

# IFC to Gregorian
ifc IFC:2024-06-29

Output:

IFC:2026-03-25
IFC:2024-06-29
2024-06-17

API 📖

toIFC(date?)

Turn any Gregorian date into an IFC date object. Pass an ISO string or nothing at all — no argument means today.

const { toIFC } = require('@gooddadmike/ifc-js');

toIFC('2026-03-22');
// {
//   year: 2026,
//   month: 3,      // 1-based: 1=January, 7=Sol, 13=December
//   day: 25,
//   weekday: 4,    // 0=Sun, 1=Mon ... 6=Sat, null for intercalary days
//   isLeapDay: false,
//   isYearDay: false
// }

toIFC('2024-06-17');
// { year: 2024, month: 6, day: 29, weekday: null, isLeapDay: true,  isYearDay: false }

toIFC('2026-12-31');
// { year: 2026, month: 13, day: 29, weekday: null, isLeapDay: false, isYearDay: true  }

// No argument uses today
toIFC();

toGregorian(input)

Turn an IFC date back into a Gregorian ISO string. Pass a string, the result of toIFC(), or build the object yourself.

const { toGregorian } = require('@gooddadmike/ifc-js');

// From an IFC date string
toGregorian('IFC:2024-06-29');  // '2024-06-17'  (Leap Day)
toGregorian('IFC:2026-07-01');  // '2026-06-18'  (Sol 1)
toGregorian('IFC:2026-13-29');  // '2026-12-31'  (Year Day)

// Pass the result of toIFC() directly
const ifc = toIFC('2024-06-17');
toGregorian(ifc);               // '2024-06-17'

// Or build an IFC date object by hand
toGregorian({ year: 2026, month: 7, day: 1 });  // '2026-06-18'  (Sol 1)

The IFC: prefix is required when passing a string. Without it the parser assumes Gregorian. The same numeric string means different things in each calendar:

2024-07-15       -> Gregorian July 15
IFC:2024-07-15   -> IFC Sol 15 (Gregorian July 2nd)

IFC month numbers are 1-based and go up to 13:

| Number | Month | |--------|---------| | 1 - 6 | Jan-Jun | | 7 | Sol ☀️ | | 8 - 13 | Jul-Dec |


isLeap(year)

Quick check — is this year a leap year? ✅

const { isLeap } = require('@gooddadmike/ifc-js');

isLeap(2024);  // true
isLeap(2026);  // false
isLeap(1900);  // false  (divisible by 100 but not 400)
isLeap(2000);  // true   (divisible by 400)

ES Modules

Drop the require and use import instead.

import { toIFC, toGregorian, isLeap } from '@gooddadmike/ifc-js';

TypeScript Shape

Not a TypeScript package but here is the shape of an IFC date object for reference — useful if you are writing .d.ts types or just want to understand what toIFC() returns.

type IFCDate = {
  year:      number
  month:     number        // 1-based: 1=January, 7=Sol, 13=December
  day:       number        // 1-28 for normal days, 29 for intercalary days
  weekday:   number | null // 0=Sun ... 6=Sat, null for Leap Day / Year Day
  isLeapDay: boolean
  isYearDay: boolean
}

Timezones 🌍

toIFC() with no argument uses the local system time. To use a specific timezone, pass an ISO string calculated in that zone:

const iso = new Intl.DateTimeFormat('en-CA', {
  timeZone: 'UTC'
}).format(new Date());

toIFC(iso);

Replace 'UTC' with any IANA timezone string such as 'America/New_York', 'Europe/London', or 'Pacific/Auckland'.


Implementations 🔧


Go Deeper 🐇

Curious about date and time handling in general? These are worth knowing about:

  • date-fns — modern JavaScript date utility library, functional and tree-shakeable
  • Temporal — the upcoming JavaScript standard for date and time, fixing everything Date got wrong
  • Luxon — powerful and friendly date/time library with full timezone support
  • day.js — tiny 2kb date library with a familiar API

The white rabbit goes as deep as you want. 🐇


A Note on How This Was Built 🤖

The ideation, code, and tests for this package were written lovingly alongside Claude.ai. Not generated and pasted — actually discussed, debugged, argued over, and refined through conversation. The bugs were real, the fixes were earned, and the documentation went through more drafts than anyone should admit.


Contributing 🤝

See CONTRIBUTING.md for guidelines.


Credits 🙏


License

MIT