@@ -13,21 +13,23 @@ module Eucalypt.Stg.Intrinsics.Time
13
13
, toZonedDateTime
14
14
) where
15
15
16
- import Eucalypt.Stg.Error
17
- import Eucalypt.Stg.IntrinsicInfo
18
- import Eucalypt.Stg.Intrinsics.Common (invoke , returnList , returnDynamic )
19
- import Eucalypt.Stg.Native
20
- import Eucalypt.Stg.Machine
16
+ import Data.Dynamic
21
17
import Data.Scientific
22
18
import Data.Time.Calendar
23
19
import Data.Time.Clock.POSIX
24
20
import Data.Time.LocalTime
25
- import Text.Regex.PCRE.Heavy (scan , re )
21
+ import Eucalypt.Stg.Error
22
+ import Eucalypt.Stg.IntrinsicInfo
23
+ import Eucalypt.Stg.Intrinsics.Common (cast , invoke , returnDynamic , returnList )
24
+ import Eucalypt.Stg.Machine
25
+ import Eucalypt.Stg.Native
26
+ import Text.Regex.PCRE.Heavy (re , scan )
26
27
27
28
intrinsics :: [IntrinsicInfo ]
28
29
intrinsics =
29
30
[ IntrinsicInfo " IFIELDS" 1 (invoke instantToUTCFields)
30
31
, IntrinsicInfo " ZDT" 7 (invoke toZonedDateTime)
32
+ , IntrinsicInfo " ZDT.FIELDS" 1 (invoke zdtFields)
31
33
]
32
34
33
35
@@ -38,21 +40,23 @@ instantToUTCFields s d =
38
40
z = utcToZonedTime utc u
39
41
in returnList s $ zonedDateTimeFields z
40
42
43
+ -- | Represent a 'ZonedTime' as its component fields
41
44
zonedDateTimeFields :: ZonedTime -> [(Native , Native )]
42
45
zonedDateTimeFields ZonedTime {.. } =
43
46
let LocalTime {.. } = zonedTimeToLocalTime
44
47
tz = timeZoneOffsetString zonedTimeZone
45
48
(year, month, day) = toGregorian localDay
46
49
TimeOfDay {.. } = localTimeOfDay
47
50
in [ (NativeSymbol " y" , NativeNumber $ fromIntegral year)
48
- , (NativeSymbol " M " , NativeNumber $ fromIntegral month)
51
+ , (NativeSymbol " m " , NativeNumber $ fromIntegral month)
49
52
, (NativeSymbol " d" , NativeNumber $ fromIntegral day)
50
53
, (NativeSymbol " h" , NativeNumber $ fromIntegral todHour)
51
- , (NativeSymbol " m " , NativeNumber $ fromIntegral todMin)
54
+ , (NativeSymbol " M " , NativeNumber $ fromIntegral todMin)
52
55
, (NativeSymbol " s" , NativeNumber $ fromRational $ toRational todSec)
53
56
, (NativeSymbol " Z" , NativeString tz)
54
57
]
55
58
59
+ -- | Parse a time zone string into a 'TimeZone', supports numeric or "UTC"
56
60
timeZoneFromString :: MachineState -> String -> IO TimeZone
57
61
timeZoneFromString _ " UTC" = return utc
58
62
timeZoneFromString _ " " = return utc
@@ -68,6 +72,7 @@ timeZoneFromString ms s =
68
72
in return $ minutesToTimeZone $ sig * (60 * h + m)
69
73
_ -> throwIn ms $ InvalidArgument " Time zone was not valid"
70
74
75
+ -- | Create a raw zoned date time from its components
71
76
toZonedDateTime ::
72
77
MachineState
73
78
-> Scientific
@@ -87,3 +92,10 @@ toZonedDateTime ms y m d h mins s tz =
87
92
dtz <- timeZoneFromString ms tz
88
93
returnDynamic ms $ ZonedTime locTime dtz
89
94
_ -> throwIn ms $ InvalidArgument " Time field was invalid"
95
+
96
+ -- | Split up a raw zoned date time into its components (as k-v pairs
97
+ -- for populating a block).
98
+ zdtFields :: MachineState -> Dynamic -> IO MachineState
99
+ zdtFields ms zdtDyn = do
100
+ zdt <- cast ms zdtDyn
101
+ returnList ms $ zonedDateTimeFields zdt
0 commit comments