Lines 33-50
Link Here
|
33 |
* @author Hack Kampbjorn (hak at 2mba.dk) |
33 |
* @author Hack Kampbjorn (hak at 2mba.dk) |
34 |
* @author Alex Jacoby (ajacoby at gmail.com) |
34 |
* @author Alex Jacoby (ajacoby at gmail.com) |
35 |
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com) |
35 |
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com) |
|
|
36 |
* @author Thies Wellpott |
36 |
*/ |
37 |
*/ |
37 |
public class DateUtil { |
38 |
public class DateUtil { |
38 |
protected DateUtil() { |
39 |
protected DateUtil() { |
39 |
// no instances of this class |
40 |
// no instances of this class |
40 |
} |
41 |
} |
41 |
private static final int SECONDS_PER_MINUTE = 60; |
|
|
42 |
private static final int MINUTES_PER_HOUR = 60; |
43 |
private static final int HOURS_PER_DAY = 24; |
44 |
private static final int SECONDS_PER_DAY = (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE); |
45 |
|
42 |
|
|
|
43 |
public static final int SECONDS_PER_MINUTE = 60; |
44 |
public static final int MINUTES_PER_HOUR = 60; |
45 |
public static final int HOURS_PER_DAY = 24; |
46 |
public static final int SECONDS_PER_DAY = (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE); |
47 |
|
46 |
private static final int BAD_DATE = -1; // used to specify that date is invalid |
48 |
private static final int BAD_DATE = -1; // used to specify that date is invalid |
47 |
private static final long DAY_MILLISECONDS = SECONDS_PER_DAY * 1000L; |
49 |
public static final long DAY_MILLISECONDS = SECONDS_PER_DAY * 1000L; |
48 |
|
50 |
|
49 |
private static final Pattern TIME_SEPARATOR_PATTERN = Pattern.compile(":"); |
51 |
private static final Pattern TIME_SEPARATOR_PATTERN = Pattern.compile(":"); |
50 |
|
52 |
|
Lines 57-62
Link Here
|
57 |
// elapsed time patterns: [h],[m] and [s] |
59 |
// elapsed time patterns: [h],[m] and [s] |
58 |
private static final Pattern date_ptrn4 = Pattern.compile("^\\[([hH]+|[mM]+|[sS]+)\\]"); |
60 |
private static final Pattern date_ptrn4 = Pattern.compile("^\\[([hH]+|[mM]+|[sS]+)\\]"); |
59 |
|
61 |
|
|
|
62 |
// only get this static info once (because operations are not really cheap) |
63 |
private static final TimeZone TIMEZONE_UTC = TimeZone.getTimeZone("UTC"); |
64 |
|
65 |
|
60 |
/** |
66 |
/** |
61 |
* Given a Date, converts it into a double representing its internal Excel representation, |
67 |
* Given a Date, converts it into a double representing its internal Excel representation, |
62 |
* which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. |
68 |
* which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. |
Lines 178-196
Link Here
|
178 |
* @return Java representation of the date, or null if date is not a valid Excel date |
184 |
* @return Java representation of the date, or null if date is not a valid Excel date |
179 |
*/ |
185 |
*/ |
180 |
public static Date getJavaDate(double date, boolean use1904windowing, TimeZone tz) { |
186 |
public static Date getJavaDate(double date, boolean use1904windowing, TimeZone tz) { |
181 |
if (!isValidExcelDate(date)) { |
187 |
return getJavaCalendar(date, use1904windowing, tz).getTime(); |
182 |
return null; |
|
|
183 |
} |
184 |
Calendar calendar; |
185 |
if (tz != null) |
186 |
calendar = new GregorianCalendar(tz); |
187 |
else |
188 |
calendar = new GregorianCalendar(); // using default time-zone |
189 |
|
190 |
int wholeDays = (int)Math.floor(date); |
191 |
int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5); |
192 |
setCalendar(calendar, wholeDays, millisecondsInDay, use1904windowing); |
193 |
return calendar.getTime(); |
194 |
} |
188 |
} |
195 |
/** |
189 |
/** |
196 |
* Given an Excel date with either 1900 or 1904 date windowing, |
190 |
* Given an Excel date with either 1900 or 1904 date windowing, |
Lines 212-219
Link Here
|
212 |
* @see java.util.TimeZone |
206 |
* @see java.util.TimeZone |
213 |
*/ |
207 |
*/ |
214 |
public static Date getJavaDate(double date, boolean use1904windowing) { |
208 |
public static Date getJavaDate(double date, boolean use1904windowing) { |
215 |
return getJavaDate(date, use1904windowing, (TimeZone)null); |
209 |
return getJavaCalendar(date, use1904windowing).getTime(); |
216 |
} |
210 |
} |
|
|
211 |
|
212 |
|
217 |
public static void setCalendar(Calendar calendar, int wholeDays, |
213 |
public static void setCalendar(Calendar calendar, int wholeDays, |
218 |
int millisecondsInDay, boolean use1904windowing) { |
214 |
int millisecondsInDay, boolean use1904windowing) { |
219 |
int startYear = 1900; |
215 |
int startYear = 1900; |
Lines 233-238
Link Here
|
233 |
|
229 |
|
234 |
|
230 |
|
235 |
/** |
231 |
/** |
|
|
232 |
* Get EXCEL date as Java Calendar (with default time zone). |
233 |
* This is like {@link #getJavaDate(double, boolean)} but returns a Calendar object. |
234 |
* @param date The Excel date. |
235 |
* @param use1904windowing true if date uses 1904 windowing, |
236 |
* or false if using 1900 date windowing. |
237 |
* @return Java representation of the date, or null if date is not a valid Excel date |
238 |
*/ |
239 |
public static Calendar getJavaCalendar(double date, boolean use1904windowing) { |
240 |
return getJavaCalendar(date, use1904windowing, (TimeZone)null); |
241 |
} |
242 |
|
243 |
/** |
244 |
* Get EXCEL date as Java Calendar with UTC time zone. |
245 |
* This is similar to {@link #getJavaDate(double, boolean)} but returns a |
246 |
* Calendar object that has UTC as time zone, so no daylight saving hassle. |
247 |
* @param date The Excel date. |
248 |
* @param use1904windowing true if date uses 1904 windowing, |
249 |
* or false if using 1900 date windowing. |
250 |
* @return Java representation of the date in UTC, or null if date is not a valid Excel date |
251 |
*/ |
252 |
public static Calendar getJavaCalendarUTC(double date, boolean use1904windowing) { |
253 |
return getJavaCalendar(date, use1904windowing, TIMEZONE_UTC); |
254 |
} |
255 |
|
256 |
|
257 |
/** |
258 |
* Get EXCEL date as Java Calendar with given time zone. |
259 |
* @see getJavaDate(double, TimeZone) |
260 |
* @return Java representation of the date, or null if date is not a valid Excel date |
261 |
*/ |
262 |
public static Calendar getJavaCalendar(double date, boolean use1904windowing, TimeZone timeZone) { |
263 |
if (!isValidExcelDate(date)) { |
264 |
return null; |
265 |
} |
266 |
int wholeDays = (int)Math.floor(date); |
267 |
int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5); |
268 |
Calendar calendar; |
269 |
if (timeZone != null) { |
270 |
calendar = new GregorianCalendar(timeZone); |
271 |
} else { |
272 |
calendar = new GregorianCalendar(); // using default time-zone |
273 |
} |
274 |
setCalendar(calendar, wholeDays, millisecondsInDay, use1904windowing); |
275 |
return calendar; |
276 |
} |
277 |
|
278 |
|
279 |
/** |
236 |
* Given a format ID and its format String, will check to see if the |
280 |
* Given a format ID and its format String, will check to see if the |
237 |
* format represents a date format or not. |
281 |
* format represents a date format or not. |
238 |
* Firstly, it will check to see if the format ID corresponds to an |
282 |
* Firstly, it will check to see if the format ID corresponds to an |
Lines 257-263
Link Here
|
257 |
} |
301 |
} |
258 |
|
302 |
|
259 |
String fs = formatString; |
303 |
String fs = formatString; |
260 |
if (false) { |
304 |
/*if (false) { |
261 |
// Normalize the format string. The code below is equivalent |
305 |
// Normalize the format string. The code below is equivalent |
262 |
// to the following consecutive regexp replacements: |
306 |
// to the following consecutive regexp replacements: |
263 |
|
307 |
|
Lines 276-282
Link Here
|
276 |
|
320 |
|
277 |
// The code above was reworked as suggested in bug 48425: |
321 |
// The code above was reworked as suggested in bug 48425: |
278 |
// simple loop is more efficient than consecutive regexp replacements. |
322 |
// simple loop is more efficient than consecutive regexp replacements. |
279 |
} |
323 |
}*/ |
280 |
StringBuilder sb = new StringBuilder(fs.length()); |
324 |
StringBuilder sb = new StringBuilder(fs.length()); |
281 |
for (int i = 0; i < fs.length(); i++) { |
325 |
for (int i = 0; i < fs.length(); i++) { |
282 |
char c = fs.charAt(i); |
326 |
char c = fs.charAt(i); |