    {-# LINE 1 "Data/Text/ICU/Calendar.hsc" #-}
    {-# LANGUAGE RankNTypes, BangPatterns, ForeignFunctionInterface, RecordWildCards #-}
    -- |
    -- Module      : Data.Text.ICU.Calendar
    -- Copyright   : (c) 2021 Torsten Kemps-Benedix
    --
    -- License     : BSD-style
    -- Maintainer  : bos@serpentine.com
    -- Stability   : experimental
    -- Portability : GHC
    --
    -- Calendar functions implemented as bindings to
    -- the International Components for Unicode (ICU) libraries.

    module Data.Text.ICU.Calendar
        (
          -- * Data
          Calendar(..), CalendarType(..), SystemTimeZoneType(..), CalendarField(..), UCalendar,
          -- * High-level interface
          -- ** Operations on calendars
          roll, add, set1, set, get,
          -- ** Calendar field getters
          era, year, month,
          dayOfMonth, dayOfYear, dayOfWeek, dayOfWeekInMonth, amPm,
          hour, hourOfDay, minute, second, millisecond, zoneOffset, dstOffset, yearWoY, doWLocal, extendedYear, julianDay,
          millisecondsInDay, isLeapMonth, day, utcTime,
          -- ** Calendar field setters
          setEra, setYear, setMonth,
          setDayOfMonth, setDayOfYear, setDayOfWeek, setDayOfWeekInMonth, setAmPm,
          setHour, setHourOfDay, setMinute, setSecond, setMillisecond, setZoneOffset, setDstOffset, setYearWoY, setDoWLocal, setExtendedYear, setJulianDay,
          setMillisecondsInDay, setDay,
          -- ** Lenses
          _era, _year, _month,
          _dayOfMonth, _dayOfYear, _dayOfWeek, _dayOfWeekInMonth, _amPm,
          _hour, _hourOfDay, _minute, _second, _millisecond, _zoneOffset, _dstOffset, _day,
          -- ** Time zone functions
          timeZoneIDs, timeZones,
          -- * Low-level interface
          calendar, openTimeZoneIDEnumeration, openTimeZones, getField, setField, setDate, setDateTime, rollField, addField, setTimeZone,
        ) where

    import Control.Monad (forM_)
    import Data.Int (Int32)
    import Data.Text (Text, pack)
    import Data.Text.Foreign (withCStringLen)
    import Data.Text.ICU.Enumerator
    import Data.Text.ICU.Error.Internal (UErrorCode, handleError)
    import Data.Text.ICU.Internal (LocaleName(..), UChar, withLocaleName, newICUPtr, useAsUCharPtr)
    import qualified Data.Time.Calendar as Cal
    import qualified Data.Time.Clock as Clock
    import Foreign.C.String (CString)
    import Foreign.C.Types (CInt(..))
    import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
    import Foreign.Ptr (FunPtr, Ptr)
    import Prelude hiding (last)
    import System.IO.Unsafe (unsafePerformIO)

    type UCalendar = CInt

    -- A 'Calendar' is an abstract data type that contains a foreign pointer to the ICU internal data structure.
    data Calendar = Calendar {Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr :: ForeignPtr UCalendar}

    -- | All the fields that comprise a 'Calendar'.
    data CalendarField =
      Era -- ^ Field indicating the era, e.g., AD or BC in the Gregorian (Julian) calendar. This is a calendar-specific value.
      | Year -- ^ Field indicating the year. This is a calendar-specific value.
      | Month -- ^ Field indicating the month. This is a calendar-specific value. The first month of the year is JANUARY; the last depends on the number of months in a year. Note: Calendar month is 0-based.
      | WeekOfYear -- ^ Field indicating the week number within the current year. The first week of the year, as defined by UCAL_FIRST_DAY_OF_WEEK and UCAL_MINIMAL_DAYS_IN_FIRST_WEEK attributes, has value 1. Subclasses define the value of UCAL_WEEK_OF_YEAR for days before the first week of the year.
      | WeekOfMonth -- ^ Field indicating the week number within the current month. The first week of the month, as defined by UCAL_FIRST_DAY_OF_WEEK and UCAL_MINIMAL_DAYS_IN_FIRST_WEEK attributes, has value 1. Subclasses define the value of WEEK_OF_MONTH for days before the first week of the month.
      | DayOfMonth -- ^ Field indicating the day of the month. This is a synonym for DAY_OF_MONTH. The first day of the month has value 1.
      | DayOfYear -- ^ Field indicating the day number within the current year. The first day of the year has value 1.
      | DayOfWeek -- ^ Field indicating the day of the week. This field takes values SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, and SATURDAY. Note: Calendar day-of-week is 1-based. Clients who create locale resources for the field of first-day-of-week should be aware of this. For instance, in US locale, first-day-of-week is set to 1, i.e., UCAL_SUNDAY.
      | DayOfWeekInMonth -- ^ Field indicating the ordinal number of the day of the week within the current month. Together with the DAY_OF_WEEK field, this uniquely specifies a day within a month. Unlike WEEK_OF_MONTH and WEEK_OF_YEAR, this field's value does not depend on getFirstDayOfWeek() or getMinimalDaysInFirstWeek(). DAY_OF_MONTH 1 through 7 always correspond to DAY_OF_WEEK_IN_MONTH 1; 8 through 15 correspond to DAY_OF_WEEK_IN_MONTH 2, and so on. DAY_OF_WEEK_IN_MONTH 0 indicates the week before DAY_OF_WEEK_IN_MONTH 1. Negative values count back from the end of the month, so the last Sunday of a month is specified as DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1. Because negative values count backward they will usually be aligned differently within the month than positive values. For example, if a month has 31 days, DAY_OF_WEEK_IN_MONTH -1 will overlap DAY_OF_WEEK_IN_MONTH 5 and the end of 4.
      | AmPm -- ^ Field indicating whether the HOUR is before or after noon. E.g., at 10:04:15.250 PM the AM_PM is PM.
      | Hour -- ^ Field indicating the hour of the morning or afternoon. HOUR is used for the 12-hour clock. E.g., at 10:04:15.250 PM the HOUR is 10.
      | HourOfDay -- ^ Field indicating the hour of the day. HOUR_OF_DAY is used for the 24-hour clock. E.g., at 10:04:15.250 PM the HOUR_OF_DAY is 22.
      | Minute -- ^ Field indicating the minute within the hour. E.g., at 10:04:15.250 PM the UCAL_MINUTE is 4.
      | Second -- ^ Field indicating the second within the minute. E.g., at 10:04:15.250 PM the UCAL_SECOND is 15.
      | Millisecond -- ^ Field indicating the millisecond within the second. E.g., at 10:04:15.250 PM the UCAL_MILLISECOND is 250.
      | ZoneOffset -- ^ Field indicating the raw offset from GMT in milliseconds.
      | DstOffset -- ^ Field indicating the daylight savings offset in milliseconds.
      | YearWoY -- ^ Field indicating the extended year corresponding to the UCAL_WEEK_OF_YEAR field. This may be one greater or less than the value of UCAL_EXTENDED_YEAR.
      | DoWLocal -- ^ Field indicating the localized day of week. This will be a value from 1 to 7 inclusive, with 1 being the localized first day of the week.
      | ExtendedYear -- ^ Year of this calendar system, encompassing all supra-year fields. For example, in Gregorian/Julian calendars, positive Extended Year values indicate years AD, 1 BC = 0 extended, 2 BC = -1 extended, and so on.
      | JulianDay -- ^ Field indicating the modified Julian day number. This is different from the conventional Julian day number in two regards. First, it demarcates days at local zone midnight, rather than noon GMT. Second, it is a local number; that is, it depends on the local time zone. It can be thought of as a single number that encompasses all the date-related fields.
      | MillisecondsInDay -- ^ Ranges from 0 to 23:59:59.999 (regardless of DST). This field behaves exactly like a composite of all time-related fields, not including the zone fields. As such, it also reflects discontinuities of those fields on DST transition days. On a day of DST onset, it will jump forward. On a day of DST cessation, it will jump backward. This reflects the fact that it must be combined with the DST_OFFSET field to obtain a unique local time value.
      | IsLeapMonth -- ^ Whether or not the current month is a leap month (0 or 1). See the Chinese calendar for an example of this.
      deriving (Int -> CalendarField -> ShowS
    [CalendarField] -> ShowS
    CalendarField -> String
    (Int -> CalendarField -> ShowS)
    -> (CalendarField -> String)
    -> ([CalendarField] -> ShowS)
    -> Show CalendarField
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CalendarField -> ShowS
    showsPrec :: Int -> CalendarField -> ShowS
    $cshow :: CalendarField -> String
    show :: CalendarField -> String
    $cshowList :: [CalendarField] -> ShowS
    showList :: [CalendarField] -> ShowS
    Show, ReadPrec [CalendarField]
    ReadPrec CalendarField
    Int -> ReadS CalendarField
    ReadS [CalendarField]
    (Int -> ReadS CalendarField)
    -> ReadS [CalendarField]
    -> ReadPrec CalendarField
    -> ReadPrec [CalendarField]
    -> Read CalendarField
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS CalendarField
    readsPrec :: Int -> ReadS CalendarField
    $creadList :: ReadS [CalendarField]
    readList :: ReadS [CalendarField]
    $creadPrec :: ReadPrec CalendarField
    readPrec :: ReadPrec CalendarField
    $creadListPrec :: ReadPrec [CalendarField]
    readListPrec :: ReadPrec [CalendarField]
    Read, CalendarField -> CalendarField -> Bool
    (CalendarField -> CalendarField -> Bool)
    -> (CalendarField -> CalendarField -> Bool) -> Eq CalendarField
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CalendarField -> CalendarField -> Bool
    == :: CalendarField -> CalendarField -> Bool
    $c/= :: CalendarField -> CalendarField -> Bool
    /= :: CalendarField -> CalendarField -> Bool
    Eq)

    type UCalendarDateFields = CInt

    toUCalendarDateFields :: CalendarField -> UCalendarDateFields
    toUCalendarDateFields :: CalendarField -> USystemTimeZoneType
    toUCalendarDateFields CalendarField
    Era = USystemTimeZoneType
    0
    {-# LINE 95 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields Year = 1
    {-# LINE 96 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields Month = 2
    {-# LINE 97 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields WeekOfYear = 3
    {-# LINE 98 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields WeekOfMonth = 4
    {-# LINE 99 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields DayOfMonth = 5
    {-# LINE 100 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields DayOfYear = 6
    {-# LINE 101 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields DayOfWeek = 7
    {-# LINE 102 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields DayOfWeekInMonth = 8
    {-# LINE 103 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields AmPm = 9
    {-# LINE 104 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields Hour = 10
    {-# LINE 105 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields HourOfDay = 11
    {-# LINE 106 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields Minute = 12
    {-# LINE 107 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields Second = 13
    {-# LINE 108 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields Millisecond = 14
    {-# LINE 109 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields ZoneOffset = 15
    {-# LINE 110 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields DstOffset = 16
    {-# LINE 111 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields YearWoY = 17
    {-# LINE 112 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields DoWLocal = 18
    {-# LINE 113 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields ExtendedYear = 19
    {-# LINE 114 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields JulianDay = 20
    {-# LINE 115 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields MillisecondsInDay = 21
    {-# LINE 116 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarDateFields IsLeapMonth = 22
    {-# LINE 117 "Data/Text/ICU/Calendar.hsc" #-}

    data CalendarType = TraditionalCalendarType | DefaultCalendarType | GregorianCalendarType
      deriving (Int -> CalendarType -> ShowS
    [CalendarType] -> ShowS
    CalendarType -> String
    (Int -> CalendarType -> ShowS)
    -> (CalendarType -> String)
    -> ([CalendarType] -> ShowS)
    -> Show CalendarType
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CalendarType -> ShowS
    showsPrec :: Int -> CalendarType -> ShowS
    $cshow :: CalendarType -> String
    show :: CalendarType -> String
    $cshowList :: [CalendarType] -> ShowS
    showList :: [CalendarType] -> ShowS
    Show, ReadPrec [CalendarType]
    ReadPrec CalendarType
    Int -> ReadS CalendarType
    ReadS [CalendarType]
    (Int -> ReadS CalendarType)
    -> ReadS [CalendarType]
    -> ReadPrec CalendarType
    -> ReadPrec [CalendarType]
    -> Read CalendarType
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS CalendarType
    readsPrec :: Int -> ReadS CalendarType
    $creadList :: ReadS [CalendarType]
    readList :: ReadS [CalendarType]
    $creadPrec :: ReadPrec CalendarType
    readPrec :: ReadPrec CalendarType
    $creadListPrec :: ReadPrec [CalendarType]
    readListPrec :: ReadPrec [CalendarType]
    Read, CalendarType -> CalendarType -> Bool
    (CalendarType -> CalendarType -> Bool)
    -> (CalendarType -> CalendarType -> Bool) -> Eq CalendarType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CalendarType -> CalendarType -> Bool
    == :: CalendarType -> CalendarType -> Bool
    $c/= :: CalendarType -> CalendarType -> Bool
    /= :: CalendarType -> CalendarType -> Bool
    Eq)

    type UCalendarType = CInt

    toUCalendarType :: CalendarType -> UCalendarType
    toUCalendarType :: CalendarType -> USystemTimeZoneType
    toUCalendarType CalendarType
    TraditionalCalendarType = USystemTimeZoneType
    0
    {-# LINE 125 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarType DefaultCalendarType = 0
    {-# LINE 126 "Data/Text/ICU/Calendar.hsc" #-}
    toUCalendarType GregorianCalendarType = 1
    {-# LINE 127 "Data/Text/ICU/Calendar.hsc" #-}

    data SystemTimeZoneType = AnyTimeZone | CanonicalTimeZone | CanonicalLocationTimeZone
      deriving (Int -> SystemTimeZoneType -> ShowS
    [SystemTimeZoneType] -> ShowS
    SystemTimeZoneType -> String
    (Int -> SystemTimeZoneType -> ShowS)
    -> (SystemTimeZoneType -> String)
    -> ([SystemTimeZoneType] -> ShowS)
    -> Show SystemTimeZoneType
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SystemTimeZoneType -> ShowS
    showsPrec :: Int -> SystemTimeZoneType -> ShowS
    $cshow :: SystemTimeZoneType -> String
    show :: SystemTimeZoneType -> String
    $cshowList :: [SystemTimeZoneType] -> ShowS
    showList :: [SystemTimeZoneType] -> ShowS
    Show, ReadPrec [SystemTimeZoneType]
    ReadPrec SystemTimeZoneType
    Int -> ReadS SystemTimeZoneType
    ReadS [SystemTimeZoneType]
    (Int -> ReadS SystemTimeZoneType)
    -> ReadS [SystemTimeZoneType]
    -> ReadPrec SystemTimeZoneType
    -> ReadPrec [SystemTimeZoneType]
    -> Read SystemTimeZoneType
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS SystemTimeZoneType
    readsPrec :: Int -> ReadS SystemTimeZoneType
    $creadList :: ReadS [SystemTimeZoneType]
    readList :: ReadS [SystemTimeZoneType]
    $creadPrec :: ReadPrec SystemTimeZoneType
    readPrec :: ReadPrec SystemTimeZoneType
    $creadListPrec :: ReadPrec [SystemTimeZoneType]
    readListPrec :: ReadPrec [SystemTimeZoneType]
    Read, SystemTimeZoneType -> SystemTimeZoneType -> Bool
    (SystemTimeZoneType -> SystemTimeZoneType -> Bool)
    -> (SystemTimeZoneType -> SystemTimeZoneType -> Bool)
    -> Eq SystemTimeZoneType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SystemTimeZoneType -> SystemTimeZoneType -> Bool
    == :: SystemTimeZoneType -> SystemTimeZoneType -> Bool
    $c/= :: SystemTimeZoneType -> SystemTimeZoneType -> Bool
    /= :: SystemTimeZoneType -> SystemTimeZoneType -> Bool
    Eq)

    toUSystemTimeZoneType :: SystemTimeZoneType -> USystemTimeZoneType
    toUSystemTimeZoneType :: SystemTimeZoneType -> USystemTimeZoneType
    toUSystemTimeZoneType SystemTimeZoneType
    AnyTimeZone = USystemTimeZoneType
    0
    {-# LINE 133 "Data/Text/ICU/Calendar.hsc" #-}
    toUSystemTimeZoneType CanonicalTimeZone = 1
    {-# LINE 134 "Data/Text/ICU/Calendar.hsc" #-}
    toUSystemTimeZoneType CanonicalLocationTimeZone = 2
    {-# LINE 135 "Data/Text/ICU/Calendar.hsc" #-}

    type USystemTimeZoneType = CInt

    -- | Open a Calendar.
    --
    -- A Calendar may be used to convert a millisecond value to a year,
    -- month, and day.
    --
    -- Note: When unknown TimeZone ID is specified or if the TimeZone ID
    -- specified is "Etc/Unknown", the Calendar returned by the function
    -- is initialized with GMT zone with TimeZone ID UCAL_UNKNOWN_ZONE_ID
    -- ("Etc/Unknown") without any errors/warnings. If you want to check
    -- if a TimeZone ID is valid prior to this function, use
    -- ucal_getCanonicalTimeZoneID.
    --
    -- >>> import qualified Data.Text as T
    -- >>> c <- calendar (T.pack "CET") (Locale "de_DE") TraditionalCalendarType
    -- >>> show c
    -- 2021-10-12 17:37:43
    calendar :: Text -> LocaleName -> CalendarType -> IO Calendar
    calendar :: Text -> LocaleName -> CalendarType -> IO Calendar
    calendar Text
    zoneId LocaleName
    loc CalendarType
    typ =
      LocaleName -> (CString -> IO Calendar) -> IO Calendar
    forall a. LocaleName -> (CString -> IO a) -> IO a
    withLocaleName LocaleName
    loc ((CString -> IO Calendar) -> IO Calendar)
    -> (CString -> IO Calendar) -> IO Calendar
    forall a b. (a -> b) -> a -> b
    $ \CString
    locale ->
        Text -> (Ptr UChar -> I16 -> IO Calendar) -> IO Calendar
    forall a. Text -> (Ptr UChar -> I16 -> IO a) -> IO a
    useAsUCharPtr Text
    zoneId ((Ptr UChar -> I16 -> IO Calendar) -> IO Calendar)
    -> (Ptr UChar -> I16 -> IO Calendar) -> IO Calendar
    forall a b. (a -> b) -> a -> b
    $ \Ptr UChar
    zoneIdPtr I16
    zoneIdLen ->
          (ForeignPtr USystemTimeZoneType -> Calendar)
    -> FinalizerPtr USystemTimeZoneType
    -> IO (Ptr USystemTimeZoneType)
    -> IO Calendar
    forall a i.
    (ForeignPtr a -> i) -> FinalizerPtr a -> IO (Ptr a) -> IO i
    newICUPtr ForeignPtr USystemTimeZoneType -> Calendar
    Calendar FinalizerPtr USystemTimeZoneType
    ucal_close (IO (Ptr USystemTimeZoneType) -> IO Calendar)
    -> IO (Ptr USystemTimeZoneType) -> IO Calendar
    forall a b. (a -> b) -> a -> b
    $
            (Ptr USystemTimeZoneType -> IO (Ptr USystemTimeZoneType))
    -> IO (Ptr USystemTimeZoneType)
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO (Ptr USystemTimeZoneType))
     -> IO (Ptr USystemTimeZoneType))
    -> (Ptr USystemTimeZoneType -> IO (Ptr USystemTimeZoneType))
    -> IO (Ptr USystemTimeZoneType)
    forall a b. (a -> b) -> a -> b
    $ Ptr UChar
    -> Int32
    -> CString
    -> USystemTimeZoneType
    -> Ptr USystemTimeZoneType
    -> IO (Ptr USystemTimeZoneType)
    ucal_open Ptr UChar
    zoneIdPtr (I16 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral I16
    zoneIdLen) CString
    locale (CalendarType -> USystemTimeZoneType
    toUCalendarType CalendarType
    typ)

    setTimeZone :: Calendar -> Text -> IO ()
    setTimeZone :: Calendar -> Text -> IO ()
    setTimeZone Calendar
    cal Text
    zoneId =
      ForeignPtr USystemTimeZoneType
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr (Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr Calendar
    cal) ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr USystemTimeZoneType
    calPtr -> do
        Text -> (CStringLen -> IO ()) -> IO ()
    forall a. Text -> (CStringLen -> IO a) -> IO a
    withCStringLen Text
    zoneId ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \(CString
    zoneIdPtr, Int
    zoneIdLen) -> do
          (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Ptr USystemTimeZoneType
    -> CString -> Int32 -> Ptr USystemTimeZoneType -> IO ()
    ucal_setTimeZone Ptr USystemTimeZoneType
    calPtr CString
    zoneIdPtr (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    zoneIdLen)

    clone :: Calendar -> IO Calendar
    clone :: Calendar -> IO Calendar
    clone Calendar
    cal =
      ForeignPtr USystemTimeZoneType
    -> (Ptr USystemTimeZoneType -> IO Calendar) -> IO Calendar
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr (Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr Calendar
    cal) ((Ptr USystemTimeZoneType -> IO Calendar) -> IO Calendar)
    -> (Ptr USystemTimeZoneType -> IO Calendar) -> IO Calendar
    forall a b. (a -> b) -> a -> b
    $ \Ptr USystemTimeZoneType
    calPtr -> do
        (ForeignPtr USystemTimeZoneType -> Calendar)
    -> FinalizerPtr USystemTimeZoneType
    -> IO (Ptr USystemTimeZoneType)
    -> IO Calendar
    forall a i.
    (ForeignPtr a -> i) -> FinalizerPtr a -> IO (Ptr a) -> IO i
    newICUPtr ForeignPtr USystemTimeZoneType -> Calendar
    Calendar FinalizerPtr USystemTimeZoneType
    ucal_close (IO (Ptr USystemTimeZoneType) -> IO Calendar)
    -> IO (Ptr USystemTimeZoneType) -> IO Calendar
    forall a b. (a -> b) -> a -> b
    $ (Ptr USystemTimeZoneType -> IO (Ptr USystemTimeZoneType))
    -> IO (Ptr USystemTimeZoneType)
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO (Ptr USystemTimeZoneType))
     -> IO (Ptr USystemTimeZoneType))
    -> (Ptr USystemTimeZoneType -> IO (Ptr USystemTimeZoneType))
    -> IO (Ptr USystemTimeZoneType)
    forall a b. (a -> b) -> a -> b
    $ Ptr USystemTimeZoneType
    -> Ptr USystemTimeZoneType -> IO (Ptr USystemTimeZoneType)
    ucal_clone Ptr USystemTimeZoneType
    calPtr

    -- | List of all time zones.
    timeZones :: IO [Text]
    timeZones :: IO [Text]
    timeZones = do
      tzEnum <- IO Enumerator
    openTimeZones
      tzs <- toList tzEnum
      pure tzs

    timeZoneIDs :: SystemTimeZoneType -> IO [Text]
    timeZoneIDs :: SystemTimeZoneType -> IO [Text]
    timeZoneIDs SystemTimeZoneType
    typ = do
      tzEnum <- SystemTimeZoneType -> IO Enumerator
    openTimeZoneIDEnumeration SystemTimeZoneType
    typ
      tzs <- toList tzEnum
      pure tzs

    openTimeZoneIDEnumeration :: SystemTimeZoneType -> IO Enumerator
    openTimeZoneIDEnumeration :: SystemTimeZoneType -> IO Enumerator
    openTimeZoneIDEnumeration SystemTimeZoneType
    typ = IO (Ptr UEnumerator) -> IO Enumerator
    createEnumerator (IO (Ptr UEnumerator) -> IO Enumerator)
    -> IO (Ptr UEnumerator) -> IO Enumerator
    forall a b. (a -> b) -> a -> b
    $
      (Ptr USystemTimeZoneType -> IO (Ptr UEnumerator))
    -> IO (Ptr UEnumerator)
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO (Ptr UEnumerator))
     -> IO (Ptr UEnumerator))
    -> (Ptr USystemTimeZoneType -> IO (Ptr UEnumerator))
    -> IO (Ptr UEnumerator)
    forall a b. (a -> b) -> a -> b
    $ USystemTimeZoneType
    -> Ptr USystemTimeZoneType -> IO (Ptr UEnumerator)
    ucal_openTimeZoneIDEnumeration (SystemTimeZoneType -> USystemTimeZoneType
    toUSystemTimeZoneType SystemTimeZoneType
    typ)

    -- | Create an enumeration over all time zones.
    openTimeZones :: IO Enumerator
    openTimeZones :: IO Enumerator
    openTimeZones = IO (Ptr UEnumerator) -> IO Enumerator
    createEnumerator (IO (Ptr UEnumerator) -> IO Enumerator)
    -> IO (Ptr UEnumerator) -> IO Enumerator
    forall a b. (a -> b) -> a -> b
    $ (Ptr USystemTimeZoneType -> IO (Ptr UEnumerator))
    -> IO (Ptr UEnumerator)
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO (Ptr UEnumerator))
     -> IO (Ptr UEnumerator))
    -> (Ptr USystemTimeZoneType -> IO (Ptr UEnumerator))
    -> IO (Ptr UEnumerator)
    forall a b. (a -> b) -> a -> b
    $ Ptr USystemTimeZoneType -> IO (Ptr UEnumerator)
    ucal_openTimeZones

    -- | Get the value of a specific calendar field.
    --
    -- >>> import qualified Data.Text as T
    -- >>> c <- calendar (T.pack "CET") (Locale "de_DE") TraditionalCalendarType
    -- >>> getField c Year
    -- 2021
    getField :: Calendar -> CalendarField -> IO Int
    getField :: Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    fld = ForeignPtr USystemTimeZoneType
    -> (Ptr USystemTimeZoneType -> IO Int) -> IO Int
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr (Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr Calendar
    cal) ((Ptr USystemTimeZoneType -> IO Int) -> IO Int)
    -> (Ptr USystemTimeZoneType -> IO Int) -> IO Int
    forall a b. (a -> b) -> a -> b
    $ \Ptr USystemTimeZoneType
    calPtr -> do
      n <- (Ptr USystemTimeZoneType -> IO Int32) -> IO Int32
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO Int32) -> IO Int32)
    -> (Ptr USystemTimeZoneType -> IO Int32) -> IO Int32
    forall a b. (a -> b) -> a -> b
    $ Ptr USystemTimeZoneType
    -> USystemTimeZoneType -> Ptr USystemTimeZoneType -> IO Int32
    ucal_get Ptr USystemTimeZoneType
    calPtr (CalendarField -> USystemTimeZoneType
    toUCalendarDateFields CalendarField
    fld)
      pure (fromIntegral n)

    setField :: Calendar -> CalendarField -> Int -> IO ()
    setField :: Calendar -> CalendarField -> Int -> IO ()
    setField Calendar
    cal CalendarField
    fld Int
    n = ForeignPtr USystemTimeZoneType
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr (Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr Calendar
    cal) ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr USystemTimeZoneType
    calPtr ->
      Ptr USystemTimeZoneType -> USystemTimeZoneType -> Int32 -> IO ()
    ucal_set Ptr USystemTimeZoneType
    calPtr (CalendarField -> USystemTimeZoneType
    toUCalendarDateFields CalendarField
    fld) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n)

    setDate :: Calendar -> Int -> Int -> Int -> IO ()
    setDate :: Calendar -> Int -> Int -> Int -> IO ()
    setDate Calendar
    cal Int
    y Int
    m Int
    d = ForeignPtr USystemTimeZoneType
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr (Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr Calendar
    cal) ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr USystemTimeZoneType
    calPtr ->
      (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Ptr USystemTimeZoneType
    -> Int32 -> Int32 -> Int32 -> Ptr USystemTimeZoneType -> IO ()
    ucal_setDate Ptr USystemTimeZoneType
    calPtr (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    y) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    m) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    d)

    setDateTime :: Calendar -> Int -> Int -> Int -> Int -> Int -> Int -> IO ()
    setDateTime :: Calendar -> Int -> Int -> Int -> Int -> Int -> Int -> IO ()
    setDateTime Calendar
    cal Int
    y Int
    m Int
    d Int
    hr Int
    mn Int
    sec = ForeignPtr USystemTimeZoneType
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr (Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr Calendar
    cal) ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr USystemTimeZoneType
    calPtr ->
      (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Ptr USystemTimeZoneType
    -> Int32
    -> Int32
    -> Int32
    -> Int32
    -> Int32
    -> Int32
    -> Ptr USystemTimeZoneType
    -> IO ()
    ucal_setDateTime Ptr USystemTimeZoneType
    calPtr (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    y) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    m) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    d) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    hr) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    mn) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    sec)

    -- | Add a specified signed amount to a particular field in a Calendar.
    --
    -- This will not modify more significant fields in the calendar. Rolling by a
    -- positive value always means moving forward in time (unless the limit of the
    -- field is reached, in which case it may pin or wrap), so for Gregorian
    -- calendar, starting with 100 BC and rolling the year by +1 results in 99 BC.
    -- When eras have a definite beginning and end (as in the Chinese calendar, or
    -- as in most eras in the Japanese calendar) then rolling the year past either
    -- limit of the era will cause the year to wrap around. When eras only have a
    -- limit at one end, then attempting to roll the year past that limit will
    --result in pinning the year at that limit. Note that for most calendars in
    -- which era 0 years move forward in time (such as Buddhist, Hebrew, or Islamic),
    -- it is possible for add or roll to result in negative years for era 0 (that
    -- is the only way to represent years before the calendar epoch).
    rollField :: Calendar -> CalendarField -> Int -> IO ()
    rollField :: Calendar -> CalendarField -> Int -> IO ()
    rollField Calendar
    cal CalendarField
    fld Int
    n = ForeignPtr USystemTimeZoneType
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr (Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr Calendar
    cal) ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr USystemTimeZoneType
    calPtr ->
      (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Ptr USystemTimeZoneType
    -> USystemTimeZoneType -> Int32 -> Ptr USystemTimeZoneType -> IO ()
    ucal_roll Ptr USystemTimeZoneType
    calPtr (CalendarField -> USystemTimeZoneType
    toUCalendarDateFields CalendarField
    fld) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n)

    -- | Add a specified signed amount to a particular field in a Calendar.
    --
    -- See 'rollField' for further details.
    --
    -- >>> import qualified Data.Text as T
    -- >>> c1 <- calendar (T.pack "CET") (Locale "de_DE") TraditionalCalendarType
    -- >>> show c1
    -- 2021-10-12 17:53:26
    -- >>> let c2 = roll c1 [(Hour, 2)]
    -- >>> show c2
    -- 2021-10-12 19:53:26
    -- >>> let c3 = roll c1 [(Hour, 12)]
    -- >>> show c3
    -- 2021-10-12 17:53:26
    -- >>> let c4 = add c1 [(Hour, 12)]
    -- >>> show c4
    -- 2021-10-13 5:53:26
    roll ::
      Calendar
      -> [(CalendarField, Int)] -- ^ The field and the signed amount to add to this field. If the amount causes the value to exceed to maximum or minimum values for that field, the field is pinned to a permissible value.
      -> Calendar
    roll :: Calendar -> [(CalendarField, Int)] -> Calendar
    roll Calendar
    cal [(CalendarField, Int)]
    lst = IO Calendar -> Calendar
    forall a. IO a -> a
    unsafePerformIO (IO Calendar -> Calendar) -> IO Calendar -> Calendar
    forall a b. (a -> b) -> a -> b
    $ do
      cal' <- Calendar -> IO Calendar
    clone Calendar
    cal
      forM_ lst (\(CalendarField
    fld,Int
    n) -> Calendar -> CalendarField -> Int -> IO ()
    rollField Calendar
    cal' CalendarField
    fld Int
    n)
      pure cal'

    -- | Add a specified signed amount to a particular field in a Calendar.
    --
    -- This can modify more significant fields in the calendar. Adding a positive
    -- value always means moving forward in time, so for the Gregorian calendar,
    -- starting with 100 BC and adding +1 to year results in 99 BC (even though
    -- this actually reduces the numeric value of the field itself).
    addField :: Calendar -> CalendarField -> Int -> IO ()
    addField :: Calendar -> CalendarField -> Int -> IO ()
    addField Calendar
    cal CalendarField
    fld Int
    n = ForeignPtr USystemTimeZoneType
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr (Calendar -> ForeignPtr USystemTimeZoneType
    calendarForeignPtr Calendar
    cal) ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr USystemTimeZoneType
    calPtr ->
      (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a. (Ptr USystemTimeZoneType -> IO a) -> IO a
    handleError ((Ptr USystemTimeZoneType -> IO ()) -> IO ())
    -> (Ptr USystemTimeZoneType -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Ptr USystemTimeZoneType
    -> USystemTimeZoneType -> Int32 -> Ptr USystemTimeZoneType -> IO ()
    ucal_add Ptr USystemTimeZoneType
    calPtr (CalendarField -> USystemTimeZoneType
    toUCalendarDateFields CalendarField
    fld) (Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n)

    -- | Add a specified signed amount to a particular field in a Calendar.
    --
    -- See 'addField' for further details and see 'rollField' for examples and differences
    -- compared to rolling.
    add ::
      Calendar -- ^ The 'Calendar' to which to add.
      -> [(CalendarField, Int)] -- ^ Field type and the signed amount to add to field. If the amount causes the value to exceed to maximum or minimum values for that field, other fields are modified to preserve the magnitude of the change.
      -> Calendar
    add :: Calendar -> [(CalendarField, Int)] -> Calendar
    add Calendar
    cal [(CalendarField, Int)]
    lst = IO Calendar -> Calendar
    forall a. IO a -> a
    unsafePerformIO (IO Calendar -> Calendar) -> IO Calendar -> Calendar
    forall a b. (a -> b) -> a -> b
    $ do
      cal' <- Calendar -> IO Calendar
    clone Calendar
    cal
      forM_ lst (\(CalendarField
    fld,Int
    n) -> Calendar -> CalendarField -> Int -> IO ()
    addField Calendar
    cal' CalendarField
    fld Int
    n)
      pure cal'

    -- | Set the value of one field of a calendar to a certain value. All fields are
    -- represented as 32-bit integers.
    set1 :: Calendar -> CalendarField -> Int -> Calendar
    set1 :: Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    fld Int
    n = IO Calendar -> Calendar
    forall a. IO a -> a
    unsafePerformIO (IO Calendar -> Calendar) -> IO Calendar -> Calendar
    forall a b. (a -> b) -> a -> b
    $ do
      cal' <- Calendar -> IO Calendar
    clone Calendar
    cal
      setField cal' fld n
      pure cal'

    -- | Set the value of a list of fields of a calendar to certain values. All fields are
    -- represented as 32-bit integers.
    set :: Calendar -> [(CalendarField, Int)] -> Calendar
    set :: Calendar -> [(CalendarField, Int)] -> Calendar
    set Calendar
    cal [(CalendarField, Int)]
    lst = IO Calendar -> Calendar
    forall a. IO a -> a
    unsafePerformIO (IO Calendar -> Calendar) -> IO Calendar -> Calendar
    forall a b. (a -> b) -> a -> b
    $ do
      cal' <- Calendar -> IO Calendar
    clone Calendar
    cal
      forM_ lst (\(CalendarField
    fld,Int
    n) -> Calendar -> CalendarField -> Int -> IO ()
    setField Calendar
    cal' CalendarField
    fld Int
    n)
      pure cal'

    -- | Convert the day part of the calendar to a 'Day'.
    --
    -- >>> import qualified Data.Text as T
    -- >>> c1 <- calendar (T.pack "CET") (Locale "de_DE") TraditionalCalendarType
    -- >>> show c1
    -- 2021-10-12 18:00:50
    -- >>> day c1
    -- 2021-10-12
    day :: Calendar -> Cal.Day
    day :: Calendar -> Day
    day Calendar
    cal = IO Day -> Day
    forall a. IO a -> a
    unsafePerformIO (IO Day -> Day) -> IO Day -> Day
    forall a b. (a -> b) -> a -> b
    $ do
      y <- Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    Year
      m <- getField cal Month
      d <- getField cal DayOfMonth
      pure (Cal.fromGregorian (fromIntegral y) (m+1) d)

    -- | Set the day part of the calendar from a 'Day'.
    setDay :: Calendar -> Cal.Day -> Calendar
    setDay :: Calendar -> Day -> Calendar
    setDay Calendar
    cal Day
    aDay = IO Calendar -> Calendar
    forall a. IO a -> a
    unsafePerformIO (IO Calendar -> Calendar) -> IO Calendar -> Calendar
    forall a b. (a -> b) -> a -> b
    $ do
      cal' <- Calendar -> IO Calendar
    clone Calendar
    cal
      let (y,m,d) = Cal.toGregorian aDay
      setDate cal' (fromIntegral y) (m-1) d
      pure cal'

    -- | Convert the day and time part of the calendar to a 'UTCTime'.
    --
    -- >>> import qualified Data.Text as T
    -- >>> c1 <- calendar (T.pack "CET") (Locale "de_DE") TraditionalCalendarType
    -- >>> show c1
    -- 2021-10-12 18:00:50
    -- >>> utcTime c1
    -- 2021-10-12 16:00:50.544999999998 UTC
    utcTime :: Calendar -> Clock.UTCTime
    utcTime :: Calendar -> UTCTime
    utcTime Calendar
    cal = IO UTCTime -> UTCTime
    forall a. IO a -> a
    unsafePerformIO (IO UTCTime -> UTCTime) -> IO UTCTime -> UTCTime
    forall a b. (a -> b) -> a -> b
    $ do
      cal' <- Calendar -> IO Calendar
    clone Calendar
    cal
      setTimeZone cal' (pack "UTC")
      y <- getField cal' Year
      m <- getField cal' Month
      d <- getField cal' DayOfMonth
      let day' = Year -> Int -> Int -> Day
    Cal.fromGregorian (Int -> Year
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    y) (Int
    mInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) Int
    d
      ms <- getField cal' MillisecondsInDay
      let dt = Double -> DiffTime
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac ((Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    ms :: Double) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    1000)
      pure $ Clock.UTCTime day' dt

    -- | Get the value of a specific field in the calendar.
    get :: Calendar -> CalendarField -> Int
    get :: Calendar -> CalendarField -> Int
    get Calendar
    cal CalendarField
    fld = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    fld

    -- | Return the era of the calendar. The values are calendar specific and are usually 0 (some ancient era) and 1 (current era).
    --
    -- >>> import qualified Data.Text as T
    -- >>> c1 <- calendar (T.pack "CET") (Locale "de_DE") TraditionalCalendarType
    -- >>> era c1
    -- 1
    era :: Calendar -> Int
    era :: Calendar -> Int
    era Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    Era

    setEra :: Calendar -> Int -> Calendar
    setEra :: Calendar -> Int -> Calendar
    setEra Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    Era

    -- | Return the year of the calendar. The values are calendar specific.
    --
    -- >>> import qualified Data.Text as T
    -- >>> c1 <- calendar (T.pack "CET") (Locale "de_DE") TraditionalCalendarType
    -- >>> year c1
    -- 2021
    year :: Calendar -> Int
    year :: Calendar -> Int
    year Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    Year

    setYear :: Calendar -> Int -> Calendar
    setYear :: Calendar -> Int -> Calendar
    setYear Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    Year

    -- | Return the month of the calendar. The values are calendar specific and 0-based.
    --
    -- >>> import qualified Data.Text as T
    -- >>> c1 <- calendar (T.pack "CET") (Locale "de_DE") TraditionalCalendarType
    -- >>> month c1
    -- 9
    -- >>> day c1
    -- 2021-10-12
    month :: Calendar -> Int
    month :: Calendar -> Int
    month Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    Month

    setMonth :: Calendar -> Int -> Calendar
    setMonth :: Calendar -> Int -> Calendar
    setMonth Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    Month

    dayOfMonth :: Calendar -> Int
    dayOfMonth :: Calendar -> Int
    dayOfMonth Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    DayOfMonth

    setDayOfMonth :: Calendar -> Int -> Calendar
    setDayOfMonth :: Calendar -> Int -> Calendar
    setDayOfMonth Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    DayOfMonth

    dayOfYear :: Calendar -> Int
    dayOfYear :: Calendar -> Int
    dayOfYear Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    DayOfYear

    setDayOfYear :: Calendar -> Int -> Calendar
    setDayOfYear :: Calendar -> Int -> Calendar
    setDayOfYear Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    DayOfYear

    dayOfWeek :: Calendar -> Int
    dayOfWeek :: Calendar -> Int
    dayOfWeek Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    DayOfWeek

    setDayOfWeek :: Calendar -> Int -> Calendar
    setDayOfWeek :: Calendar -> Int -> Calendar
    setDayOfWeek Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    DayOfWeek

    dayOfWeekInMonth :: Calendar -> Int
    dayOfWeekInMonth :: Calendar -> Int
    dayOfWeekInMonth Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    DayOfWeekInMonth

    setDayOfWeekInMonth :: Calendar -> Int -> Calendar
    setDayOfWeekInMonth :: Calendar -> Int -> Calendar
    setDayOfWeekInMonth Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    DayOfWeekInMonth

    amPm :: Calendar -> Int
    amPm :: Calendar -> Int
    amPm Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    AmPm

    setAmPm :: Calendar -> Int -> Calendar
    setAmPm :: Calendar -> Int -> Calendar
    setAmPm Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    AmPm

    hour :: Calendar -> Int
    hour :: Calendar -> Int
    hour Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    Hour

    setHour :: Calendar -> Int -> Calendar
    setHour :: Calendar -> Int -> Calendar
    setHour Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    Hour

    hourOfDay :: Calendar -> Int
    hourOfDay :: Calendar -> Int
    hourOfDay Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    HourOfDay

    setHourOfDay :: Calendar -> Int -> Calendar
    setHourOfDay :: Calendar -> Int -> Calendar
    setHourOfDay Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    HourOfDay

    minute :: Calendar -> Int
    minute :: Calendar -> Int
    minute Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    Minute

    setMinute :: Calendar -> Int -> Calendar
    setMinute :: Calendar -> Int -> Calendar
    setMinute Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    Minute

    second :: Calendar -> Int
    second :: Calendar -> Int
    second Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    Second

    setSecond :: Calendar -> Int -> Calendar
    setSecond :: Calendar -> Int -> Calendar
    setSecond Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    Second

    millisecond :: Calendar -> Int
    millisecond :: Calendar -> Int
    millisecond Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    Millisecond

    setMillisecond :: Calendar -> Int -> Calendar
    setMillisecond :: Calendar -> Int -> Calendar
    setMillisecond Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    Millisecond

    zoneOffset :: Calendar -> Int
    zoneOffset :: Calendar -> Int
    zoneOffset Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    ZoneOffset

    setZoneOffset :: Calendar -> Int -> Calendar
    setZoneOffset :: Calendar -> Int -> Calendar
    setZoneOffset Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    ZoneOffset

    dstOffset :: Calendar -> Int
    dstOffset :: Calendar -> Int
    dstOffset Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    DstOffset

    setDstOffset :: Calendar -> Int -> Calendar
    setDstOffset :: Calendar -> Int -> Calendar
    setDstOffset Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    DstOffset

    yearWoY :: Calendar -> Int
    yearWoY :: Calendar -> Int
    yearWoY Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    YearWoY

    setYearWoY :: Calendar -> Int -> Calendar
    setYearWoY :: Calendar -> Int -> Calendar
    setYearWoY Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    YearWoY

    doWLocal :: Calendar -> Int
    doWLocal :: Calendar -> Int
    doWLocal Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    DoWLocal

    setDoWLocal :: Calendar -> Int -> Calendar
    setDoWLocal :: Calendar -> Int -> Calendar
    setDoWLocal Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    DoWLocal

    extendedYear :: Calendar -> Int
    extendedYear :: Calendar -> Int
    extendedYear Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    ExtendedYear

    setExtendedYear :: Calendar -> Int -> Calendar
    setExtendedYear :: Calendar -> Int -> Calendar
    setExtendedYear Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    ExtendedYear

    julianDay :: Calendar -> Int
    julianDay :: Calendar -> Int
    julianDay Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    JulianDay

    setJulianDay :: Calendar -> Int -> Calendar
    setJulianDay :: Calendar -> Int -> Calendar
    setJulianDay Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    JulianDay

    millisecondsInDay :: Calendar -> Int
    millisecondsInDay :: Calendar -> Int
    millisecondsInDay Calendar
    cal = IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    MillisecondsInDay

    setMillisecondsInDay :: Calendar -> Int -> Calendar
    setMillisecondsInDay :: Calendar -> Int -> Calendar
    setMillisecondsInDay Calendar
    cal = Calendar -> CalendarField -> Int -> Calendar
    set1 Calendar
    cal CalendarField
    MillisecondsInDay

    isLeapMonth :: Calendar -> Bool
    isLeapMonth :: Calendar -> Bool
    isLeapMonth Calendar
    cal = Int
    0 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= (IO Int -> Int
    forall a. IO a -> a
    unsafePerformIO (IO Int -> Int) -> IO Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Calendar -> CalendarField -> IO Int
    getField Calendar
    cal CalendarField
    IsLeapMonth)

    -- Copied from the lens package in order not to generate a dependency.
    type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
    type Lens' s a = Lens s s a a

    lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens :: forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens s -> a
    sa s -> b -> t
    sbt a -> f b
    afb s
    s = s -> b -> t
    sbt s
    s (b -> t) -> f b -> f t
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> a -> f b
    afb (s -> a
    sa s
    s)
    {-# INLINE lens #-}

    _era :: Lens' Calendar Int
    _era :: Lens' Calendar Int
    _era = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    era Calendar -> Int -> Calendar
    setEra

    _year :: Lens' Calendar Int
    _year :: Lens' Calendar Int
    _year = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    year Calendar -> Int -> Calendar
    setYear

    _month :: Lens' Calendar Int
    _month :: Lens' Calendar Int
    _month = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    month Calendar -> Int -> Calendar
    setMonth

    _dayOfYear :: Lens' Calendar Int
    _dayOfYear :: Lens' Calendar Int
    _dayOfYear = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    dayOfYear Calendar -> Int -> Calendar
    setDayOfYear

    _dayOfMonth :: Lens' Calendar Int
    _dayOfMonth :: Lens' Calendar Int
    _dayOfMonth = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    dayOfMonth Calendar -> Int -> Calendar
    setDayOfMonth

    _dayOfWeek :: Lens' Calendar Int
    _dayOfWeek :: Lens' Calendar Int
    _dayOfWeek = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    dayOfWeek Calendar -> Int -> Calendar
    setDayOfWeek

    _dayOfWeekInMonth :: Lens' Calendar Int
    _dayOfWeekInMonth :: Lens' Calendar Int
    _dayOfWeekInMonth = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    dayOfWeekInMonth Calendar -> Int -> Calendar
    setDayOfWeekInMonth

    _amPm :: Lens' Calendar Int
    _amPm :: Lens' Calendar Int
    _amPm = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    amPm Calendar -> Int -> Calendar
    setAmPm

    _hour :: Lens' Calendar Int
    _hour :: Lens' Calendar Int
    _hour = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    hour Calendar -> Int -> Calendar
    setHour

    _hourOfDay :: Lens' Calendar Int
    _hourOfDay :: Lens' Calendar Int
    _hourOfDay = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    hour Calendar -> Int -> Calendar
    setHourOfDay

    _minute :: Lens' Calendar Int
    _minute :: Lens' Calendar Int
    _minute = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    minute Calendar -> Int -> Calendar
    setMinute

    _second :: Lens' Calendar Int
    _second :: Lens' Calendar Int
    _second = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    second Calendar -> Int -> Calendar
    setSecond

    _millisecond :: Lens' Calendar Int
    _millisecond :: Lens' Calendar Int
    _millisecond = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    millisecond Calendar -> Int -> Calendar
    setMillisecond

    _zoneOffset :: Lens' Calendar Int
    _zoneOffset :: Lens' Calendar Int
    _zoneOffset = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    zoneOffset Calendar -> Int -> Calendar
    setZoneOffset

    _dstOffset :: Lens' Calendar Int
    _dstOffset :: Lens' Calendar Int
    _dstOffset = (Calendar -> Int)
    -> (Calendar -> Int -> Calendar) -> Lens' Calendar Int
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Int
    dstOffset Calendar -> Int -> Calendar
    setDstOffset

    _day :: Lens' Calendar Cal.Day
    _day :: Lens' Calendar Day
    _day = (Calendar -> Day)
    -> (Calendar -> Day -> Calendar) -> Lens' Calendar Day
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens Calendar -> Day
    day Calendar -> Day -> Calendar
    setDay

    instance Show Calendar where
      show :: Calendar -> String
    show Calendar
    cal = UTCTime -> String
    forall a. Show a => a -> String
    show (Calendar -> UTCTime
    utcTime Calendar
    cal)

    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_open" ucal_open
        :: Ptr UChar -> Int32 -> CString -> UCalendar -> Ptr UErrorCode
        -> IO (Ptr UCalendar)
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_clone" ucal_clone
        :: Ptr UCalendar -> Ptr UErrorCode
        -> IO (Ptr UCalendar)
    foreign import ccall unsafe "hs_text_icu.h &__hs_ucal_close" ucal_close
        :: FunPtr (Ptr UCalendar -> IO ())
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_get" ucal_get
        :: Ptr UCalendar -> UCalendarDateFields -> Ptr UErrorCode
        -> IO Int32
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_set" ucal_set
        :: Ptr UCalendar -> UCalendarDateFields -> Int32
        -> IO ()
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_setDate" ucal_setDate
        :: Ptr UCalendar -> Int32 -> Int32 -> Int32
        -> Ptr UErrorCode -> IO ()
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_setDateTime" ucal_setDateTime
        :: Ptr UCalendar -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32
        -> Ptr UErrorCode -> IO ()
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_add" ucal_add
        :: Ptr UCalendar -> UCalendarDateFields -> Int32 -> Ptr UErrorCode
        -> IO ()
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_roll" ucal_roll
        :: Ptr UCalendar -> UCalendarDateFields -> Int32 -> Ptr UErrorCode
        -> IO ()
    foreign import ccall unsafe "hs_text_icu.h _hs__ucal_openTimeZoneIDEnumeration" ucal_openTimeZoneIDEnumeration
        :: USystemTimeZoneType -> Ptr UErrorCode
        -> IO (Ptr UEnumerator)
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_openTimeZones" ucal_openTimeZones
        :: Ptr UErrorCode
        -> IO (Ptr UEnumerator)
    foreign import ccall unsafe "hs_text_icu.h __hs_ucal_setTimeZone" ucal_setTimeZone
        :: Ptr UCalendar -> CString -> Int32 -> Ptr UErrorCode
        -> IO ()