/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.core.util; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import org.teiid.core.designer.CoreModelerPlugin; import org.teiid.core.designer.util.CoreArgCheck; /** * @since 8.0 */ public final class DateUtil { public static final String COMPLETE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS-ZZ:zz"; //$NON-NLS-1$ public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS"; //$NON-NLS-1$ // String indexes (useful for the logic in 'convertStringToDate') // Example "2001-08-07T20:44:22.911-06:00" // "yyyy-MM-ddTHH:mm:ss.SSS-ZZ:zz" // 01234567890123456789012345678 // 1 2 private static final ThreadLocal<DateFormat> DATE_FORMATTER = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { DateFormat df = new SimpleDateFormat(TIMESTAMP_FORMAT); df.setLenient(false); return df; } }; /** * Method to convert a string in the standard MetaMatrix pattern into a Date object. The pattern is * <i>yyyy-MM-dd'T'HH:mm:ss.SSS-ZZ:zz<i> where <blockquote> * * <pre> * Symbol Meaning Presentation Example * ------ ------- ------------ ------- * y year (Number) 1996 * M month in year (Number) 07 * d day in month (Number) 10 * h hour in am/pm (1~12) (Number) 12 * H hour in day (0~23) (Number) 0 * m minute in hour (Number) 30 * s second in minute (Number) 55 * S millisecond (Number) 978 * Z zone offset hours (Number) 6 * z zone offset minutes (Number) 30 * ' escape for text (Delimiter) * '' single quote (Literal) ' * </pre> * * </blockquote> The milliseconds, zone hour, and zone minutes are not required for parsing. * * @param dateString the stringified date in the format described above * @return the Date instance * @throws ParseException if the string is not of the expected format */ public static final Date convertStringToDate( String dateString ) throws ParseException { CoreArgCheck.isNotEmpty(dateString); int badIndex = 0; int millis = 0; try { // Find the year ... int year = Integer.parseInt(dateString.substring(0, 4)); badIndex = 5; int month = Integer.parseInt(dateString.substring(5, 7)); badIndex = 8; int day = Integer.parseInt(dateString.substring(8, 10)); badIndex = 11; int hours = Integer.parseInt(dateString.substring(11, 13)); badIndex = 14; int minutes = Integer.parseInt(dateString.substring(14, 16)); badIndex = 17; int seconds = Integer.parseInt(dateString.substring(17, 19)); int len = dateString.length(); if (len > 19) { badIndex = 20; millis = Integer.parseInt(dateString.substring(20, 23)); } if (len > 23) { badIndex = 24; Integer.parseInt(dateString.substring(24, 26)); } if (len > 26) { badIndex = 27; Integer.parseInt(dateString.substring(27, 29)); } // Note the month is zero-based!!!! GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day, hours, minutes, seconds); calendar.add(Calendar.MILLISECOND, millis); // TODO: Unable to support different time zones!!!! // calendar.add(Calendar.ZONE_OFFSET,millis); throws IllegalArgument return calendar.getTime(); // Use a java.sql.Timestamp since java.util.Date doesn't have a way to set millis!!! // return new Timestamp(year,month,day,hours,minutes,seconds,millis*1000); } catch (IndexOutOfBoundsException ioobe) { final Object[] params = new Object[] {dateString, COMPLETE_FORMAT}; throw new ParseException( CoreModelerPlugin.Util.getString("DateUtil.The_string_is_not_of_the_expected_format_1", params), badIndex); //$NON-NLS-1$ } catch (NumberFormatException nfe) { final Object[] params = new Object[] {dateString, COMPLETE_FORMAT}; throw new ParseException( CoreModelerPlugin.Util.getString("DateUtil.The_string_is_not_of_the_expected_format_2", params), badIndex); //$NON-NLS-1$ } } public static final String getDateAsString( Date timestamp ) { return formatString(timestamp); } public static final String getDateAsString( long timestamp ) { return formatString(new Date(timestamp)); } public static final Date getDate( long timestamp ) { return new Date(timestamp); } public static final String getCurrentDateAsString() { return formatString(new Date()); } public static final Date getCurrentDate() { return new Date(); } private static final String formatString( Date timestamp ) { StringBuffer sb = new StringBuffer(DATE_FORMATTER.get().format(timestamp)); long offsetMillis = Calendar.getInstance().get(Calendar.ZONE_OFFSET); if (offsetMillis == 0) { sb.append("+00:00"); //$NON-NLS-1$ } else if (offsetMillis > 0) { sb.append('+'); } else { sb.append('-'); } int seconds = (int)(Math.abs(offsetMillis) / 1000); int minutes = seconds / 60; int hours = minutes / 60; minutes = minutes % 60; if (hours < 10) { sb.append('0'); } sb.append(hours); sb.append(':'); if (minutes < 10) { sb.append('0'); } sb.append(minutes); return sb.toString(); } }