Skip to main content
By default, Ramadan CLI uses the Hijri calendar from the Aladhan API to determine when Ramadan begins. However, you can override this with a custom first roza date to match your local community’s moon sighting or personal preference.

Why Use a Custom Date?

Different Islamic communities may begin Ramadan on different dates based on:
  • Local moon sighting: Some communities follow physical moon sightings rather than calculations
  • Different calculation methods: Various Islamic organizations may declare different start dates
  • Geographic variations: Moon visibility varies by location
  • Following specific authorities: Your community may follow a specific Islamic authority’s declaration
The custom first roza date feature lets you align Ramadan CLI with your community’s actual observance while still getting accurate prayer times.

Setting a Custom First Roza Date

Use the --first-roza-date flag with a date in YYYY-MM-DD format:
roza --first-roza-date 2026-03-01
This sets March 1, 2026 as the first day of Ramadan and persists this date to your configuration.

Date Format

The date must be in ISO 8601 format: YYYY-MM-DD
# ✅ Correct
roza --first-roza-date 2026-03-01
roza --first-roza-date 2025-02-28

# ❌ Incorrect
roza --first-roza-date 01-03-2026    # Wrong format
roza --first-roza-date 2026/03/01    # Wrong separator
roza --first-roza-date March 1 2026  # Not ISO format

Validation

The date is validated to ensure it’s a real calendar date:
const parseIsoDate = (value: string): Date | null => {
  const match = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (!match) {
    return null;
  }

  const year = parseInt(match[1], 10);
  const month = parseInt(match[2], 10);
  const day = parseInt(match[3], 10);

  const date = new Date(year, month - 1, day);
  const isValid =
    date.getFullYear() === year &&
    date.getMonth() === month - 1 &&
    date.getDate() === day;

  if (!isValid) {
    return null;
  }

  return date;
};
Invalid dates will show an error:
roza --first-roza-date 2026-02-30
❌ Invalid first roza date. Use YYYY-MM-DD.

How Custom Dates Work

Persistent Storage

Once set, the custom first roza date is saved to your configuration file:
if (opts.firstRozaDate) {
  const parsedExplicit = parseIsoDate(opts.firstRozaDate);
  if (!parsedExplicit) {
    throw new Error('Invalid first roza date. Use YYYY-MM-DD.');
  }
  setStoredFirstRozaDate(opts.firstRozaDate);
  return parsedExplicit;
}
The date is stored in ~/.config/ramadan-cli/config.json (or $RAMADAN_CLI_CONFIG_DIR if set).

Automatic Roza Number Calculation

With a custom first roza date, Ramadan CLI calculates the current roza number based on the number of days since that date:
export const getRozaNumberFromStartDate = (
  firstRozaDate: Date,
  targetDate: Date
): number =>
  Math.floor(
    (toUtcDateOnlyMs(targetDate) - toUtcDateOnlyMs(firstRozaDate)) / DAY_MS
  ) + 1;
Example:
  • First roza date: March 1, 2026
  • Today’s date: March 15, 2026
  • Roza number: 15 (15 days since start)

Calendar Generation

When a custom first roza date is set, the full calendar is generated by fetching prayer times for 30 consecutive days:
const fetchCustomRamadanDays = async (
  query: RamadanQuery,
  firstRozaDate: Date
): Promise<ReadonlyArray<PrayerData>> => {
  const totalDays = 30;
  const days = Array.from({ length: totalDays }, (_, index) =>
    addDays(firstRozaDate, index)
  );
  return Promise.all(
    days.map(async (dayDate) => fetchRamadanDay(query, dayDate))
  );
};
This ensures accurate prayer times for each day, regardless of when Ramadan actually falls in the Hijri calendar.

Using Custom Dates

View Today with Custom Date

# Set the first roza date
roza --first-roza-date 2026-03-01

# View today (uses the custom date)
roza
If today is March 15, 2026:
Today Sehar/Iftar
📍 San Francisco, United States

Roza  Sehar     Iftar     Date            Hijri
------------------------------------------------------
15    5:42 AM   7:23 PM   15-03-2026      15 Ramadan 1447 ← current
The Hijri date shown in the output comes from the API’s calculation, which may differ from your custom Gregorian start date. The Roza number is what’s calculated from your custom date.

View Full Calendar with Custom Date

roza --first-roza-date 2026-03-01 --all
This shows 30 days starting from March 1, 2026:
Ramadan 1447 (All Days)
📍 Lahore, Pakistan

Roza  Sehar     Iftar     Date            Hijri
------------------------------------------------------------------------
1     4:55 AM   6:10 PM   01-03-2026      1 Ramadan 1447 ← next
2     4:55 AM   6:11 PM   02-03-2026      2 Ramadan 1447
3     4:54 AM   6:12 PM   03-03-2026      3 Ramadan 1447
...
30    4:38 AM   6:28 PM   30-03-2026      30 Ramadan 1447

Specific Roza with Custom Date

roza --first-roza-date 2026-03-01 -n 27
Shows prayer times for March 27, 2026 (27th day from March 1).

JSON Output with Custom Date

roza --first-roza-date 2026-03-01 --json
The JSON output uses your custom date for calculations:
{
  "mode": "today",
  "location": "Dubai, United Arab Emirates",
  "hijriYear": 1447,
  "rows": [
    {
      "roza": 15,
      "sehar": "4:45 AM",
      "iftar": "6:32 PM",
      "date": "15-03-2026",
      "hijri": "15 Ramadan 1447"
    }
  ]
}

Clearing the Custom Date

Use the --clear-first-roza-date flag to remove the stored custom date and return to API-based Hijri calendar:
roza --clear-first-roza-date
After clearing, Ramadan CLI will use the Hijri calendar from the API again.
If you provide both --first-roza-date and --clear-first-roza-date, the clear flag takes precedence.
# This clears the date (--clear-first-roza-date wins)
roza --first-roza-date 2026-03-01 --clear-first-roza-date

Precedence and Storage

Configuration Resolution

const getConfiguredFirstRozaDate = (
  opts: RamadanCommandOptions
): Date | null => {
  // 1. Clear flag takes precedence
  if (opts.clearFirstRozaDate) {
    clearStoredFirstRozaDate();
    return null;
  }

  // 2. Explicit flag sets and persists
  if (opts.firstRozaDate) {
    const parsedExplicit = parseIsoDate(opts.firstRozaDate);
    if (!parsedExplicit) {
      throw new Error('Invalid first roza date. Use YYYY-MM-DD.');
    }
    setStoredFirstRozaDate(opts.firstRozaDate);
    return parsedExplicit;
  }

  // 3. Use stored date if available
  const storedDate = getStoredFirstRozaDate();
  if (!storedDate) {
    return null;
  }

  const parsedStored = parseIsoDate(storedDate);
  if (parsedStored) {
    return parsedStored;
  }

  // 4. If stored date is invalid, clear it
  clearStoredFirstRozaDate();
  return null;
};

Where It’s Stored

Default location:
~/.config/ramadan-cli/config.json
Custom location (via environment variable):
export RAMADAN_CLI_CONFIG_DIR="/path/to/custom/config"

Viewing Stored Configuration

roza config --show
{
  "location": {
    "city": "San Francisco",
    "country": "United States",
    "latitude": 37.7749,
    "longitude": -122.4194
  },
  "prayerSettings": {
    "method": 2,
    "school": 0,
    "timezone": "America/Los_Angeles"
  },
  "firstRozaDate": "2026-03-01"
}

Before Ramadan Behavior

If the current date is before your custom first roza date:
# Today is February 20, 2026
roza --first-roza-date 2026-03-01
Today Sehar/Iftar
📍 Karachi, Pakistan

Roza  Sehar     Iftar     Date            Hijri
------------------------------------------------------
1     5:10 AM   6:15 PM   01-03-2026      1 Ramadan 1447 ← next

Status: Before roza day
Up next: First Sehar in 8d 10h 25m
When before Ramadan, the CLI shows timings for the first roza and calculates the countdown to the first Sehar.

After Ramadan Behavior

If the current date is more than 30 days after your custom first roza date, the CLI still uses your custom calendar but annotations may not appear:
# Today is April 5, 2026 (35 days after March 1)
roza --first-roza-date 2026-03-01
The current day calculation will show roza 35, but since Ramadan only has 30 days, viewing the calendar will show days 1-30.

Performance Considerations

API Calls

1 API call to fetch the entire Hijri month 9 (Ramadan)Fast ⚡
// Standard: Single API call
fetchHijriCalendarByAddress({ address, year, month: 9 })

// Custom: 30 parallel API calls
Promise.all(
  days.map(async (dayDate) => fetchRamadanDay(query, dayDate))
)

Caching

The custom first roza date is cached in your config file, so you don’t need to specify it on every run:
# First time: set and persist
roza --first-roza-date 2026-03-01

# All subsequent runs: uses stored date
roza
roza --all
roza -n 15

Common Use Cases

Following Local Masjid

# Your masjid announces Ramadan starts March 2
roza --first-roza-date 2026-03-02

# Now all commands use this date
roza              # Today's roza
roza --all        # Full calendar from March 2
roza -n 27        # Laylat al-Qadr timing

Different Calculation Methods

# North America often starts a day later
roza --first-roza-date 2026-03-01

# Middle East calculation
roza --first-roza-date 2026-02-28

Testing Future Ramadan

# Test with next year's dates
roza --first-roza-date 2027-02-17 --all --json > ramadan-2027.json

Resetting Everything

To clear both the custom date and all other configuration:
roza reset
This removes:
  • Saved location
  • Prayer calculation method and school
  • Custom first roza date
  • Timezone preferences
You’ll be prompted for first-run setup on the next run.

Country-Specific Recommendations

Even when using a custom first roza date, Ramadan CLI still applies country-specific recommended calculation methods:
// From src/recommendations.ts
const countryMethodMap: Record<string, number> = {
  'United States': 2,       // ISNA
  'Pakistan': 1,            // University of Islamic Sciences, Karachi
  'Saudi Arabia': 4,        // Umm Al-Qura
  'Egypt': 5,               // Egyptian General Authority of Survey
  'United Kingdom': 3,      // Muslim World League
  // ... and more
};
This ensures accurate prayer times for your location even when overriding the Ramadan start date.