Simple Timekeeping

Simple Timekeeping

Free
Version: V13
FVTT: V13
Any System
Download
Changelog

    A simple and unobtrusive way to keep track of time. Simple Timekeeping docks on top of the screen to always have a reminder of essential date, time and weather information you can change with a click. Syncs with the core Foundry calendar API.

    If you are looking for premade calendars, click Here

    Introduction

    Simple Timekeeping is a lightweight module designed to help Game Masters manage time, weather, and events in their campaigns. It offers an intuitive interface with minimal setup while providing a rich set of features to enhance immersion and storytelling. The module is designed with a philosophy of "simple yet powerful" - offering complex functionality without a steep learning curve. It works with any game system and can be used alongside other Foundry modules.

    Interface Overview

    The Simple Timekeeping interface consists of several components:

    Top Bar Controls

    • Time Display: Shows the current day and time
    • Navigation Controls: Buttons to move backward/forward in time
    • Preset Time Buttons: Quick access to sunrise, sunset, midday, midnight
    • Weather Display: Shows current weather condition
    • Settings Button: Access to module configuration

    Event Panel

    • Event List: Displays upcoming and past events
    • Search Bar: Filter events by name
    • Create Event Button: Add new events to the timeline

    Configuration Panel

    • Tabs: Navigate between different configuration sections
    • Settings: Customize module behavior
    • Save Button: Apply configuration changes

    Configuration

    Time Management

    Manual Time Control

    The interface provides several ways to adjust the game time:

    • Hour Back/Forward: Move time backward/forward by one hour
    • Day Back/Forward: Move time backward/forward by one day
    • Preset Times: Jump to specific times of day:
      • Sunrise: Beginning of daylight
      • Midday: Peak daylight
      • Sunset: Beginning of darkness
      • Midnight: Peak darkness

    Combat Integration

    The module automatically tracks time during combat:

    • Each combat round advances time by the configured "Seconds per Round" value

    Real-time Progression

    You can enable automatic time progression:

    • Game time advances based on "Seconds per Real Second" setting
    • For example, setting this to 60 would mean 1 minute of game time passes every real second

    Weather Badge

    Simple Timekeeping includes some weather presets for you that also set the matching (or closest) weather effect on the current scene. Click on the weather badge to chose from presets or set something custom in the configuration menu.

    Event Management

    Events in Simple Timekeeping allow you to track important campaign moments and schedule future occurrences.

    Creating Events

    1. Click the "Create Event" button
    2. Fill in the event details:
      • Event Name: Brief descriptive title
      • Event Start: Date and time when event begins
      • Event End: (Optional) Date and time when event ends
      • Repeat: Frequency of recurrence (None, Daily, Weekly, Monthly, Yearly)

    Managing Events

    • Search: Filter events by name using the search bar
    • Edit: Right Click on an event to access it's context menu

    Event Display

    Events are displayed in the event list, ordered by date. Current and upcoming events are highlighted for easy reference.

    Badge System

    Badges provide visual indicators for tracking various campaign elements.

    Custom Badge Configuration

    You can configure up to four custom badges:

    1. Navigate to module settings
    2. Under "Custom Badge 1-4":
      • Set the label text
      • Choose a color (hex code)

    Badge Usage Examples

    • Moon Phases: Track lunar cycles
    • Seasons: Indicate current season
    • Campaign Day: Track days since campaign start
    • Faction Status: Monitor allegiances
    • Holiday: Mark special dates

    Scene Integration

    Darkness Synchronization

    The module can automatically adjust scene darkness based on time of day.

    Troubleshooting

    Module Not Visible

    • The module is not visible during combat. Make sure you don't have an ongoing combat.

    API

    All methods can be accessed from ui.simpleTimekeeping

    Badge Management APIs

    These functions provide programmatic control over the visual badge elements in the SimpleTimekeeping interface, allowing developers to dynamically update weather and moon phase displays.

    setWeatherBadge(label, color, weatherEffect)

    Updates the weather badge display and optionally applies weather effects to the current scene.

    Parameters:

    • label (string) - The text to display on the weather badge. Will be localized using the module's localization system
    • color (string) - CSS color value for the badge background (hex, rgb, named colors, etc.)
    • weatherEffect (string, optional) - Weather effect to apply to the scene. Pass "none" to clear existing effects

    Behavior:

    • Saves the weather label and color to persistent module settings
    • If weatherEffect is provided, updates the current scene's weather property
    • Passing "none" as weatherEffect will clear any existing weather effects by setting an empty string
    • The badge visibility is controlled by whether a label is set - empty labels hide the badge

    Usage Examples:

    // Set a storm weather badge with scene effects
    await ui.simpleTimekeeping.setWeatherBadge("Heavy Rain", "#4a90e2", "rain");
     
    // Update just the visual badge without scene effects
    await ui.simpleTimekeeping.setWeatherBadge("Partly Cloudy", "#87ceeb");
     
    // Clear weather effects but keep the badge
    await ui.simpleTimekeeping.setWeatherBadge("Clear Skies", "#87ceeb", "none");

    setMoonBadge(label, color)

    Updates the moon phase badge display with custom text and styling.

    Parameters:

    • label (string) - The text to display on the moon badge. Will be localized using the module's localization system
    • color (string, optional) - CSS color value for the badge background. If not provided, retains the current color setting

    Behavior:

    • Saves the moon label and optionally the color to persistent module settings
    • If color is omitted or null, the existing color configuration is preserved
    • The badge visibility is controlled by whether a label is set - empty labels hide the badge
    • Will not work if the automatic moon phase calculation system is enabled

    Usage Examples:

    // Set a custom moon phase with new color
    await ui.simpleTimekeeping.setMoonBadge("Waning Crescent", "#c0c0c0");
     
    // Update only the text, keeping existing color
    await ui.simpleTimekeeping.setMoonBadge("Full Moon");
     
    // Clear the moon badge
    await ui.simpleTimekeeping.setMoonBadge("");

    Custom Climate Data

    If you wish you could customize the weather generation starting from this sample template. No support is provided for custom climate data. default is used whenever a matching season or climate is not found.

    {
      "tropical": {
        "temperature": {
          "default": {
            "min": 24,
            "max": 35
          }
        },
        "weather": {
          "default": {
            "clear": 8,
            "partlyCloudy": 5,
            "rain": 7,
            "thunderstorm": 3,
            "fog": 2,
            "sunshower": 1
          }
        }
      },
      "subtropical": {
        "temperature": {
          "summer": {
            "min": 15,
            "max": 32
          },
          "winter": {
            "min": 5,
            "max": 17
          },
          "default": {
            "min": 10,
            "max": 25
          }
        },
        "weather": {
          "summer": {
            "clear": 5,
            "partlyCloudy": 4,
            "rain": 5,
            "drizzle": 2,
            "sunshower": 1
          },
          "winter": {
            "clear": 2,
            "cloudy": 4,
            "rain": 3,
            "mist": 2,
            "fog": 1
          },
          "default": {
            "clear": 4,
            "partlyCloudy": 5,
            "cloudy": 3,
            "rain": 2
          }
        }
      },
      "temperate": {
        "temperature": {
          "summer": {
            "min": 18,
            "max": 30
          },
          "winter": {
            "min": -5,
            "max": 5
          },
          "default": {
            "min": 8,
            "max": 20
          }
        },
        "weather": {
          "summer": {
            "clear": 6,
            "partlyCloudy": 4,
            "thunderstorm": 2
          },
          "winter": {
            "snow": 5,
            "blizzard": 3,
            "fog": 2
          },
          "default": {
            "rain": 3,
            "cloudy": 3,
            "mist": 2,
            "drizzle": 2
          }
        }
      },
      "polar": {
        "temperature": {
          "winter": {
            "min": -40,
            "max": -10
          },
          "default": {
            "min": -5,
            "max": 5
          }
        },
        "weather": {
          "winter": {
            "blizzard": 6,
            "snow": 5
          },
          "default": {
            "clear": 4,
            "partlyCloudy": 3,
            "windy": 2,
            "mist": 1
          }
        }
      }
    }

    You don't need the whole table if you are just using one latitude \ biome. Simply have a default table.

    {
      "default": {
        "temperature": {
          "summer": {
            "min": 18,
            "max": 30
          },
          "winter": {
            "min": -5,
            "max": 5
          },
          "default": {
            "min": 8,
            "max": 20
          }
        },
        "weather": {
          "summer": {
            "clear": 6,
            "partlyCloudy": 4,
            "thunderstorm": 2
          },
          "winter": {
            "snow": 5,
            "blizzard": 3,
            "fog": 2
          },
          "default": {
            "rain": 3,
            "cloudy": 3,
            "mist": 2,
            "drizzle": 2
          }
        }
      }
    }

    AI Calendar Generator

    If you wish, you can use this AI Foundry calendar generator created by @Phenomen here (opens in a new tab).

    Custom Calendar

    Simple Timekeeping utilizes the core Foundry API for the calendar, if you want to have specifics beyond the examples below, visit the FVTT API Reference (opens in a new tab)

    Custom Simple Timekeeping values

    Simple Timekeeping will read some additional values from the configuration. You can check the Harptos configuration for the most complete example.

    Dusk\Dawn

    Months support dusk and dawn properties, ranging from 0 to 1, where in a 24hrs day 0.25 is 06:00, 0.5 is 12:00 and 1 is 24:00. Scale it accordingly for non-24hrs calendars.

          { "name": "Hammer", "abbreviation": "Ham", "ordinal": 1, "days": 31, "dawn": 0.33, "dusk": 0.69 }

    Moons

    The moons key can hold data regarding moons (or planets) and will be used to dynamically update the moon badge. Phase names must be in order starting from new moon. The moon cycle is fixed and starts at time 0, if you need to offset it, use the offset property. Both cycle and offset are in days.

      "moons": {
        "values": [
          {
            "name": "Selûne",
            "cycleLength": 30,
            "phaseNames": [
              "New Moon",
              "Waxing Crescent",
              "First Quarter",
              "Waxing Gibbous",
              "Full Moon",
              "Waning Gibbous",
              "Last Quarter",
              "Waning Crescent"
            ],
            "offset": 0
          }
        ]
      }

    Sample Calendars

    You can simply copy and paste these sample calendars in the Calendar Configuration. When making your own calendar, note that properties not present in these examples are not supported (such as intercalary days).

    Harptos (Forgotten Realms)

    {
        "name": "Harptos (Forgotten Realms)",
        "id": "harptos",
        "description": "The standard calendar of the Forgotten Realms, consisting of twelve 30-day months punctuated by five annual festival days.",
        "years": {
            "yearZero": 0,
            "firstWeekday": 0,
            "leapYear": {
                "leapStart": 4,
                "leapInterval": 4
            }
        },
        "months": {
            "values": [
                {
                    "name": "Hammer",
                    "abbreviation": "Ham",
                    "ordinal": 1,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Midwinter",
                    "abbreviation": "Mid",
                    "ordinal": 1,
                    "days": 1,
                    "startingWeekday": 0,
                    "intercalary": true
                },
                {
                    "name": "Alturiak",
                    "abbreviation": "Alt",
                    "ordinal": 2,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Ches",
                    "abbreviation": "Che",
                    "ordinal": 3,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Tarsakh",
                    "abbreviation": "Tar",
                    "ordinal": 4,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Greengrass",
                    "abbreviation": "Gre",
                    "ordinal": 4,
                    "days": 1,
                    "intercalary": true,
                    "startingWeekday": 0
                },
                {
                    "name": "Mirtul",
                    "abbreviation": "Mir",
                    "ordinal": 5,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Kythorn",
                    "abbreviation": "Kyt",
                    "ordinal": 6,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Flamerule",
                    "abbreviation": "Fla",
                    "ordinal": 7,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Midsummer",
                    "abbreviation": "Mid",
                    "ordinal": 7,
                    "days": 1,
                    "intercalary": true,
                    "startingWeekday": 0
                },
                {
                    "name": "Shieldmeet",
                    "abbreviation": "Shi",
                    "ordinal": 7,
                    "days": 0,
                    "leapDays": 1,
                    "intercalary": true,
                    "startingWeekday": 0
                },
                {
                    "name": "Eleasis",
                    "abbreviation": "Ele",
                    "ordinal": 8,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Eleint",
                    "abbreviation": "El",
                    "ordinal": 9,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Highharvestide",
                    "abbreviation": "Hig",
                    "ordinal": 9,
                    "days": 1,
                    "intercalary": true,
                    "startingWeekday": 0
                },
                {
                    "name": "Marpenoth",
                    "abbreviation": "Mar",
                    "ordinal": 10,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Uktar",
                    "abbreviation": "Ukt",
                    "ordinal": 11,
                    "days": 30,
                    "startingWeekday": 0
                },
                {
                    "name": "Feast of the Moon",
                    "abbreviation": "Fes",
                    "ordinal": 11,
                    "days": 1,
                    "intercalary": true,
                    "startingWeekday": 0
                },
                {
                    "name": "Nightal",
                    "abbreviation": "Nig",
                    "ordinal": 12,
                    "days": 30,
                    "startingWeekday": 0
                }
            ]
        },
        "days": {
            "values": [
                {
                    "name": "First-day",
                    "abbreviation": "1D",
                    "ordinal": 1
                },
                {
                    "name": "Second-day",
                    "abbreviation": "2D",
                    "ordinal": 2
                },
                {
                    "name": "Third-day",
                    "abbreviation": "3D",
                    "ordinal": 3
                },
                {
                    "name": "Fourth-day",
                    "abbreviation": "4D",
                    "ordinal": 4
                },
                {
                    "name": "Fifth-day",
                    "abbreviation": "5D",
                    "ordinal": 5
                },
                {
                    "name": "Sixth-day",
                    "abbreviation": "6D",
                    "ordinal": 6
                },
                {
                    "name": "Seventh-day",
                    "abbreviation": "7D",
                    "ordinal": 7,
                    "isRestDay": true
                }
            ],
            "daysPerYear": 366,
            "hoursPerDay": 24,
            "minutesPerHour": 60,
            "secondsPerMinute": 60
        },
        "seasons": {
            "values": [
                {
                    "name": "Spring",
                    "monthStart": 3,
                    "monthEnd": 6,
                    "dayStart": 19,
                    "dayEnd": 19
                },
                {
                    "name": "Summer",
                    "monthStart": 6,
                    "monthEnd": 9,
                    "dayStart": 20,
                    "dayEnd": 20
                },
                {
                    "name": "Autumn",
                    "monthStart": 9,
                    "monthEnd": 12,
                    "dayStart": 21,
                    "dayEnd": 19
                },
                {
                    "name": "Winter",
                    "monthStart": 12,
                    "monthEnd": 3,
                    "dayStart": 20,
                    "dayEnd": 18
                }
            ]
        },
        "moons": {
            "values": [
                {
                    "name": "Selûne",
                    "cycleLength": 30,
                    "phaseNames": [
                        "New Moon",
                        "Waxing Crescent",
                        "First Quarter",
                        "Waxing Gibbous",
                        "Full Moon",
                        "Waning Gibbous",
                        "Last Quarter",
                        "Waning Crescent"
                    ],
                    "offset": 0
                }
            ]
        }
    }

    Galifar (Eberron)

    {
      "name": "Galifar",
      "description": "The calendar used in Eberron, featuring 12 months of 28 days and a consistent 7-day week with no leap years or intercalary days.",
      "years": {
        "yearZero": 0,
        "firstWeekday": 0
      },
      "months": {
        "values": [
          { "name": "Zarantyr", "abbreviation": "Zar", "ordinal": 1, "days": 28 },
          { "name": "Olarune", "abbreviation": "Ola", "ordinal": 2, "days": 28 },
          { "name": "Therendor", "abbreviation": "The", "ordinal": 3, "days": 28 },
          { "name": "Eyre", "abbreviation": "Eyr", "ordinal": 4, "days": 28 },
          { "name": "Dravago", "abbreviation": "Dra", "ordinal": 5, "days": 28 },
          { "name": "Nymm", "abbreviation": "Nym", "ordinal": 6, "days": 28 },
          { "name": "Lharvion", "abbreviation": "Lha", "ordinal": 7, "days": 28 },
          { "name": "Barrakas", "abbreviation": "Bar", "ordinal": 8, "days": 28 },
          { "name": "Rhaan", "abbreviation": "Rha", "ordinal": 9, "days": 28 },
          { "name": "Sypheros", "abbreviation": "Syp", "ordinal": 10, "days": 28 },
          { "name": "Aryth", "abbreviation": "Ary", "ordinal": 11, "days": 28 },
          { "name": "Vult", "abbreviation": "Vul", "ordinal": 12, "days": 28 }
        ]
      },
      "days": {
        "values": [
          { "name": "Sul", "abbreviation": "Sul", "ordinal": 1 },
          { "name": "Mol", "abbreviation": "Mol", "ordinal": 2 },
          { "name": "Zol", "abbreviation": "Zol", "ordinal": 3 },
          { "name": "Wir", "abbreviation": "Wir", "ordinal": 4 },
          { "name": "Zor", "abbreviation": "Zor", "ordinal": 5 },
          { "name": "Far", "abbreviation": "Far", "ordinal": 6 },
          { "name": "Sar", "abbreviation": "Sar", "ordinal": 7, "isRestDay": true }
        ],
        "daysPerYear": 336,
        "hoursPerDay": 24,
        "minutesPerHour": 60,
        "secondsPerMinute": 60
      },
      "seasons": {
        "values": [
          { "name": "Spring", "monthStart": 3, "monthEnd": 5 },
          { "name": "Summer", "monthStart": 6, "monthEnd": 8 },
          { "name": "Autumn", "monthStart": 9, "monthEnd": 11 },
          { "name": "Winter", "monthStart": 12, "monthEnd": 2 }
        ]
      }
    }

    Golarion (Absalom Reckoning)

    {
      "name": "Golarion",
      "description": "The Absalom Reckoning calendar used in the Pathfinder setting, featuring 12 months with varying lengths and a 7-day week.",
      "years": {
        "yearZero": 1,
        "firstWeekday": 0,
        "leapYear": {
          "leapStart": 4,
          "leapInterval": 4
        }
      },
      "months": {
        "values": [
          { "name": "Abadius", "abbreviation": "Abad", "ordinal": 1, "days": 31 },
          { "name": "Calistril", "abbreviation": "Cal", "ordinal": 2, "days": 28, "leapDays": 29 },
          { "name": "Pharast", "abbreviation": "Phar", "ordinal": 3, "days": 31 },
          { "name": "Gozran", "abbreviation": "Goz", "ordinal": 4, "days": 30 },
          { "name": "Desnus", "abbreviation": "Des", "ordinal": 5, "days": 31 },
          { "name": "Sarenith", "abbreviation": "Sar", "ordinal": 6, "days": 30 },
          { "name": "Erastus", "abbreviation": "Era", "ordinal": 7, "days": 31 },
          { "name": "Arodus", "abbreviation": "Aro", "ordinal": 8, "days": 31 },
          { "name": "Rova", "abbreviation": "Rov", "ordinal": 9, "days": 30 },
          { "name": "Lamashan", "abbreviation": "Lam", "ordinal": 10, "days": 31 },
          { "name": "Neth", "abbreviation": "Neth", "ordinal": 11, "days": 30 },
          { "name": "Kuthona", "abbreviation": "Kuth", "ordinal": 12, "days": 31 }
        ]
      },
      "days": {
        "values": [
          { "name": "Moonday", "abbreviation": "Mon", "ordinal": 1 },
          { "name": "Toilday", "abbreviation": "Tue", "ordinal": 2 },
          { "name": "Wealday", "abbreviation": "Wed", "ordinal": 3 },
          { "name": "Oathday", "abbreviation": "Thu", "ordinal": 4 },
          { "name": "Fireday", "abbreviation": "Fri", "ordinal": 5 },
          { "name": "Starday", "abbreviation": "Sat", "ordinal": 6 },
          { "name": "Sunday", "abbreviation": "Sun", "ordinal": 7, "isRestDay": true }
        ],
        "daysPerYear": 365,
        "hoursPerDay": 24,
        "minutesPerHour": 60,
        "secondsPerMinute": 60
      },
      "seasons": {
        "values": [
          { "name": "Winter", "monthStart": 1, "monthEnd": 2 },
          { "name": "Spring", "monthStart": 3, "monthEnd": 5 },
          { "name": "Summer", "monthStart": 6, "monthEnd": 8 },
          { "name": "Autumn", "monthStart": 9, "monthEnd": 11 }
        ]
      }
    }

    Mystara (Thyatian Calendar)

    {
      "name": "Mystara",
      "description": "The Thyatian calendar used in the Mystara setting, closely resembling the Gregorian calendar with 12 months and a 7-day week.",
      "years": {
        "yearZero": 0,
        "firstWeekday": 0,
        "leapYear": {
          "leapStart": 4,
          "leapInterval": 4
        }
      },
      "months": {
        "values": [
          { "name": "Nuwmont", "abbreviation": "Nuw", "ordinal": 1, "days": 31 },
          { "name": "Vatermont", "abbreviation": "Vat", "ordinal": 2, "days": 28, "leapDays": 29 },
          { "name": "Thaumont", "abbreviation": "Thau", "ordinal": 3, "days": 31 },
          { "name": "Flaurmont", "abbreviation": "Flau", "ordinal": 4, "days": 30 },
          { "name": "Yarthmont", "abbreviation": "Yar", "ordinal": 5, "days": 31 },
          { "name": "Klarmont", "abbreviation": "Klar", "ordinal": 6, "days": 30 },
          { "name": "Felmont", "abbreviation": "Fel", "ordinal": 7, "days": 31 },
          { "name": "Fyrmont", "abbreviation": "Fyr", "ordinal": 8, "days": 31 },
          { "name": "Ambyrmont", "abbreviation": "Amb", "ordinal": 9, "days": 30 },
          { "name": "Sviftmont", "abbreviation": "Svi", "ordinal": 10, "days": 31 },
          { "name": "Eirmont", "abbreviation": "Eir", "ordinal": 11, "days": 30 },
          { "name": "Kaldmont", "abbreviation": "Kal", "ordinal": 12, "days": 31 }
        ]
      },
      "days": {
        "values": [
          { "name": "Soladain", "abbreviation": "Sol", "ordinal": 1 },
          { "name": "Lunadain", "abbreviation": "Lun", "ordinal": 2 },
          { "name": "Gromdain", "abbreviation": "Gro", "ordinal": 3 },
          { "name": "Tserdain", "abbreviation": "Tse", "ordinal": 4 },
          { "name": "Moldain", "abbreviation": "Mol", "ordinal": 5 },
          { "name": "Nytdain", "abbreviation": "Nyt", "ordinal": 6 },
          { "name": "Loshdain", "abbreviation": "Los", "ordinal": 7, "isRestDay": true }
        ],
        "daysPerYear": 365,
        "hoursPerDay": 24,
        "minutesPerHour": 60,
        "secondsPerMinute": 60
      },
      "seasons": {
        "values": [
          { "name": "Winter", "monthStart": 1, "monthEnd": 2 },
          { "name": "Spring", "monthStart": 3, "monthEnd": 5 },
          { "name": "Summer", "monthStart": 6, "monthEnd": 8 },
          { "name": "Autumn", "monthStart": 9, "monthEnd": 11 }
        ]
      }
    }

    Greyhawk (Common Year)

    {
      "name": "Greyhawk",
      "description": "The Common Year calendar used in the World of Greyhawk setting, featuring 12 months of 28 days and four 7-day festivals.",
      "years": {
        "yearZero": 0,
        "firstWeekday": 0
      },
      "months": {
        "values": [
          { "name": "Fireseek", "abbreviation": "Fir", "ordinal": 1, "days": 28 },
          { "name": "Readying", "abbreviation": "Rea", "ordinal": 2, "days": 28 },
          { "name": "Coldeven", "abbreviation": "Col", "ordinal": 3, "days": 28 },
          { "name": "Planting", "abbreviation": "Pla", "ordinal": 4, "days": 28 },
          { "name": "Flocktime", "abbreviation": "Flo", "ordinal": 5, "days": 28 },
          { "name": "Wealsun", "abbreviation": "Wea", "ordinal": 6, "days": 28 },
          { "name": "Reaping", "abbreviation": "Rea", "ordinal": 7, "days": 28 },
          { "name": "Goodmonth", "abbreviation": "Goo", "ordinal": 8, "days": 28 },
          { "name": "Harvester", "abbreviation": "Har", "ordinal": 9, "days": 28 },
          { "name": "Patchwall", "abbreviation": "Pat", "ordinal": 10, "days": 28 },
          { "name": "Ready'reat", "abbreviation": "Rea", "ordinal": 11, "days": 28 },
          { "name": "Sunsebb", "abbreviation": "Sun", "ordinal": 12, "days": 28 }
        ]
      },
      "days": {
        "values": [
          { "name": "Starday", "abbreviation": "Sta", "ordinal": 1 },
          { "name": "Sunday", "abbreviation": "Sun", "ordinal": 2 },
          { "name": "Moonday", "abbreviation": "Mon", "ordinal": 3 },
          { "name": "Godsday", "abbreviation": "God", "ordinal": 4 },
          { "name": "Waterday", "abbreviation": "Wat", "ordinal": 5 },
          { "name": "Earthday", "abbreviation": "Ear", "ordinal": 6 },
          { "name": "Freeday", "abbreviation": "Fre", "ordinal": 7, "isRestDay": true }
        ],
        "daysPerYear": 364,
        "hoursPerDay": 24,
        "minutesPerHour": 60,
        "secondsPerMinute": 60
      },
      "seasons": {
        "values": [
          { "name": "Spring", "monthStart": 3, "monthEnd": 5 },
          { "name": "Summer", "monthStart": 6, "monthEnd": 8 },
          { "name": "Autumn", "monthStart": 9, "monthEnd": 11 }
          { "name": "Winter", "monthStart": 12, "monthEnd": 2 },
        ]
      }
    }

    Dark Sun (Athasian Calendar)

    {
      "name": "Athas",
      "description": "The Athasian calendar used in the Dark Sun setting. It has 10 months of 36 days each, with 5 festival days.",
      "years": {
        "yearZero": 0,
        "firstWeekday": 0
      },
      "months": {
        "values": [
          { "name": "Sorrow", "abbreviation": "Sor", "ordinal": 1, "days": 36 },
          { "name": "Sunbirth", "abbreviation": "Sun", "ordinal": 2, "days": 36 },
          { "name": "Ral's Rest", "abbreviation": "Ral", "ordinal": 3, "days": 36 },
          { "name": "Windfury", "abbreviation": "Win", "ordinal": 4, "days": 36 },
          { "name": "Sea's Fury", "abbreviation": "Sea", "ordinal": 5, "days": 36 },
          { "name": "Sun Descending", "abbreviation": "Des", "ordinal": 6, "days": 36 },
          { "name": "Fireseek", "abbreviation": "Fir", "ordinal": 7, "days": 36 },
          { "name": "Dragon's Rest", "abbreviation": "Dra", "ordinal": 8, "days": 36 },
          { "name": "Smoldering", "abbreviation": "Smo", "ordinal": 9, "days": 36 },
          { "name": "Cooling", "abbreviation": "Coo", "ordinal": 10, "days": 36 }
        ]
      },
      "days": {
        "values": [
          { "name": "Firstday", "abbreviation": "F1", "ordinal": 1 },
          { "name": "Secondday", "abbreviation": "F2", "ordinal": 2 },
          { "name": "Thirdday", "abbreviation": "F3", "ordinal": 3 },
          { "name": "Fourthday", "abbreviation": "F4", "ordinal": 4 },
          { "name": "Fifthday", "abbreviation": "F5", "ordinal": 5 },
          { "name": "Sixthday", "abbreviation": "F6", "ordinal": 6 }
        ],
        "daysPerYear": 365,
        "hoursPerDay": 24,
        "minutesPerHour": 60,
        "secondsPerMinute": 60
      }
    }

    Dragonlance Calendar (Ansalon)

    {
      "name": "Dragonlance (Ansalon)",
      "description": "The standard calendar used across Ansalon, with 12 months named after gods and constellations.",
      "years": {
        "yearZero": 0,
        "firstWeekday": 0
      },
      "months": {
        "values": [
          { "name": "Brookgreen", "abbreviation": "Brookgr.", "ordinal": 1, "days": 30 },
          { "name": "Fleurgreen", "abbreviation": "Fleurg.", "ordinal": 2, "days": 30 },
          { "name": "Brookmonth", "abbreviation": "Brookm.", "ordinal": 3, "days": 30 },
          { "name": "Planting", "abbreviation": "Plant.", "ordinal": 4, "days": 30 },
          { "name": "Goldmonth", "abbreviation": "Goldm.", "ordinal": 5, "days": 30 },
          { "name": "Reapember", "abbreviation": "Reapem.", "ordinal": 6, "days": 30 },
          { "name": "Hiddumont", "abbreviation": "Hiddum.", "ordinal": 7, "days": 30 },
          { "name": "Reapgreen", "abbreviation": "Reapgr.", "ordinal": 8, "days": 30 },
          { "name": "Chislmont", "abbreviation": "Chislm.", "ordinal": 9, "days": 30 },
          { "name": "Darkember", "abbreviation": "Darkem.", "ordinal": 10, "days": 30 },
          { "name": "Frostkolt", "abbreviation": "Frostk.", "ordinal": 11, "days": 30 },
          { "name": "Deepkolt", "abbreviation": "Deepk.", "ordinal": 12, "days": 30 }
        ]
      },
      "days": {
        "values": [
          { "name": "Firstday", "abbreviation": "1st", "ordinal": 1 },
          { "name": "Secondday", "abbreviation": "2nd", "ordinal": 2 },
          { "name": "Thirdday", "abbreviation": "3rd", "ordinal": 3 },
          { "name": "Fourthday", "abbreviation": "4th", "ordinal": 4 },
          { "name": "Fifthday", "abbreviation": "5th", "ordinal": 5 },
          { "name": "Sixthday", "abbreviation": "6th", "ordinal": 6 },
          { "name": "Seventhday", "abbreviation": "7th", "ordinal": 7 }
        ],
        "daysPerYear": 360,
        "hoursPerDay": 24,
        "minutesPerHour": 60,
        "secondsPerMinute": 60
      }
    }

    Birthright Calendar (Cerilian Reckoning)

    {
      "name": "Birthright (Cerilian Reckoning)",
      "description": "The calendar of Cerilia, used in the Birthright setting. 12 months, 30 days each, plus festivals.",
      "years": {
        "yearZero": 0,
        "firstWeekday": 0
      },
      "months": {
        "values": [
          { "name": "Roelir", "abbreviation": "Roel.", "ordinal": 1, "days": 30 },
          { "name": "Haelynir", "abbreviation": "Hael.", "ordinal": 2, "days": 30 },
          { "name": "Anarire", "abbreviation": "Anar.", "ordinal": 3, "days": 30 },
          { "name": "Talienir", "abbreviation": "Tali.", "ordinal": 4, "days": 30 },
          { "name": "Roele", "abbreviation": "Roele", "ordinal": 5, "days": 30 },
          { "name": "Deismir", "abbreviation": "Deis.", "ordinal": 6, "days": 30 },
          { "name": "Erntenir", "abbreviation": "Ernt.", "ordinal": 7, "days": 30 },
          { "name": "Sehnir", "abbreviation": "Sehn.", "ordinal": 8, "days": 30 },
          { "name": "Emmanir", "abbreviation": "Emma.", "ordinal": 9, "days": 30 },
          { "name": "Keltier", "abbreviation": "Kelt.", "ordinal": 10, "days": 30 },
          { "name": "Krylinir", "abbreviation": "Kryl.", "ordinal": 11, "days": 30 },
          { "name": "Sidhevair", "abbreviation": "Sidh.", "ordinal": 12, "days": 30 }
        ]
      },
      "days": {
        "values": [
          { "name": "Sunday", "abbreviation": "Sun", "ordinal": 1 },
          { "name": "Moonday", "abbreviation": "Moon", "ordinal": 2 },
          { "name": "Earthday", "abbreviation": "Earth", "ordinal": 3 },
          { "name": "Wineday", "abbreviation": "Wine", "ordinal": 4 },
          { "name": "Stormday", "abbreviation": "Storm", "ordinal": 5 },
          { "name": "Kingsday", "abbreviation": "King", "ordinal": 6 },
          { "name": "Starday", "abbreviation": "Star", "ordinal": 7 }
        ],
        "daysPerYear": 360,
        "hoursPerDay": 24,
        "minutesPerHour": 60,
        "secondsPerMinute": 60
      }
    }

    Exandrian Calendar (Critical Role)

    {
      "name": "Calendar of Exandria",
      "description": "A calendar with 328 days over 11 months, used across Exandria. It features a 7-day week and seasonal shifts based on the northern hemisphere.",
      "years": {
        "yearZero": 0,
        "firstWeekday": 0
      },
      "months": {
        "values": [
          { "name": "Horisal", "abbreviation": "Hor", "ordinal": 1, "days": 29 },
          { "name": "Misuthar", "abbreviation": "Mis", "ordinal": 2, "days": 30 },
          { "name": "Dualahei", "abbreviation": "Dua", "ordinal": 3, "days": 30 },
          { "name": "Thunsheer", "abbreviation": "Thu", "ordinal": 4, "days": 31 },
          { "name": "Unndilar", "abbreviation": "Unn", "ordinal": 5, "days": 28 },
          { "name": "Brussendar", "abbreviation": "Bru", "ordinal": 6, "days": 31 },
          { "name": "Sydenstar", "abbreviation": "Syd", "ordinal": 7, "days": 32 },
          { "name": "Fessuran", "abbreviation": "Fes", "ordinal": 8, "days": 29 },
          { "name": "Quen'pillar", "abbreviation": "Que", "ordinal": 9, "days": 27 },
          { "name": "Cuersaar", "abbreviation": "Cue", "ordinal": 10, "days": 29 },
          { "name": "Duscar", "abbreviation": "Dus", "ordinal": 11, "days": 32 }
        ]
      },
      "days": {
        "values": [
          { "name": "Miresen", "abbreviation": "Mir", "ordinal": 1 },
          { "name": "Grissen", "abbreviation": "Gri", "ordinal": 2 },
          { "name": "Whelsen", "abbreviation": "Whe", "ordinal": 3 },
          { "name": "Conthsen", "abbreviation": "Con", "ordinal": 4 },
          { "name": "Folsen", "abbreviation": "Fol", "ordinal": 5 },
          { "name": "Yulisen", "abbreviation": "Yul", "ordinal": 6, "isRestDay": true },
          { "name": "Da'leysen", "abbreviation": "Dal", "ordinal": 7, "isRestDay": true }
        ],
        "daysPerYear": 328,
        "hoursPerDay": 24,
        "minutesPerHour": 60,
        "secondsPerMinute": 60
      },
      "seasons": {
        "values": [
          { "name": "Spring", "monthStart": 3, "monthEnd": 5 },
          { "name": "Summer", "monthStart": 6, "monthEnd": 8 },
          { "name": "Autumn", "monthStart": 9, "monthEnd": 11 },
          { "name": "Winter", "monthStart": 1, "monthEnd": 2 }
        ]
      },
      "moons": {
        "values": [
          {
            "name": "Ruidus",
            "cycleLength": 29,
            "phaseNames": [
              "New Moon",
              "Waxing Crescent",
              "First Quarter",
              "Waxing Gibbous",
              "Full Moon",
              "Waning Gibbous",
              "Last Quarter",
              "Waning Crescent"
            ],
            "offset": 0
          },
          {
            "name": "Catha",
            "cycleLength": 30,
            "phaseNames": [
              "New Moon",
              "Waxing Crescent",
              "First Quarter",
              "Waxing Gibbous",
              "Full Moon",
              "Waning Gibbous",
              "Last Quarter",
              "Waning Crescent"
            ],
            "offset": 15
          }
        ]
    }
    }