2456
|
1 /* |
|
2 |
|
3 Copyright (C) 1996 John W. Eaton |
|
4 |
|
5 This file is part of Octave. |
|
6 |
|
7 Octave is free software; you can redistribute it and/or modify it |
|
8 under the terms of the GNU General Public License as published by the |
|
9 Free Software Foundation; either version 2, or (at your option) any |
|
10 later version. |
|
11 |
|
12 Octave is distributed in the hope that it will be useful, but WITHOUT |
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
15 for more details. |
|
16 |
|
17 You should have received a copy of the GNU General Public License |
|
18 along with Octave; see the file COPYING. If not, write to the Free |
|
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
20 |
|
21 */ |
|
22 |
|
23 #ifdef HAVE_CONFIG_H |
|
24 #include <config.h> |
|
25 #endif |
|
26 |
|
27 #include <string> |
|
28 |
2457
|
29 #include "defun-dld.h" |
2456
|
30 #include "error.h" |
|
31 #include "help.h" |
|
32 #include "oct-map.h" |
|
33 #include "systime.h" |
|
34 #include "ov.h" |
|
35 #include "oct-obj.h" |
|
36 #include "utils.h" |
|
37 |
|
38 // Date and time functions. |
|
39 |
|
40 static Octave_map |
|
41 mk_tm_map (struct tm *tm, double fraction) |
|
42 { |
|
43 Octave_map m; |
|
44 |
|
45 m ["usec"] = fraction * 1e6; |
|
46 m ["sec"] = (double) tm->tm_sec; |
|
47 m ["min"] = (double) tm->tm_min; |
|
48 m ["hour"] = (double) tm->tm_hour; |
|
49 m ["mday"] = (double) tm->tm_mday; |
|
50 m ["mon"] = (double) tm->tm_mon; |
|
51 m ["year"] = (double) tm->tm_year; |
|
52 m ["wday"] = (double) tm->tm_wday; |
|
53 m ["yday"] = (double) tm->tm_yday; |
|
54 m ["isdst"] = (double) tm->tm_isdst; |
|
55 #if defined (HAVE_TM_ZONE) |
|
56 m ["zone"] = tm->tm_zone; |
|
57 #elif defined (HAVE_TZNAME) |
|
58 if (tm->tm_isdst && tzname[1] && *tzname[1]) |
|
59 m ["zone"] = tzname[1]; |
|
60 else |
|
61 m ["zone"] = tzname[0]; |
|
62 #else |
|
63 m ["zone"] = zone_name (tm); |
|
64 #endif |
|
65 |
|
66 return m; |
|
67 } |
|
68 |
|
69 static struct tm* |
|
70 extract_tm (Octave_map &m, double& fraction) |
|
71 { |
|
72 static struct tm tm; |
|
73 |
|
74 fraction = (m ["usec"] . double_value ()) / 1e6; |
|
75 tm.tm_sec = NINT (m ["sec"] . double_value ()); |
|
76 tm.tm_min = NINT (m ["min"] . double_value ()); |
|
77 tm.tm_hour = NINT (m ["hour"] . double_value ()); |
|
78 tm.tm_mday = NINT (m ["mday"] . double_value ()); |
|
79 tm.tm_mon = NINT (m ["mon"] . double_value ()); |
|
80 tm.tm_year = NINT (m ["year"] . double_value ()); |
|
81 tm.tm_wday = NINT (m ["wday"] . double_value ()); |
|
82 tm.tm_yday = NINT (m ["yday"] . double_value ()); |
|
83 tm.tm_isdst = NINT (m ["isdst"] . double_value ()); |
|
84 #ifdef HAVE_TMZONE |
|
85 string tstr = m ["zone"] . string_value (); |
|
86 tm.tm_zone = tstr.c_str (); |
|
87 #endif |
|
88 |
|
89 return &tm; |
|
90 } |
|
91 |
2465
|
92 DEFUN_DLD (time, , , |
2456
|
93 "time ()\n\ |
|
94 \n\ |
2459
|
95 Return current time. On Unix systems, this is the number of\n\ |
|
96 seconds since the epoch.") |
2456
|
97 { |
|
98 time_t now; |
|
99 double fraction = 0.0; |
|
100 |
|
101 #ifdef HAVE_GETTIMEOFDAY |
|
102 |
|
103 struct timeval tp; |
|
104 |
|
105 #ifdef GETTIMEOFDAY_NO_TZ |
|
106 gettimeofday (&tp); |
|
107 #else |
|
108 gettimeofday (&tp, 0); |
|
109 #endif |
|
110 |
|
111 now = tp.tv_sec; |
|
112 |
|
113 fraction = tp.tv_usec / 1e6; |
|
114 |
|
115 #else |
|
116 |
|
117 now = time (0); |
|
118 |
|
119 #endif |
|
120 |
|
121 return (double) now + fraction; |
|
122 } |
|
123 |
2465
|
124 DEFUN_DLD (gmtime, args, , |
2456
|
125 "gmtime (TIME)\n\ |
|
126 \n\ |
2459
|
127 Given a value returned from time(), return a structure like that\n\ |
|
128 returned from localtime() but with values corresponding to\n\ |
|
129 Coordinated Universal Time (UTC).") |
2456
|
130 { |
|
131 octave_value_list retval; |
|
132 |
|
133 if (args.length () == 1) |
|
134 { |
|
135 double tmp = args(0).double_value (); |
|
136 |
|
137 if (! error_state) |
|
138 { |
|
139 time_t timeval = NINT (tmp); |
|
140 double ip; |
|
141 double fraction = modf (tmp, &ip); |
|
142 |
|
143 retval = octave_value (mk_tm_map (gmtime (&timeval), fraction)); |
|
144 } |
|
145 } |
|
146 else |
|
147 print_usage ("gmtime"); |
|
148 |
|
149 return retval; |
|
150 } |
|
151 |
2465
|
152 DEFUN_DLD (localtime, args, , |
2456
|
153 "localtime (TIME)\n\ |
|
154 \n\ |
2459
|
155 Given a value returned from time(), return a structure with\n\ |
|
156 the following elements:\n\ |
2456
|
157 \n\ |
2459
|
158 usec : microseconds after the second (0, 999999)\n\ |
|
159 sec : seconds after the minute (0, 61)\n\ |
|
160 min : minutes after the hour (0, 59)\n\ |
|
161 hour : hours since midnight (0, 23)\n\ |
|
162 mday : day of the month (1, 31)\n\ |
|
163 mon : months since January (0, 11)\n\ |
|
164 year : years since 1900\n\ |
|
165 wday : days since Sunday (0, 6)\n\ |
|
166 yday : days since January 1 (0, 365)\n\ |
|
167 isdst : Daylight Savings Time flag\n\ |
|
168 zone : Time zone") |
2456
|
169 { |
|
170 octave_value_list retval; |
|
171 |
|
172 if (args.length () == 1) |
|
173 { |
|
174 double tmp = args(0).double_value (); |
|
175 |
|
176 if (! error_state) |
|
177 { |
|
178 time_t timeval = NINT (tmp); |
|
179 double ip; |
|
180 double fraction = modf (tmp, &ip); |
|
181 |
|
182 retval = octave_value (mk_tm_map (localtime (&timeval), fraction)); |
|
183 } |
|
184 } |
|
185 else |
|
186 print_usage ("localtime"); |
|
187 |
|
188 return retval; |
|
189 } |
|
190 |
2465
|
191 DEFUN_DLD (mktime, args, , |
2456
|
192 "mktime (TMSTRUCT)") |
|
193 { |
|
194 octave_value_list retval; |
|
195 |
|
196 if (args.length () == 1 && args(0).is_map ()) |
|
197 { |
|
198 Octave_map map = args(0).map_value (); |
|
199 |
|
200 double fraction; |
|
201 |
|
202 struct tm *tm = extract_tm (map, fraction); |
|
203 |
|
204 if (! error_state) |
|
205 retval = (double) mktime (tm) + fraction; |
|
206 } |
|
207 else |
|
208 print_usage ("mktime"); |
|
209 |
|
210 return retval; |
|
211 } |
|
212 |
2465
|
213 DEFUN_DLD (strftime, args, , |
2456
|
214 "strftime (FMT, TMSTRUCT)\n\ |
|
215 \n\ |
2459
|
216 Performs `%' substitutions similar to those in printf. Except where\n\ |
|
217 noted, substituted fields have a fixed size; numeric fields are\n\ |
|
218 padded if necessary. Padding is with zeros by default; for fields\n\ |
|
219 that display a single number, padding can be changed or inhibited by\n\ |
|
220 following the `%' with one of the modifiers described below.\n\ |
|
221 Unknown field specifiers are copied as normal characters. All other\n\ |
|
222 characters are copied to the output without change.\n\ |
2456
|
223 \n\ |
2459
|
224 Supports a superset of the ANSI C field specifiers.\n\ |
2456
|
225 \n\ |
2459
|
226 Literal character fields:\n\ |
2456
|
227 \n\ |
2459
|
228 % %\n\ |
|
229 n newline\n\ |
|
230 t tab\n\ |
2456
|
231 \n\ |
2459
|
232 Numeric modifiers (a nonstandard extension):\n\ |
2456
|
233 \n\ |
2459
|
234 - do not pad the field\n\ |
|
235 _ pad the field with spaces\n\ |
2456
|
236 \n\ |
2459
|
237 Time fields:\n\ |
2456
|
238 \n\ |
2459
|
239 %H hour (00..23)\n\ |
|
240 %I hour (01..12)\n\ |
|
241 %k hour ( 0..23)\n\ |
|
242 %l hour ( 1..12)\n\ |
|
243 %M minute (00..59)\n\ |
|
244 %p locale's AM or PM\n\ |
|
245 %r time, 12-hour (hh:mm:ss [AP]M)\n\ |
|
246 %R time, 24-hour (hh:mm)\n\ |
|
247 %s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension)\n\ |
|
248 %S second (00..61)\n\ |
|
249 %T time, 24-hour (hh:mm:ss)\n\ |
|
250 %X locale's time representation (%H:%M:%S)\n\ |
|
251 %Z time zone (EDT), or nothing if no time zone is determinable\n\ |
2456
|
252 \n\ |
2459
|
253 Date fields:\n\ |
2456
|
254 \n\ |
2459
|
255 %a locale's abbreviated weekday name (Sun..Sat)\n\ |
|
256 %A locale's full weekday name, variable length (Sunday..Saturday)\n\ |
|
257 %b locale's abbreviated month name (Jan..Dec)\n\ |
|
258 %B locale's full month name, variable length (January..December)\n\ |
|
259 %c locale's date and time (Sat Nov 04 12:02:33 EST 1989)\n\ |
|
260 %C century (00..99)\n\ |
|
261 %d day of month (01..31)\n\ |
|
262 %e day of month ( 1..31)\n\ |
|
263 %D date (mm/dd/yy)\n\ |
|
264 %h same as %b\n\ |
|
265 %j day of year (001..366)\n\ |
|
266 %m month (01..12)\n\ |
|
267 %U week number of year with Sunday as first day of week (00..53)\n\ |
|
268 %w day of week (0..6)\n\ |
|
269 %W week number of year with Monday as first day of week (00..53)\n\ |
|
270 %x locale's date representation (mm/dd/yy)\n\ |
|
271 %y last two digits of year (00..99)\n\ |
|
272 %Y year (1970...)") |
2456
|
273 { |
|
274 octave_value_list retval; |
|
275 |
|
276 if (args.length () == 2 && args(0).is_string () && args(1).is_map ()) |
|
277 { |
|
278 string fmt = args(0).string_value (); |
|
279 |
|
280 Octave_map map = args(1).map_value (); |
|
281 |
|
282 double fraction; |
|
283 |
|
284 struct tm *tm = extract_tm (map, fraction); |
|
285 |
|
286 if (! error_state) |
|
287 { |
|
288 int bufsize = 128; |
|
289 char *buf = new char [bufsize]; |
|
290 |
|
291 while (! strftime (buf, bufsize, fmt.c_str (), tm)) |
|
292 { |
|
293 delete [] buf; |
|
294 bufsize *= 2; |
|
295 buf = new char [bufsize]; |
|
296 } |
|
297 |
|
298 retval = buf; |
|
299 |
|
300 delete [] buf; |
|
301 } |
|
302 } |
|
303 else |
|
304 print_usage ("strftime"); |
|
305 |
|
306 return retval; |
|
307 } |
|
308 |
|
309 /* |
|
310 ;;; Local Variables: *** |
|
311 ;;; mode: C++ *** |
|
312 ;;; End: *** |
|
313 */ |