hodatime
Copyright(C) 2016 Jason Johnson
LicenseBSD-style (see the file LICENSE)
MaintainerJason Johnson <jason.johnson.081@gmail.com>
Stabilityexperimental
PortabilityPOSIX, Windows
Safe HaskellSafe-Inferred
LanguageHaskell2010

Data.HodaTime.Pattern.Locale

Description

Compiles the strftime layout strings captured in a Locale by Data.HodaTime.Locale (the operating system's D_FMT / T_FMT on POSIX, translated from the equivalent Windows picture strings) into hodatime Patterns, so a date or time can be formatted and parsed using the machine's own conventions.

Using the machine's own layout

Expand

localeDatePattern turns a locale's D_FMT into a pattern, so the same date renders the way each culture writes it — month-first in the US, day-first in Germany (here march15 is 15 March 2020):

do us  <- localeByName "en_US.UTF-8"
   de  <- localeByName "de_DE.UTF-8"
   usP <- localeDatePattern us
   deP <- localeDatePattern de
   pure (format usP march15, format deP march15)       -- ("03/15/2020", "15.03.2020")

Use currentLocale instead of localeByName to follow the machine's own LC_TIME setting, and parse with the same pattern to read that layout back:

do loc <- currentLocale
   p   <- localeDatePattern loc                        -- the current locale's short-date layout
   pure (format p march15) >>= parse p                 -- round-trips in whatever order the locale uses

localeTimePattern does the same for the time-of-day layout (T_FMT), and localeDateTimePattern for the combined date-and-time layout (D_T_FMT) as a CalendarDateTime.

On time zones

Expand

localeDateTimePattern deliberately ignores the time zone. Most D_T_FMT strings end with %Z (a zone abbreviation such as CEST) or %z (a numeric offset); a CalendarDateTime is civil time with no zone attached, so there is nothing to render there and nothing to interpret, and those specifiers are dropped from the compiled pattern. In particular a zone-less datetime is not assumed to be UTC — treating civil time as UTC is exactly the accidental coupling the library is built to avoid; turning a CalendarDateTime into an absolute instant always requires you to attach an offset or time zone on purpose.

When you do want the zone, use parseZonedDateTime (below): it parses the locale's zoned layout into a ZonedDateTime, capturing the %Z abbreviation and resolving it through a provider you supply (abbreviations are ambiguous, so the caller owns that mapping). It requires the layout to contain a zone, throwing ZonelessLayoutException otherwise — a layout with no zone is not a zoned value.

A layout that instead carries a numeric offset (%z, e.g. +0200) is unambiguous, so localeOffsetDateTimePattern compiles it into an ordinary, pure, bidirectional OffsetDateTime pattern (used with parse and format, no provider needed), throwing OffsetlessLayoutException if the layout has no %z.

Synopsis

Documentation

data StrftimeError Source #

Raised when a layout string uses a strftime conversion that the compiler does not implement.

Constructors

UnsupportedSpecifier Char

a conversion we do not support here (e.g. %Z, %V, or a width/flag like %-d)

DanglingPercent

the layout string ended with a bare %

localeDatePattern :: (MonadThrow m, HasDate d, Enum (MoY d), Enum (DoW d)) => Locale -> m (Pattern (d -> d) (d -> String) String) Source #

The locale's short date pattern, compiled from its short-date layout (rawDateFormat; D_FMT on POSIX).

localeTimePattern :: (MonadThrow m, HasLocalTime lt) => Locale -> m (Pattern (lt -> lt) (lt -> String) String) Source #

The locale's time pattern, compiled from its time layout (rawTimeFormat; T_FMT on POSIX).

localeDateTimePattern :: (MonadThrow m, IsCalendar cal, Enum (Month cal), Enum (DoW (CalendarDateTime cal))) => Locale -> m (Pattern (CalendarDateTime cal -> CalendarDateTime cal) (CalendarDateTime cal -> String) String) Source #

The locale's combined date-and-time pattern, compiled from its combined layout (rawDateTimeFormat; D_T_FMT on POSIX) as a CalendarDateTime. The zone specifiers %Z/%z are dropped — see the note on time zones in the module header.

localeOffsetDateTimePattern :: (MonadThrow m, IsCalendar cal, Enum (Month cal), Enum (DoW (CalendarDateTime cal))) => Locale -> m (Pattern (OffsetDateTime cal -> OffsetDateTime cal) (OffsetDateTime cal -> String) String) Source #

Compile the locale's D_T_FMT into an OffsetDateTime pattern, using its numeric offset (%z, e.g. +0200). Unlike parseZonedDateTime this is a plain, pure, bidirectional pattern (drive it with parse and format) because a numeric offset is unambiguous — no zone provider or resolver is needed. Throws OffsetlessLayoutException if the layout has no %z (the abbreviation form %Z is not an offset; use parseZonedDateTime for that).

parseZonedDateTime :: (MonadThrow m, IsCalendar cal, Enum (Month cal), Enum (DoW (CalendarDateTime cal))) => (String -> m TimeZone) -> (CalendarDateTime cal -> TimeZone -> m (ZonedDateTime cal)) -> Locale -> String -> m (ZonedDateTime cal) Source #

Parse a zoned date/time written in the locale's D_T_FMT into a ZonedDateTime. The local part is read from the layout and the trailing %Z token is captured and handed to the provider (abbreviations such as CEST are ambiguous, so you supply the mapping to a real TimeZone); the resolver then decides skipped/ambiguous local times (e.g. fromCalendarDateTimeStrictly). Throws ZonelessLayoutException if the locale's layout has no %Z (a layout with no zone is not a zoned value).