| Copyright | (C) 2017 Jason Johnson |
|---|---|
| License | BSD-style (see the file LICENSE) |
| Maintainer | Jason Johnson <jason.johnson.081@gmail.com> |
| Stability | experimental |
| Portability | POSIX, Windows |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Data.HodaTime.Calendar.Islamic
Description
This is the module for CalendarDate and CalendarDateTime in the Islamic (Hijri) calendar, a purely lunar calendar of twelve months. The odd-numbered months (Muharram, RabiAlAwwal, … ) have
30 days and the even-numbered months (Safar, RabiAlThani, … ) have 29, except that the final month (DhulHijjah) gains a thirtieth day in a leap year. A common year is therefore 354 days and a
leap year 355 — roughly eleven days shorter than a solar year, so Islamic dates drift steadily backwards through the seasons. Year 1 begins on 18.Jul.622 CE (proleptic Gregorian), the year of the
Hijra; dates share the same absolute timeline as every other calendar.
Which Islamic calendar this is, and the choices we made
There is no single "Islamic calendar": the religiously authoritative one is observational (each month begins on the naked-eye sighting of the new crescent), which is inherently non-algorithmic and varies by location, so it cannot be computed. What software can compute is either the tabular (arithmetic) calendar or a tabulated astronomical calendar such as Umm al-Qura. This module implements the tabular arithmetic calendar. A tabular calendar leaves two parameters open — the leap-year pattern and the epoch — and we treat them differently:
- Leap-year pattern: selectable, defaulting to "Base16" (type II). A leap pattern says which 11 of every 30 years carry the extra day. Four patterns are in common use, and the calendar is
parameterised over them at the type level (see below), so a date always records which pattern built it and the type system refuses to mix incompatible ones. The default, Base16 — leap years
2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 of each cycle — is the pattern used by the .NET BCL
HijriCalendarand NodaTime'sIslamicBcl, so it is the most interoperable choice and the one we cross-check against. - Epoch: fixed to astronomical ("Thursday") — 18.Jul.622 CE (proleptic Gregorian), Julian day 1948439. The alternative "civil" ("Friday") epoch is exactly one day later. Unlike the leap
pattern, the epoch does not change the calendar's internal structure (month lengths, leap years, arithmetic); it only shifts how Islamic dates line up with the absolute timeline — i.e. their
Instant, their Gregorian correspondence and their day-of-week — by that one day. Because it is a one-day alignment convention rather than a structurally different calendar, we fix it (to the astronomical epoch, matching the .NET BCL and NodaTime) rather than expose it. Were it ever wanted it would become a second type parameter in exactly the same way as the leap pattern, a non-breaking change (today'sIslamic lwould become a synonym forIslamic l Astronomical).
Being purely arithmetic, the calendar is exact by definition (there is no astronomical approximation, unlike the astronomical Persian calendar) and total for every year, so — like the Coptic calendar — it is only floored at year 1 (the Hijra) and has no upper bound. Note that the tabular calendar can differ from an actual crescent sighting, and from the Umm al-Qura calendar, by a day or two; if you need to match observation you must use sighting data, which is outside the scope of an arithmetic calendar.
Selecting a leap pattern
The calendar type carries the leap pattern as a type parameter of kind LeapPattern: . This is why ordinary, non-configurable calendars such as Islamic lGregorian
are unaffected — only a calendar that actually has a choice to record gains a parameter, and it is always fully applied (e.g. ). Because the parameter is phantom,
the month and weekday constructors (CalendarDateTime (Islamic Base15)Muharram, Sunday, … ) are shared across every variant, but two dates built with different patterns have different types and cannot be combined or compared.
For convenience each pattern has a type synonym — IslamicBcl (the Base16 default), IslamicBase15, IslamicIndian and IslamicHabashAlHasib — and the constructors come in two forms:
calendarDate,fromNthDayandfromWeekDatebuild the defaultIslamicBclcalendar and need no annotation.calendarDate',fromNthDay'andfromWeekDate'are polymorphic in the pattern; choose one with a type annotation orTypeApplications, e.g.calendarDate' @Base15 d m yorcalendarDate' d m y :: Maybe (.CalendarDateIslamicBase15)
Synopsis
- calendarDate :: DayOfMonth -> Month IslamicBcl -> Year -> Maybe (CalendarDate IslamicBcl)
- fromNthDay :: DayNth -> DayOfWeek IslamicBcl -> Month IslamicBcl -> Year -> Maybe (CalendarDate IslamicBcl)
- fromWeekDate :: WeekNumber -> DayOfWeek IslamicBcl -> Year -> Maybe (CalendarDate IslamicBcl)
- calendarDate' :: forall l. KnownLeap l => DayOfMonth -> Month (Islamic l) -> Year -> Maybe (CalendarDate (Islamic l))
- fromNthDay' :: forall l. KnownLeap l => DayNth -> DayOfWeek (Islamic l) -> Month (Islamic l) -> Year -> Maybe (CalendarDate (Islamic l))
- fromWeekDate' :: forall l. KnownLeap l => WeekNumber -> DayOfWeek (Islamic l) -> Year -> Maybe (CalendarDate (Islamic l))
- data family Month cal
- data family DayOfWeek cal
- data Islamic (l :: LeapPattern)
- data LeapPattern
- = Base15
- | Base16
- | Indian
- | HabashAlHasib
- class KnownLeap (l :: LeapPattern)
- type IslamicBcl = Islamic 'Base16
- type IslamicBase15 = Islamic 'Base15
- type IslamicBase16 = Islamic 'Base16
- type IslamicIndian = Islamic 'Indian
- type IslamicHabashAlHasib = Islamic 'HabashAlHasib
Constructors (default IslamicBcl calendar)
calendarDate :: DayOfMonth -> Month IslamicBcl -> Year -> Maybe (CalendarDate IslamicBcl) Source #
Smart constructor for the default IslamicBcl calendar date. Returns Nothing if the day is out of range for the
month or the year is before the epoch (year 1). Use calendarDate' to pick a different leap pattern.
fromNthDay :: DayNth -> DayOfWeek IslamicBcl -> Month IslamicBcl -> Year -> Maybe (CalendarDate IslamicBcl) Source #
Smart constructor for the default IslamicBcl calendar date given as a day relative to a month (e.g. the third Monday of the month). Returns Nothing if the resulting date is invalid.
fromWeekDate :: WeekNumber -> DayOfWeek IslamicBcl -> Year -> Maybe (CalendarDate IslamicBcl) Source #
Smart constructor for the default IslamicBcl calendar date given as a week date. Note that this method assumes weeks start on Saturday (as in the Islamic calendar) and the first week of the year is
the one which has at least one day in the new year.
Constructors (choose the leap pattern)
calendarDate' :: forall l. KnownLeap l => DayOfMonth -> Month (Islamic l) -> Year -> Maybe (CalendarDate (Islamic l)) Source #
fromNthDay' :: forall l. KnownLeap l => DayNth -> DayOfWeek (Islamic l) -> Month (Islamic l) -> Year -> Maybe (CalendarDate (Islamic l)) Source #
As fromNthDay, but in any leap pattern (chosen by the result type).
fromWeekDate' :: forall l. KnownLeap l => WeekNumber -> DayOfWeek (Islamic l) -> Year -> Maybe (CalendarDate (Islamic l)) Source #
As fromWeekDate, but in any leap pattern (chosen by the result type).
Types
data family Month cal Source #
Instances
data family DayOfWeek cal Source #
Instances
data Islamic (l :: LeapPattern) Source #
The Islamic (Hijri) calendar, parameterised by its leap-year pattern (see LeapPattern and the module header).
Instances
data LeapPattern Source #
The four tabular leap-year patterns in common use, used as the (kind-LeapPattern) type parameter of Islamic.
Each names which 11 of the 30 cycle years carry the extra day; Base16 is the .NET BCL / NodaTime default (see
the module header).
Constructors
| Base15 | |
| Base16 | |
| Indian | |
| HabashAlHasib |
class KnownLeap (l :: LeapPattern) Source #
Reflects a LeapPattern type down to its leap-year bit set: bit n is set when year n of the 30-year cycle
(0-based, so year `mod` 30) is a leap year. Use TypeApplications to read it, e.g. .leapPatternBits @Base16
Minimal complete definition
leapPatternBits
Instances
| KnownLeap 'Base15 Source # | |
Defined in Data.HodaTime.Calendar.Islamic Methods | |
| KnownLeap 'Base16 Source # | |
Defined in Data.HodaTime.Calendar.Islamic Methods | |
| KnownLeap 'HabashAlHasib Source # | |
Defined in Data.HodaTime.Calendar.Islamic Methods | |
| KnownLeap 'Indian Source # | |
Defined in Data.HodaTime.Calendar.Islamic Methods | |
Named calendars (leap-pattern type synonyms)
type IslamicBcl = Islamic 'Base16 Source #
The default Islamic calendar: the Base16 leap pattern, matching the .NET BCL HijriCalendar and NodaTime's IslamicBcl.
type IslamicBase15 = Islamic 'Base15 Source #
The Base15 tabular calendar.
type IslamicBase16 = Islamic 'Base16 Source #
The Base16 tabular calendar (same as IslamicBcl).
type IslamicIndian = Islamic 'Indian Source #
The Indian tabular calendar.
type IslamicHabashAlHasib = Islamic 'HabashAlHasib Source #
The Habash al-Hasib tabular calendar.