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 4100 2007-11-26 21:04:25Z dkincade $ 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 10, 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 }