git.iko.soy/purescript-intl
on 010ca64 help sign in
purescript-intl/src/Data/Intl/DateTimeFormat.purs
296 lines 8.9 kB history raw
1module Data.Intl.DateTimeFormat
2 ( LocalesOption
3 , LocaleMatcher(..)
4 , TimeZone(..)
5 , FormatMatcher(..)
6 , WeekdayYearMonthDayHourMinuteSecond(..)
7 , WeekdayYearMonthDay(..)
8 , YearMonthDay(..)
9 , YearMonth(..)
10 , MonthDay(..)
11 , HourMinuteSecond(..)
12 , HourMinute(..)
13 , Undefined
14 , undefined
15 , DateTimeFormatOptions(..)
16 , DateTimeFormatOptions'
17 , DateTimeComponents(..)
18 , DateTimeFormatter
19 , createDateTimeFormatter
20 , formatJSDate
21 , module Data.Intl.DateTimeFormat.Types
22 , supportedLocalesOf
23 ) where
25import Data.Intl.DateTimeFormat.Types
27import Data.Either (Either(..))
28import Data.Function.Uncurried (Fn3, runFn3)
29import Data.Generic.Rep (class Generic)
30import Data.Intl.DateTimeFormat.Generic (class FormatComponent, defaultComponentRecord, formatComponent, genericFormatComponent)
31import Data.JSDate (JSDate)
32import Data.Maybe (Maybe, fromMaybe, maybe)
33import Data.Newtype (class Newtype)
34import Data.StrMap (union)
35import Data.Symbol (SProxy(..))
36import Data.Variant (Variant, default, on)
37import Prelude (class Eq, class Show, Unit, id, show, (#), ($))
38import Unsafe.Coerce (unsafeCoerce)
40foreign import data LocalesOption' :: Type
41foreign import data DateTimeFormat :: Type
43foreign import data Undefined :: Type
44foreign import undefined :: Undefined
46foreign import dateTimeFormatImpl :: LocalesOption' -> DateTimeFormatOptions_ -> DateTimeFormat
48newtype DateTimeFormatOptions_ = DateTimeFormatOptions_
49 { localeMatcher :: String
50 , timeZone :: String
51 , hour12 :: Boolean
52 , formatMatcher :: String
53 , weekday :: String
54 , era :: String
55 , year :: String
56 , month :: String
57 , day :: String
58 , hour :: String
59 , minutes :: String
60 , second :: String
61 , timeZoneName :: String
62 }
64type LocalesOption = Variant (locale :: String, locales :: Array String, undefined :: Undefined)
66toLocale :: LocalesOption -> LocalesOption'
67toLocale = unsafeCoerce $
68 default undefined
69 # on (SProxy :: SProxy "locale") id
70 # on (SProxy :: SProxy "locales") id
72data LocaleMatcher
73 = LMLookup
74 | LMBestFit
76instance showLocaleMatcher :: Show LocaleMatcher where
77 show LMLookup = "lookup"
78 show LMBestFit = "best fit"
80newtype TimeZone = TimeZone String
82instance showTimeZone :: Show TimeZone where
83 show (TimeZone tz) = tz
85derive instance newtypeTimeZone :: Newtype TimeZone _
87derive instance eqTimeZone :: Eq TimeZone
89data FormatMatcher
90 = FMBasic
91 | FMBestFit
93instance showFormatMatcher :: Show FormatMatcher where
94 show FMBasic = "basic"
95 show FMBestFit = "best fit"
97newtype WeekdayYearMonthDayHourMinuteSecond = WeekdayYearMonthDayHourMinuteSecond
98 { weekday :: StringRep
99 , year :: NumericRep
100 , month :: MonthRep
101 , day :: NumericRep
102 , hour :: NumericRep
103 , minute :: NumericRep
104 , second :: NumericRep
105 }
107derive instance genericWeekdayYearMonthDayHourMinuteSecond :: Generic WeekdayYearMonthDayHourMinuteSecond _
109instance formatComponentWeekdayYearMonthDayHourMinuteSecond :: FormatComponent WeekdayYearMonthDayHourMinuteSecond where
110 formatComponent = genericFormatComponent
112newtype WeekdayYearMonthDay = WeekdayYearMonthDay
113 { weekday :: StringRep
114 , year :: NumericRep
115 , month :: MonthRep
116 , day :: NumericRep
117 }
119derive instance genericWeekdayYearMonthDay :: Generic WeekdayYearMonthDay _
121instance formatComponentWeekdayYearMonthDay :: FormatComponent WeekdayYearMonthDay where
122 formatComponent = genericFormatComponent
124newtype YearMonthDay = YearMonthDay
125 { year :: NumericRep
126 , month :: MonthRep
127 , day :: NumericRep
128 }
130derive instance genericYearMonthDay :: Generic YearMonthDay _
132instance formatComponentYearMonthDay :: FormatComponent YearMonthDay where
133 formatComponent = genericFormatComponent
135newtype YearMonth = YearMonth
136 { year :: NumericRep
137 , month :: MonthRep
138 }
140derive instance genericYearMonth :: Generic YearMonth _
142instance formatComponentYearMonth :: FormatComponent YearMonth where
143 formatComponent = genericFormatComponent
145newtype MonthDay = MonthDay
146 { month :: MonthRep
147 , day :: NumericRep
148 }
150derive instance genericMonthDay :: Generic MonthDay _
152instance formatComponentMonthDay :: FormatComponent MonthDay where
153 formatComponent = genericFormatComponent
155newtype HourMinuteSecond = HourMinuteSecond
156 { hour :: NumericRep
157 , minute :: NumericRep
158 , second :: NumericRep
159 }
161derive instance genericHourMinuteSecond :: Generic HourMinuteSecond _
163instance formatComponentHourMinuteSecond :: FormatComponent HourMinuteSecond where
164 formatComponent = genericFormatComponent
166newtype HourMinute = HourMinute
167 { hour :: NumericRep
168 , minute :: NumericRep
169 }
171derive instance genericHourMinute :: Generic HourMinute _
173instance formatComponentHourMinute :: FormatComponent HourMinute where
174 formatComponent = genericFormatComponent
176type DateTimeComponents a =
177 Variant
178 ( weekdayYearMonthDayHourMinuteSecond :: WeekdayYearMonthDayHourMinuteSecond
179 , weekdayYearMonthDay :: WeekdayYearMonthDay
180 , yearMonthDay :: YearMonthDay
181 , yearMonth :: YearMonth
182 , monthDay :: MonthDay
183 , hourMinuteSecond :: HourMinuteSecond
184 , hourMinute :: HourMinute
185 , custom :: a
186 )
188data DateTimeFormatOptions a = DateTimeFormatOptions
189 { localeMatcher :: Maybe LocaleMatcher
190 , timeZone :: Maybe TimeZone
191 , hour12 :: Maybe Boolean
192 , formatMatcher :: Maybe FormatMatcher
193 }
194 (DateTimeComponents a)
196type DateTimeFormatOptions' = DateTimeFormatOptions Unit
198formatDateTimeOptions :: forall a. (FormatComponent a) => DateTimeFormatOptions a -> DateTimeFormatOptions_
199formatDateTimeOptions (DateTimeFormatOptions opts comps) = merge opts' (compsCoerce comps')
200 where
202 undefinedString :: String
203 undefinedString = unsafeCoerce undefined
205 opts' = { localeMatcher: maybe undefinedString show opts.localeMatcher
206 , timeZone: maybe undefinedString show opts.timeZone
207 , hour12: fromMaybe (unsafeCoerce undefined) opts.hour12
208 , formatMatcher: maybe undefinedString show opts.formatMatcher
209 }
210 comps' = default (defaultComponentRecord)
211 # on (SProxy :: SProxy "weekdayYearMonthDayHourMinuteSecond") formatComponent
212 # on (SProxy :: SProxy "weekdayYearMonthDay") formatComponent
213 # on (SProxy :: SProxy "yearMonthDay") formatComponent
214 # on (SProxy :: SProxy "yearMonth") formatComponent
215 # on (SProxy :: SProxy "monthDay") formatComponent
216 # on (SProxy :: SProxy "hourMinuteSecond") formatComponent
217 # on (SProxy :: SProxy "hourMinute") formatComponent
218 # on (SProxy :: SProxy "custom") formatComponent
219 $ comps
221 toUndefined :: Maybe String -> String
222 toUndefined m = fromMaybe (unsafeCoerce undefined) m
224 compsCoerce
225 :: { weekday :: Maybe String
226 , era :: Maybe String
227 , year :: Maybe String
228 , month :: Maybe String
229 , day :: Maybe String
230 , hour :: Maybe String
231 , minute :: Maybe String
232 , second :: Maybe String
233 , timeZoneName :: Maybe String
234 }
235 -> { weekday :: String
236 , era :: String
237 , year :: String
238 , month :: String
239 , day :: String
240 , hour :: String
241 , minute :: String
242 , second :: String
243 , timeZoneName :: String
244 }
245 compsCoerce { weekday, era, year, month, day, hour, minute, second, timeZoneName }
246 = { weekday: toUndefined weekday
247 , era: toUndefined era
248 , year: toUndefined year
249 , month: toUndefined month
250 , day: toUndefined day
251 , hour: toUndefined hour
252 , minute: toUndefined minute
253 , second: toUndefined second
254 , timeZoneName: toUndefined timeZoneName
255 }
257 merge
258 :: { localeMatcher :: String
259 , timeZone :: String
260 , hour12 :: Boolean
261 , formatMatcher :: String
262 }
263 -> { weekday :: String
264 , era :: String
265 , year :: String
266 , month :: String
267 , day :: String
268 , hour :: String
269 , minute :: String
270 , second :: String
271 , timeZoneName :: String
272 }
273 -> DateTimeFormatOptions_
274 merge a b = unsafeCoerce $ union (unsafeCoerce a) (unsafeCoerce b)
276foreign import data DateTimeFormatter :: Type
278foreign import createDateTimeFormatterImpl
279 :: LocalesOption'
280 -> DateTimeFormatOptions_
281 -> DateTimeFormatter
283createDateTimeFormatter
284 :: forall a
285 .(FormatComponent a)
286 => LocalesOption
287 -> DateTimeFormatOptions a
288 -> DateTimeFormatter
289createDateTimeFormatter ls opts = createDateTimeFormatterImpl (toLocale ls) (formatDateTimeOptions opts)
291foreign import formatJSDate :: DateTimeFormatter -> JSDate -> String
293foreign import supportedLocalesOfImpl :: Fn3 (String -> Either String (Array String)) (Array String -> Either String (Array String)) (Array String) (Either String (Array String))
295supportedLocalesOf :: Array String -> Either String (Array String)
296supportedLocalesOf locales = runFn3 supportedLocalesOfImpl Left Right locales