Hijri calendar
Islamic (Hijri) dates: a Gregorian date in Umm al-Qura, civil or observational reckoning, written in English and Arabic; a Hijri date back to the Gregorian; a month's first and last days; and the year's holy days.
Version 1.0.0 · 4 functions · 3 crates
Functions
What use hijri.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use hijri_from_date, hijri_to_date from hijri (Quillo 0.6).
hijri_from_date(date: str, calendar: str) → anyor an errorA Gregorian date ("2026-10-29", or "today") in the Hijri calendar calendar ("umm_al_qura", the default when ""; "civil", "tabular" or "observational"): { year, month, day, month_name, month_name_ar, weekday, weekday_ar, days_in_month, text, text_ar }, text as "18 Jumada al-Awwal 1448 AH".
hijri_to_date(year: int, month: int, day: int, calendar: str) → stror an errorThe Gregorian date ("2027-03-09") of a Hijri date in calendar ("" for Umm al-Qura).
hijri_month(year: int, month: int, calendar: str) → anyor an errorA Hijri month in Gregorian dates: { year, month, month_name, first, last, days }; hijri_month(1448, 9, "") is Ramadan 1448.
hijri_holy_days(year: int, calendar: str) → listor an errorThe holy days of Hijri year year with their Gregorian dates: Islamic New Year, Ashura, the Mawlid, Isra and Mi'raj, the start of Ramadan, Laylat al-Qadr, Eid al-Fitr, the Day of Arafah and Eid al-Adha. By calculation: where a day is fixed by sighting the moon, it may come a day later.
Get it
$ quillo install hijri # hijri.qwer into this folder$ quillo install hijri --example # and its example, hijri.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/hijri.qwer$ curl -O https://quillolang.org/plugins/files/hijri.qweThen, in your program, all of it or only what you call:
use hijri.qweruse hijri_from_date, hijri_to_date from hijri // Quillo 0.6: only theseIt uses these crates, which cargo fetches the first time the plugin is built:
icu_calendar = "=1.5.2"chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }serde_json = { version = "1", features = ["preserve_order"] }Example
// A mosque's website: today's Hijri date in the header, Ramadan's dates, and the year's holy days.//// quillo run hijri.qwe then open http://localhost:8080/calendaruse "hijri.qwer"route GET /calendar { { today: hijri_from_date("today", "")?.text, date: hijri_from_date("2026-10-29", "")?, civil: hijri_from_date("2026-10-29", "civil")?.text, ramadan: hijri_month(1448, 9, "")?, back: hijri_to_date(1447, 10, 1, "")?, bad: hijri_month(1448, 13, "").error, }}route GET /holy-days/:year(int) = hijri_holy_days(year, "")?route GET / { let h = hijri_from_date("today", "")? <html><body> <header>{h.weekday}, {h.text} · <span dir="rtl" lang="ar">{h.weekday_ar} {h.text_ar}</span></header> </body></html>}$ quillo run hijri.qwe$ curl 'localhost:8080/calendar'$ curl 'localhost:8080/holy-days/1447'Source
//! Islamic (Hijri) calendar dates: today's date in Umm al-Qura (Saudi Arabia's official calendar), the civil tabular or the observational calendar, written in English and Arabic; a Hijri date back to the Gregorian one; a month's first and last days; and the year's holy days.//! version: 1.0.0//!//! [dependencies]//! icu_calendar = "=1.5.2"//! chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }//! serde_json = { version = "1", features = ["preserve_order"] }use chrono::{Datelike, NaiveDate};use icu_calendar::islamic::{IslamicCivil, IslamicObservational, IslamicTabular, IslamicUmmAlQura};use icu_calendar::{Date, Iso};use serde_json::{json, Value};const MONTHS: [&str; 12] = ["Muharram", "Safar", "Rabi al-Awwal", "Rabi al-Thani", "Jumada al-Awwal", "Jumada al-Thani", "Rajab", "Shaban", "Ramadan", "Shawwal", "Dhu al-Qadah", "Dhu al-Hijjah"];const MONTHS_AR: [&str; 12] = ["محرم", "صفر", "ربيع الأول", "ربيع الآخر", "جمادى الأولى", "جمادى الآخرة", "رجب", "شعبان", "رمضان", "شوال", "ذو القعدة", "ذو الحجة"];const WEEKDAYS: [&str; 7] = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];const WEEKDAYS_AR: [&str; 7] = ["الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"];#[derive(Clone, Copy)]enum Kind { UmmAlQura, Civil, Tabular, Observational }fn kind(name: &str) -> Result<Kind, String> { Ok(match name.trim().to_lowercase().replace(['-', ' '], "_").as_str() { "" | "umm_al_qura" | "ummalqura" | "saudi" => Kind::UmmAlQura, "civil" => Kind::Civil, "tabular" => Kind::Tabular, "observational" | "sighting" => Kind::Observational, other => return Err(format!("`{}` is not a Hijri calendar: umm_al_qura, civil, tabular or observational", other)), })}fn iso_of(date: &str) -> Result<(NaiveDate, Date<Iso>), String> { let t = date.trim(); let d = if t.is_empty() || t == "today" { chrono::Utc::now().date_naive() } else { NaiveDate::parse_from_str(t.get(..10).unwrap_or(t), "%Y-%m-%d").map_err(|_| format!("`{}` is not a date (2026-10-29)", date))? }; let iso = Date::try_new_iso_date(d.year(), d.month() as u8, d.day() as u8).map_err(|e| format!("{}: {:?}", date, e))?; Ok((d, iso))}// (year, month, day, days in month) of an ISO date.fn to_hijri(iso: &Date<Iso>, k: Kind) -> (i32, u8, u8, u8) { macro_rules! conv { ($cal:expr) => {{ let h = iso.to_calendar($cal); (h.year().number, h.month().ordinal as u8, h.day_of_month().0 as u8, h.days_in_month()) }} } match k { Kind::UmmAlQura => conv!(IslamicUmmAlQura::new()), Kind::Civil => conv!(IslamicCivil::new()), Kind::Tabular => conv!(IslamicTabular::new()), Kind::Observational => conv!(IslamicObservational::new()), }}fn to_gregorian(y: i32, m: u8, d: u8, k: Kind) -> Result<NaiveDate, String> { let bad = |e: icu_calendar::CalendarError| format!("{}-{}-{} is not a Hijri date: {:?}", y, m, d, e); let iso = match k { Kind::UmmAlQura => Date::try_new_ummalqura_date(y, m, d, IslamicUmmAlQura::new()).map_err(bad)?.to_iso(), Kind::Civil => Date::try_new_islamic_civil_date_with_calendar(y, m, d, IslamicCivil::new()).map_err(bad)?.to_iso(), Kind::Tabular => Date::try_new_islamic_tabular_date_with_calendar(y, m, d, IslamicTabular::new()).map_err(bad)?.to_iso(), Kind::Observational => Date::try_new_observational_islamic_date(y, m, d, IslamicObservational::new()).map_err(bad)?.to_iso(), }; NaiveDate::from_ymd_opt(iso.year().number, iso.month().ordinal, iso.day_of_month().0).ok_or_else(|| "the date is out of range".to_string())}fn arabic_digits(n: i64) -> String { n.to_string().chars().map(|c| match c.to_digit(10) { Some(d) => char::from_u32(0x0660 + d).unwrap(), None => c }).collect()}fn check(y: i64, m: i64) -> Result<(), String> { if !(1..=9999).contains(&y) || !(1..=12).contains(&m) { return Err(format!("{}-{} is not a Hijri year and month (months 1 to 12)", y, m)); } Ok(())}/// A Gregorian date (`"2026-10-29"`, or `"today"`) in the Hijri calendar `calendar` (`"umm_al_qura"`, the default when `""`; `"civil"`, `"tabular"` or `"observational"`):/// `{ year, month, day, month_name, month_name_ar, weekday, weekday_ar, days_in_month, text, text_ar }`, `text` as "18 Jumada al-Awwal 1448 AH".pub fn hijri_from_date(date: &str, calendar: &str) -> Result<Value, String> { let k = kind(calendar)?; let (g, iso) = iso_of(date)?; let (y, m, d, dim) = to_hijri(&iso, k); let wd = g.weekday().num_days_from_monday() as usize; let mi = (m as usize).clamp(1, 12) - 1; Ok(json!({ "year": y, "month": m, "day": d, "month_name": MONTHS[mi], "month_name_ar": MONTHS_AR[mi], "weekday": WEEKDAYS[wd], "weekday_ar": WEEKDAYS_AR[wd], "days_in_month": dim, "text": format!("{} {} {} AH", d, MONTHS[mi], y), "text_ar": format!("{} {} {} هـ", arabic_digits(d as i64), MONTHS_AR[mi], arabic_digits(y as i64)), }))}/// The Gregorian date (`"2027-03-09"`) of a Hijri date in `calendar` (`""` for Umm al-Qura).pub fn hijri_to_date(year: i64, month: i64, day: i64, calendar: &str) -> Result<String, String> { check(year, month)?; if !(1..=30).contains(&day) { return Err(format!("day {} is not 1 to 30", day)) } Ok(to_gregorian(year as i32, month as u8, day as u8, kind(calendar)?)?.to_string())}/// A Hijri month in Gregorian dates: `{ year, month, month_name, first, last, days }`; `hijri_month(1448, 9, "")` is Ramadan 1448.pub fn hijri_month(year: i64, month: i64, calendar: &str) -> Result<Value, String> { check(year, month)?; let k = kind(calendar)?; let first = to_gregorian(year as i32, month as u8, 1, k)?; let (_, iso) = iso_of(&first.to_string())?; let days = to_hijri(&iso, k).3 as i64; Ok(json!({ "year": year, "month": month, "month_name": MONTHS[month as usize - 1], "first": first.to_string(), "last": (first + chrono::Duration::days(days - 1)).to_string(), "days": days, }))}/// The holy days of Hijri year `year` with their Gregorian dates: Islamic New Year, Ashura, the Mawlid, Isra and Mi'raj, the start of Ramadan, Laylat al-Qadr, Eid al-Fitr, the Day of Arafah and Eid al-Adha./// By calculation: where a day is fixed by sighting the moon, it may come a day later.pub fn hijri_holy_days(year: i64, calendar: &str) -> Result<Vec<Value>, String> { check(year, 1)?; let k = kind(calendar)?; let days: [(&str, u8, u8); 9] = [ ("Islamic New Year", 1, 1), ("Ashura", 1, 10), ("Mawlid", 3, 12), ("Isra and Mi'raj", 7, 27), ("First day of Ramadan", 9, 1), ("Laylat al-Qadr", 9, 27), ("Eid al-Fitr", 10, 1), ("Day of Arafah", 12, 9), ("Eid al-Adha", 12, 10), ]; days.iter().map(|(name, m, d)| { let g = to_gregorian(year as i32, *m, *d, k)?; Ok(json!({ "name": name, "date": g.to_string(), "hijri": format!("{} {} {}", d, MONTHS[*m as usize - 1], year) })) }).collect()}Related
world_calendars.qwer · 1.0.0Dates in the world's other calendars, each way and with month names: Hebrew, Persian, Ethiopian, Coptic, Indian national, Thai Buddhist, Japanese eras (令和8年) and Taiwan's Minguo; and the Jewish holidays of a year.8 views · 6 downloadsChinese calendar chinese_calendar.qwer · 1.0.0The Chinese lunisolar calendar: a date's lunar year, month and day in Chinese, leap months included, the year's stem and branch, zodiac animal and element, Chinese New Year, lunar dates back to Gregorian, and the 24 solar terms.8 views · 7 downloadsPublic holidays holidays.qwer · 1.0.0Public holidays of 27 countries for any year from 1970 to 2099, computed rather than listed: Easter and its feasts, "the last Monday of May", Japan's equinoxes, with the day each is taken when it falls on a weekend.8 views · 11 downloadsFluent translations fluent.qwer · 1.0.0Project Fluent translations (.ftl): messages formatted by locale with each language's plural forms, selectors on gender or anything else, terms and attributes, fallback from one locale to the next, and translation files checked and compared.8 views · 7 downloadsLanguages languages.qwer · 1.0.0ISO 639 language codes and names in English and in the language itself, two- and three-letter codes read, and the best of your translations picked from Accept-Language.7 views · 9 downloadsBusiness days business_days.qwer · 1.0.0Working days for due dates, delivery estimates and SLAs: add them, count them between dates, skip weekends and holidays, with US, UK, French and German public holidays built in.6 views · 5 downloadsThread 0 posts
On Hijri calendar: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.