@@ -1,8 +1,17 @@
1−module Data.Intl.DateTimeFormat
1+module Data.Intl.DateTimeFormat
22 ( LocalesOption
33 , LocaleMatcher(..)
44 , TimeZone(..)
55 , FormatMatcher(..)
6+ , WeekdayYearMonthDayHourMinuteSecond(..)
7+ , WeekdayYearMonthDay(..)
8+ , YearMonthDay(..)
9+ , YearMonth(..)
10+ , MonthDay(..)
11+ , HourMinuteSecond(..)
12+ , HourMinute(..)
13+ , Undefined
14+ , undefined
615 , DateTimeFormatOptions(..)
716 , DateTimeFormatOptions'
817 , DateTimeComponents(..)
@@ -22,19 +31,23 @@ import Data.Either (Either(..))
2231import Data.Foreign (F, Foreign, ForeignError(..), isUndefined, readString)
2332import Data.Foreign.Index ((!))
2433import Data.Function.Uncurried (Fn3, Fn4, runFn3, runFn4)
25−import Data.Intl.DateTimeFormat.Class (class FormatComponent, FormatComponentRecord(FormatComponentRecord), formatComponent)
34+import Data.Generic.Rep (class Generic)
35+import Data.Intl.DateTimeFormat.Generic (class FormatComponent, defaultComponentRecord, formatComponent, genericFormatComponent)
2636import Data.JSDate (JSDate)
2737import Data.Maybe (Maybe(..), fromMaybe, maybe)
28−import Data.Newtype (class Newtype, un)
38+import Data.Newtype (class Newtype)
2939import Data.StrMap (union)
3040import Data.Symbol (SProxy(..))
3141import Data.Traversable (sequence)
32−import Data.Variant (Variant, case_, default, on)
42+import Data.Variant (Variant, default, on)
3343import Prelude (class Eq, class Show, Unit, bind, id, pure, show, (#), ($), (<$>), (<<<), (>>=))
3444import Unsafe.Coerce (unsafeCoerce)
3545
3646foreign import data LocalesOption' :: Type
3747
48+foreign import data Undefined :: Type
49+foreign import undefined :: Undefined
50+
3851foreign import dateTimeFormatImpl :: LocalesOption' -> DateTimeFormatOptions_ -> DateTimeFormat
3952
4053newtype DateTimeFormatOptions_ = DateTimeFormatOptions_
@@ -86,6 +99,85 @@ instance showFormatMatcher :: Show FormatMatcher where
8699 show FMBasic = "basic"
87100 show FMBestFit = "best fit"
88101
102+newtype WeekdayYearMonthDayHourMinuteSecond = WeekdayYearMonthDayHourMinuteSecond
103+ { weekday :: StringRep
104+ , year :: NumericRep
105+ , month :: MonthRep
106+ , day :: NumericRep
107+ , hour :: NumericRep
108+ , minute :: NumericRep
109+ , second :: NumericRep
110+ }
111+
112+derive instance genericWeekdayYearMonthDayHourMinuteSecond :: Generic WeekdayYearMonthDayHourMinuteSecond _
113+
114+instance formatComponentWeekdayYearMonthDayHourMinuteSecond :: FormatComponent WeekdayYearMonthDayHourMinuteSecond where
115+ formatComponent = genericFormatComponent
116+
117+newtype WeekdayYearMonthDay = WeekdayYearMonthDay
118+ { weekday :: StringRep
119+ , year :: NumericRep
120+ , month :: MonthRep
121+ , day :: NumericRep
122+ }
123+
124+derive instance genericWeekdayYearMonthDay :: Generic WeekdayYearMonthDay _
125+
126+instance formatComponentWeekdayYearMonthDay :: FormatComponent WeekdayYearMonthDay where
127+ formatComponent = genericFormatComponent
128+
129+newtype YearMonthDay = YearMonthDay
130+ { year :: NumericRep
131+ , month :: MonthRep
132+ , day :: NumericRep
133+ }
134+
135+derive instance genericYearMonthDay :: Generic YearMonthDay _
136+
137+instance formatComponentYearMonthDay :: FormatComponent YearMonthDay where
138+ formatComponent = genericFormatComponent
139+
140+newtype YearMonth = YearMonth
141+ { year :: NumericRep
142+ , month :: MonthRep
143+ }
144+
145+derive instance genericYearMonth :: Generic YearMonth _
146+
147+instance formatComponentYearMonth :: FormatComponent YearMonth where
148+ formatComponent = genericFormatComponent
149+
150+newtype MonthDay = MonthDay
151+ { month :: MonthRep
152+ , day :: NumericRep
153+ }
154+
155+derive instance genericMonthDay :: Generic MonthDay _
156+
157+instance formatComponentMonthDay :: FormatComponent MonthDay where
158+ formatComponent = genericFormatComponent
159+
160+newtype HourMinuteSecond = HourMinuteSecond
161+ { hour :: NumericRep
162+ , minute :: NumericRep
163+ , second :: NumericRep
164+ }
165+
166+derive instance genericHourMinuteSecond :: Generic HourMinuteSecond _
167+
168+instance formatComponentHourMinuteSecond :: FormatComponent HourMinuteSecond where
169+ formatComponent = genericFormatComponent
170+
171+newtype HourMinute = HourMinute
172+ { hour :: NumericRep
173+ , minute :: NumericRep
174+ }
175+
176+derive instance genericHourMinute :: Generic HourMinute _
177+
178+instance formatComponentHourMinute :: FormatComponent HourMinute where
179+ formatComponent = genericFormatComponent
180+
89181type DateTimeComponents a =
90182 Variant
91183 ( weekdayYearMonthDayHourMinuteSecond :: WeekdayYearMonthDayHourMinuteSecond
@@ -120,7 +212,7 @@ formatDateTimeOptions (DateTimeFormatOptions opts comps) = merge opts' (compsCoe
120212 , hour12: fromMaybe (unsafeCoerce undefined) opts.hour12
121213 , formatMatcher: maybe undefinedString show opts.formatMatcher
122214 }
123− comps' = un FormatComponentRecord $ case_
215+ comps' = default (defaultComponentRecord)
124216 # on (SProxy :: SProxy "weekdayYearMonthDayHourMinuteSecond") formatComponent
125217 # on (SProxy :: SProxy "weekdayYearMonthDay") formatComponent
126218 # on (SProxy :: SProxy "yearMonthDay") formatComponent
@@ -196,88 +288,6 @@ foreign import createDateTimeFormatImpl
196288 DateTimeFormatOptions_
197289 (F DateTimeFormat)
198290
199−-- | Examples
200−-- | ``` purescript
201−-- | import Data.Variant (inj)
202−-- |
203−-- | fmtHourMinute = F DateTimeFormat
204−-- | fmtHourMinute = createDateTimeFormat locale opts
205−-- | where
206−-- | locale = inj (SProxy :: SProxy "locale") "en-GB"
207−-- | opts = (DateTimeFormatOptions
208−-- | { localeMatcher: Nothing
209−-- | , timeZone: (Just (TimeZone "Europe/London"))
210−-- | , hour12: Just false
211−-- | , formatMatcher: Nothing
212−-- | }
213−-- | (inj (SProxy :: SProxy "hourMinute")
214−-- | (HourMinute {hour: TwoDigit, minute: TwoDigit}))
215−-- |
216−-- |
217−-- | fmtDate :: F DateTimeFormat
218−-- | fmtDate = createDateTimeFormat locale opts
219−-- | wher
220−-- | locale = inj (SProxy :: SProxy "locale") "en-GB"
221−-- | opts :: DateTimeFormatOptions'
222−-- | opts =
223−-- | (DateTimeFormatOptions
224−-- | { localeMatcher: Nothing
225−-- | , timeZone: (Just (TimeZone "Europe/London"))
226−-- | , hour12: Just true
227−-- | , formatMatcher: Nothing
228−-- | }
229−-- | (inj
230−-- | (SProxy :: SProxy "weekdayYearMonthDayHourMinuteSecond")
231−-- | (WeekdayYearMonthDayHourMinuteSecond
232−-- | { weekday: Short
233−-- | , year: Numeric
234−-- | , month: MonthLong
235−-- | , day: Numeric
236−-- | , hour: Numeric
237−-- | , minute: Numeric
238−-- | , second: Numeric
239−-- | }
240−-- | )
241−-- | )
242−-- | )
243−-- | ```
244−-- | You have predifined types: `WeekdayYearMonthDayHourMinuteSecond`,
245−-- | `WeekdayYearMonthDay`, `YearMonthDay`, `YearMonth`, `MonthDay`,
246−-- | `HourMinuteSecond`, `HourMinute`. But you can also provide your own by
247−-- | implementing `FormatComponent` class (or by deriving it), e.g.
248−-- | ``` purescript
249−-- | newtype EraYear = EraYear
250−-- | { era :: StringRep
251−-- | , year :: NumericRep
252−-- | }
253−-- |
254−-- | derive instance genericEraYear :: Generic EraYear _
255−-- |
256−-- | instance formatComponentEraYear :: FormatComponent EraYear where
257−-- | formatComponent = genericFormatComponent
258−-- |
259−-- | fmtEraYear :: F DateTimeFormat
260−-- | fmtEraYear = createDateTimeFormat locales opts
261−-- | where
262−-- | locale = inj (SProxy :: SProxy "locale") "en-GB"
263−-- | opts :: DateTimeFormatOptions EraYear
264−-- | opts =
265−-- | (DateTimeFormatOptions
266−-- | { localeMatcher: Nothing
267−-- | , timeZone: (Just (TimeZone "Europe/London"))
268−-- | , hour12: Just true
269−-- | , formatMatcher: Nothing
270−-- | }
271−-- | (inj
272−-- | (SProxy :: SProxy "custom")
273−-- | (EraYear
274−-- | { era: Long
275−-- | , year: Numeric
276−-- | }
277−-- | )
278−-- | )
279−-- | )
280−-- | ```
281291createDateTimeFormat
282292 :: forall a
283293 .(FormatComponent a)
@@ -291,12 +301,6 @@ createDateTimeFormat ls opts =
291301 (toLocale ls)
292302 (formatDateTimeOptions opts)
293303
294−-- | Examples
295−-- | ``` purescript
296−-- | formatJSDate (either (const "") id $ runExcept fmtHourMinute) date -- "12:00"
297−-- | formatJSDate (either (const "") id $ fmtDate) date -- "Tue, January 2, 2018, 12:00:00 PM"
298−-- | formatJSDate (either (const "") id $ fmtEraYear) date -- "2018 Anno Domini"
299−-- | ```
300304foreign import formatJSDate :: DateTimeFormat -> JSDate -> String
301305
302306foreign import supportedLocalesOfImpl
@@ -305,7 +309,7 @@ foreign import supportedLocalesOfImpl
305309 (Array String -> Either String (Array String))
306310 (Array String)
307311 (Either String (Array String))
308−
312+
309313foreign import formatToPartsImpl :: DateTimeFormat -> JSDate -> Array Foreign
310314
311315formatToParts :: DateTimeFormat -> JSDate -> F (Array FormatParts)