forked from jamiejennings/rosie-pattern-language
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdatetime.rpl
179 lines (143 loc) · 7.01 KB
/
datetime.rpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
---- -*- Mode: rpl; -*-
----
---- datetime.rpl Common date/time patterns in Rosie Pattern Language
----
---- © Copyright IBM Corporation 2016.
---- LICENSE: MIT License (https://opensource.org/licenses/mit-license.html)
---- AUTHOR: Jamie A. Jennings
-- [1] RFC3339 Internet Date/Time Format (http:--tools.ietf.org/html/rfc3339)
--
-- [2] RFC2822 Internet Message Format (http:--tools.ietf.org/html/rfc2822)
-- Note that email uses this standard, which is ambiguous and has caused many
-- problems over the years. Patterns for some common forms of this datetime
-- format are included here.
--
-- RFC3339
--
-- date-fullyear = 4DIGIT
-- date-month = 2DIGIT ; 01-12
-- date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
-- ; month/year
-- time-hour = 2DIGIT ; 00-23
-- time-minute = 2DIGIT ; 00-59
-- time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
-- ; rules
-- time-secfrac = "." 1*DIGIT
-- time-numoffset = ("+" / "-") time-hour ":" time-minute
-- time-offset = "Z" / time-numoffset
--
-- partial-time = time-hour ":" time-minute ":" time-second
-- [time-secfrac]
-- full-date = date-fullyear "-" date-month "-" date-mday
-- full-time = partial-time time-offset
--
-- date-time = full-date "T" full-time
--
-- Notes:
-- T and Z may be lowercase.
-- The "T" separator in the date-time rule can be a space instead.
alias d = [:digit:]
-- ---------------------------------------------------------------------------------------------------
-- RFC3339 datetime
alias fullyear = {d d d d}
alias date_month = { {"0" [1-9]} / {"1" [0-2]} }
alias date_mday = { {"0" [1-9]} -- single digit dates
/ {[12][0-9]} -- most of the two digit dates
/ {"3" [01]} } -- and the rest
alias time_hour = { {[01][0-9]} / {"2"[0-3]} }
alias time_minute = {[0-5][0-9]}
alias time_second = { {{[0-5][0-9]} / "60"} {"." d+}? } -- time_second must match 60 for leap second
alias time_numoffset = { [+-] time_hour ":"? time_minute }
alias time_offset = { [Zz] / time_numoffset }
alias partial_time = {time_hour ":" time_minute ":" time_second}
datetime.full_date_RFC3339 = {fullyear "-" date_month "-" date_mday}
datetime.full_time_RFC3339 = {partial_time [:space:]* time_offset}
datetime.datetime_RFC3339 = {datetime.full_date_RFC3339 [Tt] datetime.full_time_RFC3339}
-- Examples from RFC3339
--
-- "1985-04-12T23:20:50.52Z";
-- -- This represents 20 minutes and 50.52 seconds after the 23rd
-- -- hour of April 12th, 1985 in UTC.
--
-- "1996-12-19T16:39:57-08:00";
-- -- This represents 39 minutes and 57 seconds after the 16th hour
-- -- of December 19th, 1996 with an offset of -08:00 from UTC
-- -- (Pacific Standard Time). Note that this is equivalent to
-- -- 1996-12-20T00:39:57Z in UTC.
--
-- "1996-12-20T00:39:57Z";
-- -- See above.
--
-- "1990-12-31T23:59:60Z";
-- -- This represents the leap second inserted at the end of 1990.
--
-- "1990-12-31T15:59:60-08:00";
-- -- This represents the same leap second in Pacific Standard Time,
-- -- 8 hours behind UTC.
--
-- "1937-01-01T12:00:27.87+00:20"
--
-- ---------------------------------------------------------------------------------------------------
-- RFC2822 Section 3.3
--
-- Note: Support for most of the obsolete syntax elements is not
-- included here, and neither is support for comments within a datetime string.
-- Note: In the spec, FWS means "folded whitespace", and matches any
-- amount of whitespace, including none at all.
--
-- date-time = [ day-of-week "," ] date FWS time [CFWS]
-- day-of-week = ([FWS] day-name) / obs-day-of-week
-- day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
-- date = day month year
-- year = 4*DIGIT / obs-year
-- month = (FWS month-name FWS) / obs-month
-- month-name = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
-- "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
-- day = ([FWS] 1*2DIGIT) / obs-day
-- time = time-of-day FWS zone
-- time-of-day = hour ":" minute [ ":" second ]
-- hour = 2DIGIT / obs-hour
-- minute = 2DIGIT / obs-minute
-- second = 2DIGIT / obs-second
-- zone = (( "+" / "-" ) 4DIGIT) / obs-zone
alias numeric_zone_RFC2822 = { [+-] d d d d }
alias obsolete_zone_RFC2822 = "UTC" / "UT" / "GMT" / "CET" / "EST" / "EDT" /
"CST" / "CDT" / "MST" / "MDT" / "PST" / "PDT"
alias zone_RFC2822 = numeric_zone_RFC2822 / obsolete_zone_RFC2822
alias second_RFC2822 = {d d}
alias minute_RFC2822 = {d d}
alias hour_RFC2822 = d{1,2} -- NB: Relaxed to allow one digit
alias time_of_day_RFC2822 = { hour_RFC2822 ":" minute_RFC2822 {":" second_RFC2822}? }
datetime.time_RFC2822 = time_of_day_RFC2822 zone_RFC2822
alias day_RFC2822 = d{1,2}
alias month_RFC2822 = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
alias year_RFC2822 = fullyear
alias day_of_week_RFC2822 = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
-- strict defn of date is this:
-- date_RFC2822 = day_RFC2822 month_RFC2822 year_RFC2822
datetime.date_RFC2822 = { day_of_week_RFC2822 [:space:]* ","}? day_RFC2822 month_RFC2822 year_RFC2822
datetime.datetime_RFC2822 = datetime.date_RFC2822 datetime.time_RFC2822
--
-- Other formats
--
alias day_of_week_full = "Monday" / "Tuesday" / "Wednesday" / "Thursday" / "Friday" / "Saturday" / "Sunday"
alias day_of_week = (day_of_week_full / day_of_week_RFC2822)
alias month_name_full = "January" / "February" / "March" / "April" / "May" / "June" /
"July" / "August" / "September" / "October" / "November" / "December"
datetime.shortdate = (day_of_week ","?)? (month_name_full / month_RFC2822) day_RFC2822 ("," fullyear)?
alias ampm = "AM" / "am" / "PM" / "pm"
datetime.simple_time = { hour_RFC2822 ":" minute_RFC2822 {":" * second_RFC2822 {"." d+}?}? } ampm?
datetime.simple_date = month_RFC2822 {day_RFC2822 ","} year_RFC2822
datetime.simple_datetime = datetime.simple_date datetime.simple_time
datetime.ordinary_date = month_name_full {day_RFC2822 ","?} year_RFC2822
datetime.ordinary_datetime = datetime.ordinary_date (datetime.simple_time + datetime.time_RFC2822 + datetime.full_time_RFC3339)
datetime.slash_date = { date_mday "/" month_RFC2822 "/" year_RFC2822 }
datetime.slash_datetime = { datetime.slash_date ":" datetime.time_RFC2822 }
datetime.simple_slash_date = { d{1,2} "/" d{1,2} "/" {d{4,4} / d{2,2}} }
datetime.funny_time = { hour_RFC2822 ":" minute_RFC2822 ":" second_RFC2822 ":" common.int? } zone_RFC2822
datetime.funny_datetime = datetime.simple_slash_date datetime.funny_time -- seen in WebSphere logs
datetime.DB2_LRSN_datetime = { datetime.full_date_RFC3339 "-"
d d "." -- hour
d d "." -- min
d d "." -- sec
d+ } -- sequence number