001: /*
002: * @(#)DateElementDiff.java 1.3 05/05/07
003: *
004: * Copyright (c) 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package org.pnuts.lib;
010:
011: import java.util.Date;
012: import java.util.Calendar;
013: import pnuts.lang.PnutsFunction;
014: import pnuts.lang.Context;
015:
016: class DateElementDiff extends PnutsFunction {
017: private int element;
018:
019: DateElementDiff(int element, String name) {
020: super (name);
021: this .element = element;
022: }
023:
024: public boolean defined(int nargs) {
025: return nargs == 2;
026: }
027:
028: static int diffYear(Calendar c0, Calendar c1) {
029: return c1.get(Calendar.YEAR) - c0.get(Calendar.YEAR);
030: }
031:
032: static int diffMonth(Calendar c0, Calendar c1) {
033: return diffYear(c1, c0) * 12 + c1.get(Calendar.MONTH)
034: - c0.get(Calendar.MONTH);
035: }
036:
037: static int diffHour(Calendar c0, Calendar c1) {
038: return diffDay(c0, c1) * 24 + c1.get(Calendar.HOUR_OF_DAY)
039: - c0.get(Calendar.HOUR_OF_DAY);
040: }
041:
042: static int diffMinute(Calendar c0, Calendar c1) {
043: return diffHour(c0, c1) * 60 + c1.get(Calendar.MINUTE)
044: - c0.get(Calendar.MINUTE);
045: }
046:
047: static long diffSecond(Calendar c0, Calendar c1) {
048: return diffMinute(c0, c1) * 60L + c1.get(Calendar.SECOND)
049: - c0.get(Calendar.SECOND);
050: }
051:
052: static long diffMilliSecond(Calendar c0, Calendar c1) {
053: return diffSecond(c0, c1) * 1000L
054: + c1.get(Calendar.MILLISECOND)
055: - c0.get(Calendar.MILLISECOND);
056: }
057:
058: static int diffDay(Calendar c0, Calendar c1) {
059: int year0, year1;
060: int day0, day1;
061: year0 = c0.get(Calendar.YEAR);
062: day0 = c0.get(Calendar.DAY_OF_YEAR);
063: year1 = c1.get(Calendar.YEAR);
064: day1 = c1.get(Calendar.DAY_OF_YEAR);
065:
066: if (year0 == year1) {
067: return day1 - day0;
068: } else {
069: boolean negative;
070: if (year0 > year1) {
071: int tmp = year0;
072: year0 = year1;
073: year1 = tmp;
074: tmp = day0;
075: day0 = day1;
076: day1 = tmp;
077: negative = true;
078: } else {
079: negative = false;
080: }
081: int days;
082: Calendar c = (Calendar) c0.clone();
083: c.set(year0, 11, 31);
084: days = c.get(Calendar.DAY_OF_YEAR) - day0;
085: for (int i = year0 + 1; i < year1; i++) {
086: c.set(i, 11, 31);
087: days += c.get(Calendar.DAY_OF_YEAR);
088: }
089: days += day1;
090: if (negative) {
091: return -days;
092: } else {
093: return days;
094: }
095: }
096: }
097:
098: static int diffWeekOfYear(Calendar c0, Calendar c1) {
099: int days = diffDay(c0, c1);
100: int w, firstDay;
101: if (days < 0) {
102: w = c1.get(Calendar.DAY_OF_WEEK);
103: firstDay = c0.getFirstDayOfWeek();
104: } else {
105: w = c0.get(Calendar.DAY_OF_WEEK);
106: firstDay = c0.getFirstDayOfWeek();
107: }
108: return (days - (7 - (w - firstDay) % 7)) / 7 + 1;
109: }
110:
111: protected Object exec(Object[] args, Context context) {
112: if (args.length != 2) {
113: undefined(args, context);
114: return null;
115: }
116: Calendar c0 = date.getCalendar((Date) args[0], context);
117: Calendar c1 = date.getCalendar((Date) args[1], context);
118:
119: switch (element) {
120: case Calendar.YEAR:
121: return new Integer(diffYear(c0, c1));
122: case Calendar.MONTH:
123: return new Integer(diffMonth(c0, c1));
124: case Calendar.WEEK_OF_YEAR:
125: return new Integer(diffWeekOfYear(c0, c1));
126: case Calendar.DAY_OF_YEAR:
127: return new Integer(diffDay(c0, c1));
128: case Calendar.HOUR_OF_DAY:
129: return new Integer(diffHour(c0, c1));
130: case Calendar.MINUTE:
131: return new Integer(diffMinute(c0, c1));
132: case Calendar.SECOND: {
133: long l = diffSecond(c0, c1);
134: if (l > Integer.MAX_VALUE || l < Integer.MIN_VALUE) {
135: return new Long(l);
136: } else {
137: return new Integer((int) l);
138: }
139: }
140: case Calendar.MILLISECOND: {
141: long l = diffMilliSecond(c0, c1);
142: if (l > Integer.MAX_VALUE || l < Integer.MIN_VALUE) {
143: return new Long(l);
144: } else {
145: return new Integer((int) l);
146: }
147: }
148: default:
149: throw new IllegalArgumentException(String.valueOf(element));
150: }
151: }
152:
153: public String toString() {
154: return "function " + name + "(Date, Date)";
155: }
156: }
|