001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.util;
019:
020: import java.io.IOException;
021: import java.io.ObjectInputStream;
022: import java.io.ObjectOutputStream;
023: import java.io.Serializable;
024: import java.text.DateFormat;
025: import java.text.DateFormatSymbols;
026: import java.text.SimpleDateFormat;
027:
028: import org.apache.harmony.luni.internal.nls.Messages;
029:
030: /**
031: * Date represents a specific moment in time, to the millisecond.
032: *
033: * @see System#currentTimeMillis
034: * @see Calendar
035: * @see GregorianCalendar
036: * @see SimpleTimeZone
037: * @see TimeZone
038: */
039: public class Date implements Serializable, Cloneable, Comparable<Date> {
040:
041: private static final long serialVersionUID = 7523967970034938905L;
042:
043: // Used by parse()
044: private static int creationYear = new Date().getYear();
045:
046: private transient long milliseconds;
047:
048: /**
049: * Initializes this Date instance to the current date and time.
050: *
051: */
052: public Date() {
053: this (System.currentTimeMillis());
054: }
055:
056: /**
057: * Constructs a new Date initialized to midnight in the default TimeZone on
058: * the specified date.
059: *
060: * @param year
061: * the year, 0 is 1900
062: * @param month
063: * the month, 0 - 11
064: * @param day
065: * the day of the month, 1 - 31
066: *
067: * @deprecated use GregorianCalendar(int, int, int)
068: */
069: @Deprecated
070: public Date(int year, int month, int day) {
071: GregorianCalendar cal = new GregorianCalendar(false);
072: cal.set(1900 + year, month, day);
073: milliseconds = cal.getTimeInMillis();
074: }
075:
076: /**
077: * Constructs a new Date initialized to the specified date and time in the
078: * default TimeZone.
079: *
080: * @param year
081: * the year, 0 is 1900
082: * @param month
083: * the month, 0 - 11
084: * @param day
085: * the day of the month, 1 - 31
086: * @param hour
087: * the hour of day, 0 - 23
088: * @param minute
089: * the minute of the hour, 0 - 59
090: *
091: * @deprecated use GregorianCalendar(int, int, int, int, int)
092: */
093: @Deprecated
094: public Date(int year, int month, int day, int hour, int minute) {
095: GregorianCalendar cal = new GregorianCalendar(false);
096: cal.set(1900 + year, month, day, hour, minute);
097: milliseconds = cal.getTimeInMillis();
098: }
099:
100: /**
101: * Constructs a new Date initialized to the specified date and time in the
102: * default TimeZone.
103: *
104: * @param year
105: * the year, 0 is 1900
106: * @param month
107: * the month, 0 - 11
108: * @param day
109: * the day of the month, 1 - 31
110: * @param hour
111: * the hour of day, 0 - 23
112: * @param minute
113: * the minute of the hour, 0 - 59
114: * @param second
115: * the second of the minute, 0 - 59
116: *
117: * @deprecated use GregorianCalendar(int, int, int, int, int, int)
118: */
119: @Deprecated
120: public Date(int year, int month, int day, int hour, int minute,
121: int second) {
122: GregorianCalendar cal = new GregorianCalendar(false);
123: cal.set(1900 + year, month, day, hour, minute, second);
124: milliseconds = cal.getTimeInMillis();
125: }
126:
127: /**
128: * Initializes this Date instance using the specified millisecond value. The
129: * value is the number of milliseconds since Jan. 1, 1970 GMT.
130: *
131: * @param milliseconds
132: * the number of milliseconds since Jan. 1, 1970 GMT
133: */
134: public Date(long milliseconds) {
135: this .setTime(milliseconds);
136: }
137:
138: /**
139: * Constructs a new Date initialized to the date and time parsed from the
140: * specified String.
141: *
142: * @param string
143: * the String to parse
144: *
145: * @deprecated use DateFormat
146: */
147: @Deprecated
148: public Date(String string) {
149: milliseconds = parse(string);
150: }
151:
152: /**
153: * Answers if this Date is after the specified Date.
154: *
155: * @param date
156: * a Date instance to compare
157: * @return true if this Date is after the specified Date, false otherwise
158: */
159: public boolean after(Date date) {
160: return milliseconds > date.milliseconds;
161: }
162:
163: /**
164: * Boolean indication of whether or not this <code>Date</code> occurs
165: * earlier than the <code>Date</code> argument.
166: *
167: * @param date
168: * a Date instance to compare
169: * @return <code>true</code> if this <code>Date</code> occurs earlier
170: * than <code>date</code>, otherwise <code>false</code>
171: */
172: public boolean before(Date date) {
173: return milliseconds < date.milliseconds;
174: }
175:
176: /**
177: * Answers a new Date with the same millisecond value as this Date.
178: *
179: * @return a shallow copy of this Date
180: *
181: * @see java.lang.Cloneable
182: */
183: @Override
184: public Object clone() {
185: try {
186: return super .clone();
187: } catch (CloneNotSupportedException e) {
188: return null;
189: }
190: }
191:
192: /**
193: * Compare the receiver to the specified Date to determine the relative
194: * ordering.
195: *
196: * @param date
197: * a Date
198: * @return an int < 0 if this Date is less than the specified Date, 0 if
199: * they are equal, and > 0 if this Date is greater
200: */
201: public int compareTo(Date date) {
202: if (milliseconds < date.milliseconds) {
203: return -1;
204: }
205: if (milliseconds == date.milliseconds) {
206: return 0;
207: }
208: return 1;
209: }
210:
211: /**
212: * Compares the specified object to this Date and answer if they are equal.
213: * The object must be an instance of Date and have the same millisecond
214: * value.
215: *
216: * @param object
217: * the object to compare with this object
218: * @return true if the specified object is equal to this Date, false
219: * otherwise
220: *
221: * @see #hashCode
222: */
223: @Override
224: public boolean equals(Object object) {
225: return (object == this ) || (object instanceof Date)
226: && (milliseconds == ((Date) object).milliseconds);
227: }
228:
229: /**
230: * Answers the gregorian calendar day of the month for this Date object.
231: *
232: * @return the day of the month
233: *
234: * @deprecated use Calendar.get(Calendar.DATE)
235: */
236: @Deprecated
237: public int getDate() {
238: return new GregorianCalendar(milliseconds).get(Calendar.DATE);
239: }
240:
241: /**
242: * Answers the gregorian calendar day of the week for this Date object.
243: *
244: * @return the day of the week
245: *
246: * @deprecated use Calendar.get(Calendar.DAY_OF_WEEK)
247: */
248: @Deprecated
249: public int getDay() {
250: return new GregorianCalendar(milliseconds)
251: .get(Calendar.DAY_OF_WEEK) - 1;
252: }
253:
254: /**
255: * Answers the gregorian calendar hour of the day for this Date object.
256: *
257: * @return the hour of the day
258: *
259: * @deprecated use Calendar.get(Calendar.HOUR_OF_DAY)
260: */
261: @Deprecated
262: public int getHours() {
263: return new GregorianCalendar(milliseconds)
264: .get(Calendar.HOUR_OF_DAY);
265: }
266:
267: /**
268: * Answers the gregorian calendar minute of the hour for this Date object.
269: *
270: * @return the minutes
271: *
272: * @deprecated use Calendar.get(Calendar.MINUTE)
273: */
274: @Deprecated
275: public int getMinutes() {
276: return new GregorianCalendar(milliseconds).get(Calendar.MINUTE);
277: }
278:
279: /**
280: * Answers the gregorian calendar month for this Date object.
281: *
282: * @return the month
283: *
284: * @deprecated use Calendar.get(Calendar.MONTH)
285: */
286: @Deprecated
287: public int getMonth() {
288: return new GregorianCalendar(milliseconds).get(Calendar.MONTH);
289: }
290:
291: /**
292: * Answers the gregorian calendar second of the minute for this Date object.
293: *
294: * @return the seconds
295: *
296: * @deprecated use Calendar.get(Calendar.SECOND)
297: */
298: @Deprecated
299: public int getSeconds() {
300: return new GregorianCalendar(milliseconds).get(Calendar.SECOND);
301: }
302:
303: /**
304: * Answers this Date as a millisecond value. The value is the number of
305: * milliseconds since Jan. 1, 1970 GMT.
306: *
307: * @return the number of milliseconds since Jan. 1, 1970 GMT.
308: */
309: public long getTime() {
310: return milliseconds;
311: }
312:
313: /**
314: * Answers the timezone offset in minutes of the default TimeZone.
315: *
316: * @return the timezone offset in minutes of the default TimeZone
317: *
318: * @deprecated use
319: * <code>(Calendar.get(Calendar.ZONE_OFFSET) + Calendar.get(Calendar.DST_OFFSET)) / 60000</code>
320: */
321: @Deprecated
322: public int getTimezoneOffset() {
323: GregorianCalendar cal = new GregorianCalendar(milliseconds);
324: return -(cal.get(Calendar.ZONE_OFFSET) + cal
325: .get(Calendar.DST_OFFSET)) / 60000;
326: }
327:
328: /**
329: * Answers the gregorian calendar year since 1900 for this Date object.
330: *
331: * @return the year - 1900
332: *
333: * @deprecated use Calendar.get(Calendar.YEAR) - 1900
334: */
335: @Deprecated
336: public int getYear() {
337: return new GregorianCalendar(milliseconds).get(Calendar.YEAR) - 1900;
338: }
339:
340: /**
341: * Answers an integer hash code for the receiver. Objects which are equal
342: * answer the same value for this method.
343: *
344: * @return the receiver's hash
345: *
346: * @see #equals
347: */
348: @Override
349: public int hashCode() {
350: return (int) (milliseconds >>> 32) ^ (int) milliseconds;
351: }
352:
353: private static int parse(String string, String[] array) {
354: for (int i = 0, alength = array.length, slength = string
355: .length(); i < alength; i++) {
356: if (string.regionMatches(true, 0, array[i], 0, slength)) {
357: return i;
358: }
359: }
360: return -1;
361: }
362:
363: /**
364: * Answers the millisecond value of the date and time parsed from the
365: * specified String. Many date/time formats are recognized, including IETF
366: * standard syntax, i.e. Tue, 22 Jun 1999 12:16:00 GMT-0500
367: *
368: * @param string
369: * the String to parse
370: * @return the millisecond value parsed from the String
371: *
372: * @deprecated use DateFormat
373: */
374: @Deprecated
375: public static long parse(String string) {
376:
377: if (string == null) {
378: // luni.06=The string argument is null
379: throw new IllegalArgumentException(Messages
380: .getString("luni.06")); //$NON-NLS-1$
381: }
382:
383: char sign = 0;
384: int commentLevel = 0;
385: int offset = 0, length = string.length(), state = 0;
386: int year = -1, month = -1, date = -1;
387: int hour = -1, minute = -1, second = -1, zoneOffset = 0, minutesOffset = 0;
388: boolean zone = false;
389: final int PAD = 0, LETTERS = 1, NUMBERS = 2;
390: StringBuffer buffer = new StringBuffer();
391:
392: while (offset <= length) {
393: char next = offset < length ? string.charAt(offset) : '\r';
394: offset++;
395:
396: if (next == '(') {
397: commentLevel++;
398: }
399: if (commentLevel > 0) {
400: if (next == ')') {
401: commentLevel--;
402: }
403: if (commentLevel == 0) {
404: next = ' ';
405: } else {
406: continue;
407: }
408: }
409:
410: int nextState = PAD;
411: if ('a' <= next && next <= 'z' || 'A' <= next
412: && next <= 'Z') {
413: nextState = LETTERS;
414: } else if ('0' <= next && next <= '9') {
415: nextState = NUMBERS;
416: } else if (!Character.isSpace(next)
417: && ",+-:/".indexOf(next) == -1) { //$NON-NLS-1$
418: throw new IllegalArgumentException();
419: }
420:
421: if (state == NUMBERS && nextState != NUMBERS) {
422: int digit = Integer.parseInt(buffer.toString());
423: buffer.setLength(0);
424: if (sign == '+' || sign == '-') {
425: if (zoneOffset == 0) {
426: zone = true;
427: if (next == ':') {
428: minutesOffset = sign == '-' ? -Integer
429: .parseInt(string.substring(offset,
430: offset + 2)) : Integer
431: .parseInt(string.substring(offset,
432: offset + 2));
433: offset += 2;
434: }
435: zoneOffset = sign == '-' ? -digit : digit;
436: sign = 0;
437: } else {
438: throw new IllegalArgumentException();
439: }
440: } else if (digit >= 70) {
441: if (year == -1
442: && (Character.isSpace(next) || next == ','
443: || next == '/' || next == '\r')) {
444: year = digit;
445: } else {
446: throw new IllegalArgumentException();
447: }
448: } else if (next == ':') {
449: if (hour == -1) {
450: hour = digit;
451: } else if (minute == -1) {
452: minute = digit;
453: } else {
454: throw new IllegalArgumentException();
455: }
456: } else if (next == '/') {
457: if (month == -1) {
458: month = digit - 1;
459: } else if (date == -1) {
460: date = digit;
461: } else {
462: throw new IllegalArgumentException();
463: }
464: } else if (Character.isSpace(next) || next == ','
465: || next == '-' || next == '\r') {
466: if (hour != -1 && minute == -1) {
467: minute = digit;
468: } else if (minute != -1 && second == -1) {
469: second = digit;
470: } else if (date == -1) {
471: date = digit;
472: } else if (year == -1) {
473: year = digit;
474: } else {
475: throw new IllegalArgumentException();
476: }
477: } else if (year == -1 && month != -1 && date != -1) {
478: year = digit;
479: } else {
480: throw new IllegalArgumentException();
481: }
482: } else if (state == LETTERS && nextState != LETTERS) {
483: String text = buffer.toString().toUpperCase();
484: buffer.setLength(0);
485: if (text.length() == 1) {
486: throw new IllegalArgumentException();
487: }
488: if (text.equals("AM")) { //$NON-NLS-1$
489: if (hour == 12) {
490: hour = 0;
491: } else if (hour < 1 || hour > 12) {
492: throw new IllegalArgumentException();
493: }
494: } else if (text.equals("PM")) { //$NON-NLS-1$
495: if (hour == 12) {
496: hour = 0;
497: } else if (hour < 1 || hour > 12) {
498: throw new IllegalArgumentException();
499: }
500: hour += 12;
501: } else {
502: DateFormatSymbols symbols = new DateFormatSymbols(
503: Locale.US);
504: String[] weekdays = symbols.getWeekdays(), months = symbols
505: .getMonths();
506: int value;
507: if (parse(text, weekdays) != -1) {/* empty */
508: } else if (month == -1
509: && (month = parse(text, months)) != -1) {/* empty */
510: } else if (text.equals("GMT") || text.equals("UT") //$NON-NLS-1$ //$NON-NLS-2$
511: || text.equals("UTC")) { //$NON-NLS-1$
512: zone = true;
513: zoneOffset = 0;
514: } else if ((value = zone(text)) != 0) {
515: zone = true;
516: zoneOffset = value;
517: } else {
518: throw new IllegalArgumentException();
519: }
520: }
521: }
522:
523: if (next == '+' || (year != -1 && next == '-')) {
524: sign = next;
525: } else if (!Character.isSpace(next) && next != ','
526: && nextState != NUMBERS) {
527: sign = 0;
528: }
529:
530: if (nextState == LETTERS || nextState == NUMBERS) {
531: buffer.append(next);
532: }
533: state = nextState;
534: }
535:
536: if (year != -1 && month != -1 && date != -1) {
537: if (hour == -1) {
538: hour = 0;
539: }
540: if (minute == -1) {
541: minute = 0;
542: }
543: if (second == -1) {
544: second = 0;
545: }
546: if (year < (creationYear - 80)) {
547: year += 2000;
548: } else if (year < 100) {
549: year += 1900;
550: }
551: minute -= minutesOffset;
552: if (zone) {
553: if (zoneOffset >= 24 || zoneOffset <= -24) {
554: hour -= zoneOffset / 100;
555: minute -= zoneOffset % 100;
556: } else {
557: hour -= zoneOffset;
558: }
559: return UTC(year - 1900, month, date, hour, minute,
560: second);
561: }
562: return new Date(year - 1900, month, date, hour, minute,
563: second).getTime();
564: }
565: throw new IllegalArgumentException();
566: }
567:
568: /**
569: * Sets the gregorian calendar day of the month for this Date object.
570: *
571: * @param day
572: * the day of the month
573: *
574: * @deprecated use Calendar.set(Calendar.DATE, day)
575: */
576: @Deprecated
577: public void setDate(int day) {
578: GregorianCalendar cal = new GregorianCalendar(milliseconds);
579: cal.set(Calendar.DATE, day);
580: milliseconds = cal.getTimeInMillis();
581: }
582:
583: /**
584: * Sets the gregorian calendar hour of the day for this Date object.
585: *
586: * @param hour
587: * the hour of the day
588: *
589: * @deprecated use Calendar.set(Calendar.HOUR_OF_DAY, hour)
590: */
591: @Deprecated
592: public void setHours(int hour) {
593: GregorianCalendar cal = new GregorianCalendar(milliseconds);
594: cal.set(Calendar.HOUR_OF_DAY, hour);
595: milliseconds = cal.getTimeInMillis();
596: }
597:
598: /**
599: * Sets the gregorian calendar minute of the hour for this Date object.
600: *
601: * @param minute
602: * the minutes
603: *
604: * @deprecated use Calendar.set(Calendar.MINUTE, minute)
605: */
606: @Deprecated
607: public void setMinutes(int minute) {
608: GregorianCalendar cal = new GregorianCalendar(milliseconds);
609: cal.set(Calendar.MINUTE, minute);
610: milliseconds = cal.getTimeInMillis();
611: }
612:
613: /**
614: * Sets the gregorian calendar month for this Date object.
615: *
616: * @param month
617: * the month
618: *
619: * @deprecated use Calendar.set(Calendar.MONTH, month)
620: */
621: @Deprecated
622: public void setMonth(int month) {
623: GregorianCalendar cal = new GregorianCalendar(milliseconds);
624: cal.set(Calendar.MONTH, month);
625: milliseconds = cal.getTimeInMillis();
626: }
627:
628: /**
629: * Sets the gregorian calendar second of the minute for this Date object.
630: *
631: * @param second
632: * the seconds
633: *
634: * @deprecated use Calendar.set(Calendar.SECOND, second)
635: */
636: @Deprecated
637: public void setSeconds(int second) {
638: GregorianCalendar cal = new GregorianCalendar(milliseconds);
639: cal.set(Calendar.SECOND, second);
640: milliseconds = cal.getTimeInMillis();
641: }
642:
643: /**
644: * Sets this Date to the specified millisecond value. The value is the
645: * number of milliseconds since Jan. 1, 1970 GMT.
646: *
647: * @param milliseconds
648: * the number of milliseconds since Jan. 1, 1970 GMT.
649: */
650: public void setTime(long milliseconds) {
651: this .milliseconds = milliseconds;
652: }
653:
654: /**
655: * Sets the gregorian calendar year since 1900 for this Date object.
656: *
657: * @param year
658: * the year since 1900
659: *
660: * @deprecated use Calendar.set(Calendar.YEAR, year + 1900)
661: */
662: @Deprecated
663: public void setYear(int year) {
664: GregorianCalendar cal = new GregorianCalendar(milliseconds);
665: cal.set(Calendar.YEAR, year + 1900);
666: milliseconds = cal.getTimeInMillis();
667: }
668:
669: /**
670: * Answers the string representation of this Date in GMT in the format: 22
671: * Jun 1999 13:02:00 GMT
672: *
673: * @return the string representation of this Date in GMT
674: *
675: * @deprecated use DateFormat
676: */
677: @Deprecated
678: public String toGMTString() {
679: SimpleDateFormat format1 = new SimpleDateFormat(
680: "d MMM ", Locale.US); //$NON-NLS-1$
681: SimpleDateFormat format2 = new SimpleDateFormat(
682: " HH:mm:ss 'GMT'", Locale.US); //$NON-NLS-1$
683: TimeZone gmtZone = TimeZone.getTimeZone("GMT"); //$NON-NLS-1$
684: format1.setTimeZone(gmtZone);
685: format2.setTimeZone(gmtZone);
686: GregorianCalendar gc = new GregorianCalendar(gmtZone);
687: gc.setTimeInMillis(milliseconds);
688: return format1.format(this ) + gc.get(Calendar.YEAR)
689: + format2.format(this );
690: }
691:
692: /**
693: * Answers the string representation of this Date for the current Locale.
694: *
695: * @return the string representation of this Date for the current Locale
696: *
697: * @deprecated use DateFormat
698: */
699: @Deprecated
700: public String toLocaleString() {
701: return DateFormat.getDateTimeInstance().format(this );
702: }
703:
704: /**
705: * Answers the string representation of this Date in the format: Tue Jun 22
706: * 13:07:00 GMT 1999
707: *
708: * @return the string representation of this Date
709: */
710: @Override
711: public String toString() {
712: return new SimpleDateFormat("E MMM dd HH:mm:ss z ", Locale.US) //$NON-NLS-1$
713: .format(this )
714: + new GregorianCalendar(milliseconds)
715: .get(Calendar.YEAR);
716: }
717:
718: /**
719: * Answers the millisecond value of the specified date and time in GMT.
720: *
721: * @param year
722: * the year, 0 is 1900
723: * @param month
724: * the month, 0 - 11
725: * @param day
726: * the day of the month, 1 - 31
727: * @param hour
728: * the hour of day, 0 - 23
729: * @param minute
730: * the minute of the hour, 0 - 59
731: * @param second
732: * the second of the minute, 0 - 59
733: * @return long
734: *
735: * @deprecated use: <code>
736: * Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
737: * cal.set(year + 1900, month, day, hour, minute, second);
738: * cal.getTime().getTime();</code>
739: */
740: @Deprecated
741: public static long UTC(int year, int month, int day, int hour,
742: int minute, int second) {
743: GregorianCalendar cal = new GregorianCalendar(false);
744: cal.setTimeZone(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
745: cal.set(1900 + year, month, day, hour, minute, second);
746: return cal.getTimeInMillis();
747: }
748:
749: private static int zone(String text) {
750: if (text.equals("EST")) { //$NON-NLS-1$
751: return -5;
752: }
753: if (text.equals("EDT")) { //$NON-NLS-1$
754: return -4;
755: }
756: if (text.equals("CST")) { //$NON-NLS-1$
757: return -6;
758: }
759: if (text.equals("CDT")) { //$NON-NLS-1$
760: return -5;
761: }
762: if (text.equals("MST")) { //$NON-NLS-1$
763: return -7;
764: }
765: if (text.equals("MDT")) { //$NON-NLS-1$
766: return -6;
767: }
768: if (text.equals("PST")) { //$NON-NLS-1$
769: return -8;
770: }
771: if (text.equals("PDT")) { //$NON-NLS-1$
772: return -7;
773: }
774: return 0;
775: }
776:
777: private void writeObject(ObjectOutputStream stream)
778: throws IOException {
779: stream.defaultWriteObject();
780: stream.writeLong(getTime());
781: }
782:
783: private void readObject(ObjectInputStream stream)
784: throws IOException, ClassNotFoundException {
785: stream.defaultReadObject();
786: setTime(stream.readLong());
787: }
788: }
|