KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jruby > RubyTime


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2001 Chad Fowler <chadfowler@chadfowler.com>
15  * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
16  * Copyright (C) 2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
17  * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
18  * Copyright (C) 2004 Joey Gibson <joey@joeygibson.com>
19  * Copyright (C) 2004 Charles O Nutter <headius@headius.com>
20  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
21  * Copyright (C) 2006 Thomas E Enebo <enebo@acm.org>
22  * Copyright (C) 2006 Ola Bini <ola.bini@ki.se>
23  * Copyright (C) 2006 Miguel Covarrubias <mlcovarrubias@gmail.com>
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * either of the GNU General Public License Version 2 or later (the "GPL"),
27  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28  * in which case the provisions of the GPL or the LGPL are applicable instead
29  * of those above. If you wish to allow use of your version of this file only
30  * under the terms of either the GPL or the LGPL, and not to allow others to
31  * use your version of this file under the terms of the CPL, indicate your
32  * decision by deleting the provisions above and replace them with the notice
33  * and other provisions required by the GPL or the LGPL. If you do not delete
34  * the provisions above, a recipient may use your version of this file under
35  * the terms of any one of the CPL, the GPL or the LGPL.
36  ***** END LICENSE BLOCK *****/

37 package org.jruby;
38
39 import java.text.SimpleDateFormat JavaDoc;
40 import java.util.Calendar JavaDoc;
41 import java.util.Date JavaDoc;
42 import java.util.Locale JavaDoc;
43 import java.util.Map JavaDoc;
44 import java.util.TimeZone JavaDoc;
45
46 import org.jruby.runtime.Block;
47 import org.jruby.runtime.builtin.IRubyObject;
48 import org.jruby.util.RubyDateFormat;
49 import org.jruby.util.ByteList;
50
51 /** The Time class.
52  *
53  * @author chadfowler, jpetersen
54  */

55 public class RubyTime extends RubyObject {
56     public static final String JavaDoc UTC = "UTC";
57     private Calendar JavaDoc cal;
58     private long usec;
59
60     private static final SimpleDateFormat JavaDoc simpleDateFormat = new SimpleDateFormat JavaDoc("-", Locale.US);
61
62     public static TimeZone JavaDoc getLocalTimeZone(Ruby runtime) {
63         // TODO: cache the RubyString "TZ" so it doesn't need to be recreated for each call?
64
RubyString tzVar = runtime.newString("TZ");
65         Map JavaDoc h = ((RubyHash)runtime.getObject().getConstant("ENV")).getValueMap();
66         IRubyObject tz = (IRubyObject)h.get(tzVar);
67         if (tz == null || ! (tz instanceof RubyString)) {
68             return TimeZone.getDefault();
69         } else {
70             return TimeZone.getTimeZone(tz.toString());
71         }
72     }
73     
74     public RubyTime(Ruby runtime, RubyClass rubyClass) {
75         super(runtime, rubyClass);
76     }
77     
78     public RubyTime(Ruby runtime, RubyClass rubyClass, Calendar JavaDoc cal) {
79         super(runtime, rubyClass);
80         this.cal = cal;
81     }
82     
83     public void setUSec(long usec) {
84         this.usec = usec;
85     }
86     
87     public void updateCal(Calendar JavaDoc calendar) {
88         calendar.setTimeZone(cal.getTimeZone());
89         calendar.setTimeInMillis(getTimeInMillis());
90     }
91     
92     protected long getTimeInMillis() {
93         return cal.getTimeInMillis(); // For JDK 1.4 we can use "cal.getTimeInMillis()"
94
}
95     
96     public static RubyTime newTime(Ruby runtime, long milliseconds) {
97         Calendar JavaDoc cal = Calendar.getInstance();
98         RubyTime time = new RubyTime(runtime, runtime.getClass("Time"), cal);
99         
100         cal.setTimeInMillis(milliseconds);
101         
102         return time;
103     }
104     
105     public static RubyTime newTime(Ruby runtime, Calendar JavaDoc cal) {
106         RubyTime time = new RubyTime(runtime, runtime.getClass("Time"), cal);
107         
108         return time;
109     }
110
111     public IRubyObject initialize_copy(IRubyObject original) {
112         if (!(original instanceof RubyTime)) {
113             throw getRuntime().newTypeError("Expecting an instance of class Time");
114         }
115         
116         RubyTime originalTime = (RubyTime) original;
117         
118         cal = originalTime.cal;
119         usec = originalTime.usec;
120         
121         return this;
122     }
123
124     public RubyTime succ() {
125         Calendar JavaDoc newCal = (Calendar JavaDoc)cal.clone();
126         newCal.add(Calendar.SECOND,1);
127         return newTime(getRuntime(),newCal);
128     }
129
130     public RubyTime gmtime() {
131         cal.setTimeZone(TimeZone.getTimeZone(UTC));
132         return this;
133     }
134
135     public RubyTime localtime() {
136         long dump = cal.getTimeInMillis();
137         cal = Calendar.getInstance(getLocalTimeZone(getRuntime()));
138         cal.setTimeInMillis(dump);
139         return this;
140     }
141     
142     public RubyBoolean gmt() {
143         return getRuntime().newBoolean(cal.getTimeZone().getID().equals(UTC));
144     }
145     
146     public RubyTime getgm() {
147         Calendar JavaDoc newCal = (Calendar JavaDoc)cal.clone();
148         newCal.setTimeZone(TimeZone.getTimeZone(UTC));
149         return newTime(getRuntime(), newCal);
150     }
151
152     public RubyTime getlocal() {
153         Calendar JavaDoc newCal = (Calendar JavaDoc)cal.clone();
154         newCal.setTimeZone(getLocalTimeZone(getRuntime()));
155         return newTime(getRuntime(), newCal);
156     }
157
158     public RubyString strftime(IRubyObject format) {
159         final RubyDateFormat rubyDateFormat = new RubyDateFormat("-", Locale.US);
160         rubyDateFormat.setCalendar(cal);
161         rubyDateFormat.applyPattern(format.toString());
162         String JavaDoc result = rubyDateFormat.format(cal.getTime());
163
164         return getRuntime().newString(result);
165     }
166     
167     public IRubyObject op_ge(IRubyObject other) {
168         if (other instanceof RubyTime) {
169             return getRuntime().newBoolean(cmp((RubyTime) other) >= 0);
170         }
171         
172         return RubyComparable.op_ge(this, other);
173     }
174     
175     public IRubyObject op_gt(IRubyObject other) {
176         if (other instanceof RubyTime) {
177             return getRuntime().newBoolean(cmp((RubyTime) other) > 0);
178         }
179         
180         return RubyComparable.op_gt(this, other);
181     }
182     
183     public IRubyObject op_le(IRubyObject other) {
184         if (other instanceof RubyTime) {
185             return getRuntime().newBoolean(cmp((RubyTime) other) <= 0);
186         }
187         
188         return RubyComparable.op_le(this, other);
189     }
190     
191     public IRubyObject op_lt(IRubyObject other) {
192         if (other instanceof RubyTime) {
193             return getRuntime().newBoolean(cmp((RubyTime) other) < 0);
194         }
195         
196         return RubyComparable.op_lt(this, other);
197     }
198     
199     private int cmp(RubyTime other) {
200         long millis = getTimeInMillis();
201         long millis_other = other.getTimeInMillis();
202         long usec_other = other.usec;
203         
204         if (millis > millis_other || (millis == millis_other && usec > usec_other)) {
205             return 1;
206         } else if (millis < millis_other || (millis == millis_other && usec < usec_other)) {
207             return -1;
208         }
209
210         return 0;
211     }
212     
213     public IRubyObject op_plus(IRubyObject other) {
214         long time = getTimeInMillis();
215
216         if (other instanceof RubyTime) {
217             throw getRuntime().newTypeError("time + time ?");
218         }
219         time += ((RubyNumeric) other).getDoubleValue() * 1000;
220
221         RubyTime newTime = new RubyTime(getRuntime(), getMetaClass());
222         newTime.cal = Calendar.getInstance();
223         newTime.cal.setTimeZone(cal.getTimeZone());
224         newTime.cal.setTime(new Date JavaDoc(time));
225
226         return newTime;
227     }
228
229     public IRubyObject op_minus(IRubyObject other) {
230         long time = getTimeInMillis();
231
232         if (other instanceof RubyTime) {
233             time -= ((RubyTime) other).getTimeInMillis();
234
235             return RubyFloat.newFloat(getRuntime(), time * 10e-4);
236         }
237         time -= ((RubyNumeric) other).getDoubleValue() * 1000;
238
239         RubyTime newTime = new RubyTime(getRuntime(), getMetaClass());
240         newTime.cal = Calendar.getInstance();
241         newTime.cal.setTimeZone(cal.getTimeZone());
242         newTime.cal.setTime(new Date JavaDoc(time));
243
244         return newTime;
245     }
246
247     public IRubyObject same2(IRubyObject other) {
248         return (RubyNumeric.fix2int(callMethod(getRuntime().getCurrentContext(), "<=>", other)) == 0) ? getRuntime().getTrue() : getRuntime().getFalse();
249     }
250
251     public IRubyObject op_cmp(IRubyObject other) {
252         if (other.isNil()) {
253             return other;
254         }
255         
256         if (other instanceof RubyTime) {
257             return getRuntime().newFixnum(cmp((RubyTime) other));
258         }
259         
260         long millis = getTimeInMillis();
261
262         if(other instanceof RubyNumeric) {
263             if (other instanceof RubyFloat || other instanceof RubyBignum) {
264                 double time = millis / 1000.0;
265
266                 double time_other = ((RubyNumeric) other).getDoubleValue();
267
268                 if (time > time_other) {
269                     return RubyFixnum.one(getRuntime());
270                 } else if (time < time_other) {
271                     return RubyFixnum.minus_one(getRuntime());
272                 }
273
274                 return RubyFixnum.zero(getRuntime());
275             }
276             long millis_other = RubyNumeric.num2long(other) * 1000;
277
278             if (millis > millis_other || (millis == millis_other && usec > 0)) {
279                 return RubyFixnum.one(getRuntime());
280             } else if (millis < millis_other || (millis == millis_other && usec < 0)) {
281                 return RubyFixnum.minus_one(getRuntime());
282             }
283
284             return RubyFixnum.zero(getRuntime());
285         }
286         return getRuntime().getNil();
287     }
288
289     public RubyString asctime() {
290         simpleDateFormat.setCalendar(cal);
291         simpleDateFormat.applyPattern("EEE MMM dd HH:mm:ss yyyy");
292         String JavaDoc result = simpleDateFormat.format(cal.getTime());
293
294         return getRuntime().newString(result);
295     }
296
297     public IRubyObject to_s() {
298         simpleDateFormat.setCalendar(cal);
299         simpleDateFormat.applyPattern("EEE MMM dd HH:mm:ss z yyyy");
300         String JavaDoc result = simpleDateFormat.format(cal.getTime());
301
302         return getRuntime().newString(result);
303     }
304
305     public RubyArray to_a() {
306         return getRuntime().newArrayNoCopy(new IRubyObject[] { sec(), min(), hour(), mday(), month(),
307                 year(), wday(), yday(), isdst(), zone() });
308     }
309
310     public RubyFloat to_f() {
311         return RubyFloat.newFloat(getRuntime(), getTimeInMillis() / 1000 + microseconds() / 1000000.0);
312     }
313
314     public RubyInteger to_i() {
315         return getRuntime().newFixnum(getTimeInMillis() / 1000);
316     }
317
318     public RubyInteger usec() {
319         return getRuntime().newFixnum(microseconds());
320     }
321     
322     public void setMicroseconds(long mic) {
323         long millis = getTimeInMillis() % 1000;
324         long withoutMillis = getTimeInMillis() - millis;
325         withoutMillis += (mic / 1000);
326         cal.setTimeInMillis(withoutMillis);
327         usec = mic % 1000;
328     }
329     
330     public long microseconds() {
331         return getTimeInMillis() % 1000 * 1000 + usec;
332     }
333
334     public RubyInteger sec() {
335         return getRuntime().newFixnum(cal.get(Calendar.SECOND));
336     }
337
338     public RubyInteger min() {
339         return getRuntime().newFixnum(cal.get(Calendar.MINUTE));
340     }
341
342     public RubyInteger hour() {
343         return getRuntime().newFixnum(cal.get(Calendar.HOUR_OF_DAY));
344     }
345
346     public RubyInteger mday() {
347         return getRuntime().newFixnum(cal.get(Calendar.DAY_OF_MONTH));
348     }
349
350     public RubyInteger month() {
351         return getRuntime().newFixnum(cal.get(Calendar.MONTH) + 1);
352     }
353
354     public RubyInteger year() {
355         return getRuntime().newFixnum(cal.get(Calendar.YEAR));
356     }
357
358     public RubyInteger wday() {
359         return getRuntime().newFixnum(cal.get(Calendar.DAY_OF_WEEK) - 1);
360     }
361
362     public RubyInteger yday() {
363         return getRuntime().newFixnum(cal.get(Calendar.DAY_OF_YEAR));
364     }
365
366     public RubyInteger gmt_offset() {
367         return getRuntime().newFixnum((int)(cal.get(Calendar.ZONE_OFFSET)/1000));
368     }
369     
370     public RubyBoolean isdst() {
371         return getRuntime().newBoolean(cal.getTimeZone().inDaylightTime(cal.getTime()));
372     }
373
374     public RubyString zone() {
375         return getRuntime().newString(cal.getTimeZone().getID());
376     }
377
378     public void setJavaCalendar(Calendar JavaDoc cal) {
379         this.cal = cal;
380     }
381
382     public Date JavaDoc getJavaDate() {
383         return this.cal.getTime();
384     }
385
386     public RubyFixnum hash() {
387         // modified to match how hash is calculated in 1.8.2
388
return getRuntime().newFixnum((int)(((cal.getTimeInMillis() / 1000) ^ microseconds()) << 1) >> 1);
389     }
390
391     public RubyString dump(final IRubyObject[] args, Block unusedBlock) {
392         if (args.length > 1) {
393             throw getRuntime().newArgumentError(0, 1);
394         }
395
396         return (RubyString) mdump(new IRubyObject[] { this });
397     }
398
399     public RubyObject mdump(final IRubyObject[] args) {
400         RubyTime obj = (RubyTime)args[0];
401         Calendar JavaDoc calendar = obj.gmtime().cal;
402         byte dumpValue[] = new byte[8];
403         int pe =
404             0x1 << 31 |
405             (calendar.get(Calendar.YEAR)-1900) << 14 |
406             calendar.get(Calendar.MONTH) << 10 |
407             calendar.get(Calendar.DAY_OF_MONTH) << 5 |
408             calendar.get(Calendar.HOUR_OF_DAY);
409         int se =
410             calendar.get(Calendar.MINUTE) << 26 |
411             calendar.get(Calendar.SECOND) << 20 |
412             calendar.get(Calendar.MILLISECOND);
413
414         for(int i = 0; i < 4; i++) {
415             dumpValue[i] = (byte)(pe & 0xFF);
416             pe >>>= 8;
417         }
418         for(int i = 4; i < 8 ;i++) {
419             dumpValue[i] = (byte)(se & 0xFF);
420             se >>>= 8;
421         }
422         return RubyString.newString(obj.getRuntime(), new ByteList(dumpValue,false));
423     }
424 }
425
Popular Tags