001 /**
002 * =========================================
003 * LibFormula : a free Java formula library
004 * =========================================
005 *
006 * Project Info: http://reporting.pentaho.org/libformula/
007 *
008 * (C) Copyright 2006-2007, by Pentaho Corporation and Contributors.
009 *
010 * This library is free software; you can redistribute it and/or modify it under the terms
011 * of the GNU Lesser General Public License as published by the Free Software Foundation;
012 * either version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016 * See the GNU Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public License along with this
019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020 * Boston, MA 02111-1307, USA.
021 *
022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023 * in the United States and other countries.]
024 *
025 *
026 * ------------
027 * $Id: DateUtil.java 3521 2007-10-16 10:55:14Z tmorgner $
028 * ------------
029 * (C) Copyright 2006-2007, by Pentaho Corporation.
030 */
031 package org.jfree.formula.util;
032
033 import java.math.BigDecimal;
034 import java.sql.Time;
035 import java.util.Calendar;
036 import java.util.Date;
037 import java.util.GregorianCalendar;
038
039 import org.jfree.formula.DefaultLocalizationContext;
040 import org.jfree.formula.LocalizationContext;
041 import org.jfree.formula.typing.Type;
042 import org.jfree.formula.typing.coretypes.DateTimeType;
043
044 /**
045 *
046 * @author Cedric Pronzato
047 *
048 */
049 public class DateUtil
050 {
051 private static final Date ISO8001_TIME = new GregorianCalendar().getTime();
052
053 private DateUtil()
054 {
055 }
056
057 /**
058 * Converts a <code>Date</code> value according to the requested
059 * <code>Type</code> to the proper <code>Date</code> subclasses (<code>java.sql.Time</code>,
060 * <code>java.sql.Date</code>) if needed. If the requested type is unknown,
061 * no conversion takes place and the input date is returned.
062 *
063 * @param fromDate
064 * The date to convert.
065 * @param toType
066 * The requested type of date.
067 * @return The converted date.
068 */
069 public static Date normalizeDate(final Date fromDate, final Type toType)
070 {
071 return normalizeDate(fromDate, toType, true);
072 }
073
074 public static Date normalizeDate(Date fromDate, final Type toType,
075 final boolean convertSerial)
076 {
077 if (fromDate == null || toType == null)
078 {
079 throw new IllegalArgumentException();
080 }
081
082 if (convertSerial)
083 {
084 Number serial = toSerialDate(fromDate, null);
085 serial = normalizeDate(serial, toType);
086 fromDate = toJavaDate(serial, null);
087 }
088 // final GregorianCalendar gc = new GregorianCalendar();
089 // gc.setTime(fromDate);
090 // gc.set(GregorianCalendar.MILLISECOND, 0);
091 // fromDate = gc.getTime();
092 if (toType.isFlagSet(Type.TIME_TYPE))
093 {
094 return new Time(fromDate.getTime());
095 }
096 else if (toType.isFlagSet(Type.DATE_TYPE))
097 {
098 return new java.sql.Date(fromDate.getTime());
099 }
100 else if (toType.isFlagSet(Type.DATETIME_TYPE))
101 {
102 return new Date(fromDate.getTime());
103 }
104
105 return fromDate;
106 }
107
108 public static Number normalizeDate(final Number fromSerialDate, final Type toType)
109 {
110 if (fromSerialDate == null || toType == null)
111 {
112 throw new IllegalArgumentException();
113 }
114
115 final BigDecimal o = new BigDecimal(fromSerialDate.doubleValue()).setScale(
116 5, BigDecimal.ROUND_UP);
117
118 if (toType.isFlagSet(Type.TIME_TYPE))
119 {
120 return o.subtract(new BigDecimal(o.intValue()));
121 // only return the decimal part
122 // final Double d = new Double(fromSerialDate.doubleValue()
123 // - fromSerialDate.intValue());
124 // return d;
125 }
126 else if (toType.isFlagSet(Type.DATE_TYPE))
127 {
128 return new Integer(fromSerialDate.intValue());
129 }
130 // datetime (java.util.Date)
131 else
132 {
133 return o;
134 }
135 }
136
137 public static Date toJavaDate(final Number serialDate, final LocalizationContext context)
138 {
139 final Date javaDate = HSSFDateUtil.getJavaDate(serialDate.doubleValue());
140 // check for null (error)
141 final long l = (javaDate.getTime() / 1000) * 1000;
142 // final GregorianCalendar gc = new GregorianCalendar(context.getTimeZone(),
143 // context.getLocale());
144 // gc.setTimeInMillis(serialDate.longValue() * MILLISECS_PER_DAY);
145 // return gc.getTime();
146 return new Date(l);
147 }
148
149 public static Number toSerialDate(final Date date, final LocalizationContext context)
150 {
151 // final GregorianCalendar gc = new GregorianCalendar(context.getTimeZone(),
152 // context.getLocale());
153 // gc.setTime(date);
154 // final double fraction = (((gc.get(Calendar.HOUR_OF_DAY) * 60 + gc
155 // .get(Calendar.MINUTE)) * 60 + gc.get(Calendar.SECOND)) * 1000 + gc
156 // .get(Calendar.MILLISECOND))
157 // / (double) MILLISECS_PER_DAY;
158 // final long timeInMillis = date.getTime();
159 // final long days = timeInMillis / MILLISECS_PER_DAY;
160 // return new BigDecimal((double) (days) + fraction);
161 final double serial = HSSFDateUtil.getExcelDate(date);
162 return new Double(serial);
163 }
164
165 public static Date now(final LocalizationContext context)
166 {
167 final GregorianCalendar gc = new GregorianCalendar(context.getTimeZone(),
168 context.getLocale());
169 gc.set(Calendar.MILLISECOND, 0);
170
171 return gc.getTime();
172 }
173
174 public static Date createDateTime(final int year, final int month, final int day, final int hour,
175 final int minute, final int second, final LocalizationContext context)
176 {
177 final GregorianCalendar gc = new GregorianCalendar(context.getTimeZone(),
178 context.getLocale());
179 gc.set(Calendar.DAY_OF_MONTH, day);
180 gc.set(Calendar.MONTH, month);
181 gc.set(Calendar.YEAR, year);
182 gc.set(Calendar.MILLISECOND, 0);
183 gc.set(Calendar.HOUR_OF_DAY, hour);
184 gc.set(Calendar.MINUTE, minute);
185 gc.set(Calendar.SECOND, second);
186 return gc.getTime();
187 }
188
189 public static Time createTime(final int hour, final int minute, final int second,
190 final LocalizationContext context)
191 {
192 final GregorianCalendar gc = new GregorianCalendar(context.getTimeZone(),
193 context.getLocale());
194 gc.setTime(ISO8001_TIME);
195 gc.set(Calendar.MILLISECOND, 0);
196 gc.set(Calendar.HOUR_OF_DAY, hour);
197 gc.set(Calendar.MINUTE, minute);
198 gc.set(Calendar.SECOND, second);
199 return new Time(gc.getTime().getTime());
200 }
201
202 public static java.sql.Date createDate(final int year, final int month, final int day,
203 final LocalizationContext context)
204 {
205 final GregorianCalendar gc = new GregorianCalendar(context.getTimeZone(),
206 context.getLocale());
207 gc.set(Calendar.DAY_OF_MONTH, day);
208 gc.set(Calendar.MONTH, month - 1);
209 gc.set(Calendar.YEAR, year);
210 gc.set(Calendar.MILLISECOND, 0);
211 gc.set(Calendar.HOUR_OF_DAY, 0);
212 gc.set(Calendar.MINUTE, 0);
213 gc.set(Calendar.SECOND, 0);
214 return new java.sql.Date(gc.getTime().getTime());
215 }
216
217 public static Calendar createCalendar(final Date date, final LocalizationContext context)
218 {
219 final GregorianCalendar gc = new GregorianCalendar(context.getTimeZone(),
220 context.getLocale());
221 gc.setTime(date);
222 return gc;
223 }
224
225
226 public static void main(final String[] args)
227 {
228 final DefaultLocalizationContext context = new DefaultLocalizationContext();
229 final java.sql.Date createDate = createDate(2006, 05, 01, context);
230 final Number serial = toSerialDate(createDate, context);
231 System.out.println(createDate);
232 System.out.println(serial);
233 final Date toJavaDate = toJavaDate(serial, context);
234 System.out.println(normalizeDate(toJavaDate, DateTimeType.DATE_TYPE));
235 System.out.println(toJavaDate);
236 System.out.println(HSSFDateUtil.getJavaDate(serial.doubleValue()));
237 }
238
239 }