/*
* 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();
}
}