hodatime-1.0.0.0: src/Data/HodaTime/Calendar/Gregorian.hs
-----------------------------------------------------------------------------
-- |
-- Module : Data.HodaTime.Calendar.Gregorian
-- 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
--
-- This is the module for 'CalendarDate' and 'CalendarDateTime' in the 'Gregorian' calendar, the civil calendar used across most of the world today. The Gregorian calendar refines the Julian leap
-- year rule: every fourth year is a leap year, except that a century year (one divisible by 100) is a leap year only when it is also divisible by 400. Those century exceptions keep the calendar
-- closely aligned to the solar year and correct the slow drift of 'Data.HodaTime.Calendar.Julian' (which gains roughly three days every four centuries). Unlike some libraries this calendar is not
-- proleptic: because the Gregorian calendar first took effect on 15 October 1582 (the day after 4 October 1582 in the Julian calendar, when ten days were dropped) this implementation rejects any
-- earlier date \- use 'Data.HodaTime.Calendar.Julian' for dates before the changeover. The Gregorian calendar anchors the absolute timeline that every other calendar is measured against, so a given
-- instant's Gregorian date is the reference that the other calendars are offset from.
----------------------------------------------------------------------------
module Data.HodaTime.Calendar.Gregorian
(
-- * Constructors
calendarDate
,fromNthDay
,fromWeekDate
-- * Types
,Month(..)
,DayOfWeek(..)
,Gregorian
)
where
import Data.HodaTime.Calendar.Gregorian.Internal hiding (fromWeekDate)
import Data.HodaTime.CalendarDateTime.Internal (CalendarDate, DayNth, DayOfMonth, Year, WeekNumber)
import Data.HodaTime.Calendar.Internal (mkFromNthDay)
import qualified Data.HodaTime.Calendar.Gregorian.Internal as GI
import Control.Monad (guard)
-- Constructors
-- TODO: smart constructors hard coded to Maybe, make them like LocalTime
-- | Smart constructor for a 'Gregorian' calendar date. Returns 'Nothing' if the day is out of range for the given month and year, or if the date falls before the 15 October 1582 changeover.
calendarDate :: DayOfMonth -> Month Gregorian -> Year -> Maybe (CalendarDate Gregorian)
calendarDate d m y = do
guard $ d > 0 && d <= maxDaysInMonth m y
let gd = gregorianFromYmd y m d
guard $ gregorianToDays gd > invalidDayThresh
return gd
-- | Smart constructor for a 'Gregorian' 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.
fromNthDay :: DayNth -> DayOfWeek Gregorian -> Month Gregorian -> Year -> Maybe (CalendarDate Gregorian)
fromNthDay = mkFromNthDay invalidDayThresh epochDayOfWeek yearMonthDayToDays maxDaysInMonth daysToGregorian
-- | Smart constructor for a 'Gregorian' calendar date given as a week date. Note that this method assumes weeks start on Sunday and the first week of the year is the one
-- which has at least one day in the new year. For ISO compliant behavior use this constructor from the ISO module
fromWeekDate :: WeekNumber -> DayOfWeek Gregorian -> Year -> Maybe (CalendarDate Gregorian)
fromWeekDate = GI.fromWeekDate 1 Sunday