contrib/jwrapper: refactor some duplicated code
[nit.git] / lib / standard / time.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2008 Floréal Morandat <morandat@lirmm.fr>
4 # Copyright 2014 Alexandre Terrasa <alexandre@moz-code.org>
5 #
6 # This file is free software, which comes along with NIT. This software is
7 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
9 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
10 # is kept unaltered, and a notification of the changes is added.
11 # You are allowed to redistribute it and sell it, alone or is a part of
12 # another product.
13
14 # Management of time and dates
15 module time
16
17 import string_search
18 import stream
19
20 in "C Header" `{
21 #include <time.h>
22 `}
23
24 redef class Object
25 # Unix time: the number of seconds elapsed since January 1, 1970
26 protected fun get_time: Int is extern "kernel_Any_Any_get_time_0"
27 end
28
29 redef class Sys
30 # Wait a specific number of second and nanoseconds
31 fun nanosleep(sec, nanosec: Int) is extern "std_nanosleep"
32 end
33
34 # Time since epoch
35 extern class TimeT `{time_t`}
36
37 # Returns Time since epoch from now.
38 new `{ return time(NULL); `}
39
40 # Returns Time since epoch from `i` (expressed in seconds).
41 new from_i(i: Int) `{ return i; `}
42
43 # Update current time.
44 fun update `{ time(&recv); `}
45
46 # Convert `self` to a human readable String.
47 fun ctime: String import NativeString.to_s_with_copy `{
48 return NativeString_to_s_with_copy( ctime(&recv) );
49 `}
50
51 # Difference in secondes from start (self if the end time)
52 fun difftime(start: TimeT): Float `{ return difftime(recv, start); `}
53
54 redef fun to_s do return ctime.replace("\n", "")
55
56 # Convert self to Int (expressed as seconds since epoch).
57 fun to_i: Int `{ return (int)recv; `}
58 end
59
60 # Time structure
61 extern class Tm `{struct tm *`}
62
63 # Create a new Time structure expressed in Coordinated Universal Time (UTC).
64 new gmtime `{
65 struct tm *tm;
66 time_t t = time(NULL);
67 tm = gmtime(&t);
68 return tm;
69 `}
70
71 # Create a new Time structure expressed in UTC from `t`.
72 new gmtime_from_timet(t: TimeT) `{
73 struct tm *tm;
74 tm = gmtime(&t);
75 return tm;
76 `}
77
78 # Create a new Time structure expressed in the local timezone.
79 new localtime `{
80 struct tm *tm;
81 time_t t = time(NULL);
82 tm = localtime(&t);
83 return tm;
84 `}
85
86 # Create a new Time structure expressed in the local timezone from `t`.
87 new localtime_from_timet(t: TimeT) `{
88 struct tm *tm;
89 tm = localtime(&t);
90 return tm;
91 `}
92
93 # Convert `self` as a TimeT.
94 fun to_timet: TimeT `{ return mktime(recv); `}
95
96 # Seconds after the minute.
97 fun sec: Int `{ return recv->tm_sec; `}
98
99 # Minutes after the hour.
100 fun min: Int `{ return recv->tm_min; `}
101
102 # hours since midnight.
103 fun hour: Int `{ return recv->tm_hour; `}
104
105 # Day of the month.
106 fun mday: Int `{ return recv->tm_mday; `}
107
108 # Months since January.
109 fun mon: Int `{ return recv->tm_mon; `}
110
111 # Years since 1900.
112 fun year: Int `{ return recv->tm_year; `}
113
114 # Days since Sunday.
115 fun wday: Int `{ return recv->tm_wday; `}
116
117 # Days since January 1st.
118 fun yday: Int `{ return recv->tm_yday; `}
119
120 # Is `self` in Daylight Saving Time.
121 fun is_dst: Bool `{ return recv->tm_isdst; `}
122
123 # Convert `self` to a human readable String.
124 fun asctime: String import NativeString.to_s_with_copy `{
125 return NativeString_to_s_with_copy( asctime(recv) );
126 `}
127
128 # Convert `self` to a human readable String corresponding to `format`.
129 # TODO document allowed format.
130 fun strftime(format: String): String import String.to_cstring, NativeString.to_s `{
131 char* buf, *c_format;
132 size_t res;
133
134 buf = (char*)malloc(100);
135 c_format = String_to_cstring(format);
136
137 res = strftime(buf, 100, c_format, recv);
138 return NativeString_to_s(buf);
139 `}
140
141 redef fun to_s do return asctime.replace("\n", "")
142 end
143
144 # Date using the international format defined by ISO 8601.
145 #
146 # Usage:
147 #
148 # # By default ISODate at today.
149 # var date = new ISODate
150 # var tm = new Tm.localtime
151 # assert date.year == tm.year + 1900
152 # assert date.month == tm.mon + 1
153 # assert date.day == tm.mday
154 #
155 # # ISODate can be initialized from a String.
156 # date = new ISODate.from_string("1970-01-01T00:00:00Z")
157 # assert date.year == 1970
158 # assert date.month == 1
159 # assert date.day == 1
160 #
161 # # ISODate can be printed as String following the ISO format.
162 # assert date.to_s == "1970-01-01T00:00:00Z"
163 #
164 # Note that only the `YYYY-MM-DDTHH:MM:SSZ` is supported for now.
165 #
166 # See <http://www.w3.org/QA/Tips/iso-date>
167 class ISODate
168 super Comparable
169
170 # UTC years as Int.
171 var year: Int is noinit
172
173 # UTC months as Int (`1` for January).
174 var month: Int is noinit
175
176 # UTC days as Int (starting at `1`).
177 var day: Int is noinit
178
179 # UTC hours as Int.
180 var hours: Int is noinit
181
182 # UTC minutes as Int.
183 var minutes: Int is noinit
184
185 # UTC seconds as Int.
186 var seconds: Int is noinit
187
188 # UTC timezone marker.
189 #
190 # Note that I don't know what will happen if you change this value...
191 var timezone = "Z"
192
193 init do
194 var t = new Tm.localtime
195 year = 1900 + t.year
196 month = t.mon + 1
197 day = t.mday
198 hours = t.hour
199 minutes = t.min
200 seconds = t.sec
201 end
202
203 # Init `self` from a ISODate formatted string.
204 init from_string(str: String) do
205 year = str.substring(0, 4).to_i
206 month = str.substring(5, 2).to_i
207 day = str.substring(8, 2).to_i
208 hours = str.substring(11, 2).to_i
209 minutes = str.substring(14, 2).to_i
210 seconds = str.substring(17, 2).to_i
211 timezone = str.substring(19, str.length)
212 end
213
214 redef fun to_s do
215 var buff = new FlatBuffer
216 buff.append year.to_s
217 buff.add '-'
218 if month < 10 then buff.add '0'
219 buff.append month.to_s
220 buff.add '-'
221 if day < 10 then buff.add '0'
222 buff.append day.to_s
223 buff.add 'T'
224 if hours < 10 then buff.add '0'
225 buff.append hours.to_s
226 buff.add ':'
227 if minutes < 10 then buff.add '0'
228 buff.append minutes.to_s
229 buff.add ':'
230 if seconds < 10 then buff.add '0'
231 buff.append seconds.to_s
232 buff.append timezone
233 return buff.write_to_string
234 end
235
236 redef type OTHER: ISODate
237
238 # TODO handle timezones
239 redef fun <(o) do return to_s < o.to_s
240 end