34
35:- module(date,
36 [ date_time_value/3, 37 parse_time/2, 38 parse_time/3, 39 day_of_the_week/2, 40 day_of_the_year/2 41 ]).
61date_time_value(year, date(Y,_,_,_,_,_,_,_,_), Y).
62date_time_value(month, date(_,M,_,_,_,_,_,_,_), M).
63date_time_value(day, date(_,_,D,_,_,_,_,_,_), D).
64date_time_value(hour, date(_,_,_,H,_,_,_,_,_), H).
65date_time_value(minute, date(_,_,_,_,M,_,_,_,_), M).
66date_time_value(second, date(_,_,_,_,_,S,_,_,_), S).
67date_time_value(utc_offset, date(_,_,_,_,_,_,O,_,_), O).
68date_time_value(time_zone, date(_,_,_,_,_,_,_,Z,_), Z) :- Z \== (-).
69date_time_value(daylight_saving, date(_,_,_,_,_,_,_,_,D), D) :- D \== (-).
70
71date_time_value(date, date(Y,M,D,_,_,_,_,_,_), date(Y,M,D)).
72date_time_value(time, date(_,_,_,H,M,S,_,_,_), time(H,M,S)).
94parse_time(Text, Stamp) :-
95 parse_time(Text, _Format, Stamp).
96
97parse_time(Text, Format, Stamp) :-
98 atom_codes(Text, Codes),
99 phrase(date(Format, Y,Mon,D,H,Min,S,UTCOffset), Codes),
100 !,
101 date_time_stamp(date(Y,Mon,D,H,Min,S,UTCOffset,-,-), Stamp).
102
103date(iso_8601, Yr, Mon, D, H, Min, S, 0) --> 104 "-", date(iso_8601, Y, Mon, D, H, Min, S, 0),
105 { Yr is -1 * Y }.
106date(iso_8601, Y, Mon, D, H, Min, S, 0) -->
107 year(Y),
108 iso_8601_rest(Y, Mon, D, H, Min, S).
109date(rfc_1123, Y, Mon, D, Hr, Min, Sec, 0) --> 110 day_name(_), ", ", ws,
111 day_of_the_month(D), ws,
112 month_name(Mon), ws,
113 year(Y), ws,
114 hour(H), ":", minute(M), ":", second(S), ws,
115 timezone(DH, DM, DS),
116 { Hr is H + DH, Min is M + DM, Sec is S + DS }.
123iso_8601_rest(_, Mon, D, H, Min, S) -->
124 "-", month(Mon), "-", day(D),
125 opt_time(H, Min, S).
126iso_8601_rest(_, Mon, 0, 0, 0, 0) -->
127 "-", month(Mon).
128iso_8601_rest(_, Mon, D, H, Min, S) -->
129 month(Mon), day(D),
130 opt_time(H, Min, S).
131iso_8601_rest(_, 1, D, H, Min, S) -->
132 "-", ordinal(D),
133 opt_time(H, Min, S).
134iso_8601_rest(Yr, 1, D, H, Min, S) -->
135 "-W", week(W), "-", day_of_the_week(DW),
136 opt_time(H, Min, S),
137 { week_ordinal(Yr, W, DW, D) }.
138iso_8601_rest(Yr, 1, D, H, Min, S) -->
139 "W", week(W), day_of_the_week(DW),
140 opt_time(H, Min, S),
141 { week_ordinal(Yr, W, DW, D) }.
142iso_8601_rest(Yr, 1, D, 0, 0, 0) -->
143 "W", week(W),
144 { week_ordinal(Yr, W, 1, D) }.
145
146opt_time(Hr, Min, Sec) -->
147 ("T";" "), !, iso_time(Hr, Min, Sec).
148opt_time(0, 0, 0) --> "".
149
150
152iso_time(Hr, Min, Sec) -->
153 hour(H), ":", minute(M), ":", second(S),
154 timezone(DH, DM, DS),
155 { Hr is H + DH, Min is M + DM, Sec is S + DS }.
156iso_time(Hr, Min, Sec) -->
157 hour(H), ":", minute(M),
158 timezone(DH, DM, DS),
159 { Hr is H + DH, Min is M + DM, Sec is DS }.
160iso_time(Hr, Min, Sec) -->
161 hour(H), minute(M), second(S),
162 timezone(DH, DM, DS),
163 { Hr is H + DH, Min is M + DM, Sec is S + DS }.
164iso_time(Hr, Min, Sec) -->
165 hour(H), minute(M),
166 timezone(DH, DM, DS),
167 { Hr is H + DH, Min is M + DM, Sec is DS }.
168iso_time(Hr, Min, Sec) -->
169 hour(H),
170 timezone(DH, DM, DS),
171 { Hr is H + DH, Min is DM, Sec is DS }.
172
174timezone(Hr, Min, 0) -->
175 "+", hour(H), ":", minute(M), { Hr is -1 * H, Min is -1 * M }.
176timezone(Hr, Min, 0) -->
177 "+", hour(H), minute(M), { Hr is -1 * H, Min is -1 * M }.
178timezone(Hr, 0, 0) -->
179 "+", hour(H), { Hr is -1 * H }.
180timezone(Hr, Min, 0) -->
181 "-", hour(H), ":", minute(M), { Hr is H, Min is M }.
182timezone(Hr, Min, 0) -->
183 "-", hour(H), minute(M), { Hr is H, Min is M }.
184timezone(Hr, 0, 0) -->
185 "-", hour(H), { Hr is H }.
186timezone(0, 0, 0) -->
187 "Z".
188timezone(0, 0, 0) -->
189 ws, "UTC".
190timezone(0, 0, 0) -->
191 ws, "GMT". 192timezone(0, 0, 0) -->
193 [].
194
195day_name(0) --> "Sun".
196day_name(1) --> "Mon".
197day_name(2) --> "Tue".
198day_name(3) --> "Wed".
199day_name(4) --> "Thu".
200day_name(5) --> "Fri".
201day_name(6) --> "Sat".
202day_name(7) --> "Sun".
203
204month_name(1) --> "Jan".
205month_name(2) --> "Feb".
206month_name(3) --> "Mar".
207month_name(4) --> "Apr".
208month_name(5) --> "May".
209month_name(6) --> "Jun".
210month_name(7) --> "Jul".
211month_name(8) --> "Aug".
212month_name(9) --> "Sep".
213month_name(10) --> "Oct".
214month_name(11) --> "Nov".
215month_name(12) --> "Dec".
216
217day_of_the_month(N) --> int2digit(N), { between(1, 31, N) }.
218day_of_the_week(N) --> digit(N), { between(1, 7, N) }.
219month(M) --> int2digit(M), { between(1, 12, M) }.
220week(W) --> int2digit(W), { between(1, 53, W) }.
221day(D) --> int2digit(D), { between(1, 31, D) }.
222hour(N) --> int2digit(N), { between(0, 23, N) }.
223minute(N) --> int2digit(N), { between(0, 59, N) }.
224second(S) --> int2digit(N), { between(0, 60, N) }, 225 opt_fraction(N, S).
226
227opt_fraction(I, F) -->
228 ( "." ; "," ),
229 !,
230 digits(D),
231 { length(D, N),
232 N > 0,
233 number_codes(FP, D),
234 F is I + FP/(10^N)
235 }.
236opt_fraction(I, I) -->
237 [].
238
239int2digit(N) -->
240 digit(D0),
241 digit(D1),
242 { N is D0*10+D1 }.
243
244year(Y) -->
245 digit(D0),
246 digit(D1),
247 digit(D2),
248 digit(D3),
249 { Y is D0*1000+D1*100+D2*10+D3 }.
250
251ordinal(N) --> 252 digit(D0),
253 digit(D1),
254 digit(D2),
255 { N is D0*100+D1*10+D2, between(1, 366, N) }.
256
257digit(D) -->
258 [C],
259 { code_type(C, digit(D)) }.
260
261digits([C|T]) -->
262 [C],
263 { code_type(C, digit) },
264 !,
265 digits(T).
266digits([]) --> [].
267
268ws -->
269 " ",
270 !,
271 ws.
272ws -->
273 [].
283day_of_the_week(date(Year, Mon, Day), DotW) :-
284 format_time(atom(A), '%u', date(Year, Mon, Day, 0, 0, 0, 0, -, -)),
285 atom_number(A, DotW).
286
287week_ordinal(Year, Week, Day, Ordinal) :-
288 format_time(atom(A), '%w', date(Year, 1, 1, 0, 0, 0, 0, -, -)),
289 atom_number(A, DotW0),
290 Ordinal is ((Week-1) * 7) - DotW0 + Day + 1.
299day_of_the_year(date(Year, Mon, Day), DotY) :-
300 format_time(atom(A), '%j', date(Year, Mon, Day, 0, 0, 0, 0, -, -)),
301 atom_number(A, DotY)
Process dates and times
*/