/*
* © Copyright IBM Corp. 2012-2013
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.ibm.commons.util;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;
/**
* Some date-time converter utilities.
* @ibm-not-published
*/
public final class DateTime {
public static final String SHORT_DATE = "<date>"; //$NON-NLS-1$
public static final String LONG_DATE = "<long date>"; //$NON-NLS-1$
public static final String SHORT_TIME = "<time>"; //$NON-NLS-1$
public static final String LONG_TIME = "<long time>"; //$NON-NLS-1$
public static final String SHORT_DATETIME = "<date and time>"; //$NON-NLS-1$
public static final String LONG_DATETIME = "<long date and time>"; //$NON-NLS-1$
public static final String FULL_DATE = "<full>"; //$NON-NLS-1$
public static final String MEDIUM_DATE = "<medium>"; //$NON-NLS-1$
/**
* Convert a date object to a string using a SimpleDate format.
* @param date the date to format
* @param format the string format to use
* @ibm-api
*/
public static String formatDateTime( Date date, String format ) {
return formatDateTime(date, format, Locale.getDefault(), TimeZone.getDefault());
}
/**
* Convert a date object to a string using a default format.
* @param date the date to format
* @ibm-api
*/
public static String formatDateTime( Date date) {
return formatDateTime(date, null, Locale.getDefault(), TimeZone.getDefault());
}
/**
* Convert a date object to a string using a default format.
* @param date the date to format
* @param loc the locale to use
* @ibm-api
*/
public static String formatDateTime( Date date, Locale loc) {
return formatDateTime(date, null, loc, TimeZone.getDefault());
}
/**
* Convert a date object to a string using a default format.
* @param date the date to format
* @param format the string format to use
* @param loc the locale to use
* @ibm-api
*/
public static String formatDateTime(Date date, String format, Locale loc) {
return formatDateTime(date, format, loc, TimeZone.getDefault());
}
/**
* Format the date with the given pattern.
* If the pattern is one of the predefined pattern, it may be impacted by the locale
* (ex : dd/MM/yy in france and MM/dd/yy in the US)
* The given date is converted to the given TZ
* The TZ is also useful to display the timezone code for <long time> and <long date and time>
* that contains a 3-letters code for the tz.
* @param date the date to format
* @param format the string format to use
* @param loc the locale to use
* @param tz the time zone to use
* @ibm-api
*/
public static String formatDateTime(Date date, String format, Locale loc, TimeZone tz) {
if (date==null){
return null;
}
if (loc==null) {
loc = Locale.getDefault();
}
if (tz==null) {
tz = TimeZone.getDefault();
}
if( !StringUtil.isEmpty(format) ) {
if (format.charAt(0)=='<') {
if( format.equals(SHORT_DATE) ) {
// tz is unuseful
return getShortDateFormatter(loc, TimeZone.getDefault()).format(date);
} else if( format.equals(LONG_DATE) ) {
// tz is unuseful
return getLongDateFormatter(loc, TimeZone.getDefault()).format(date);
} else if( format.equals(SHORT_TIME) ) {
return getShortTimeFormatter(loc, tz).format(date);
} else if( format.equals(LONG_TIME) ) {
return getLongTimeFormatter(loc, tz).format(date);
} else if( format.equals(SHORT_DATETIME) ) {
return getShortDatetimeFormatter(loc, tz).format(date);
} else if( format.equals(LONG_DATETIME) ) {
return getLongDatetimeFormatter(loc, tz).format(date);
}
} else {
java.text.DateFormat fmt = new java.text.SimpleDateFormat(format, loc);
if (format!=null
&& ( format.indexOf('h')!=-1
|| format.indexOf('H')!=-1
|| format.indexOf('m')!=-1
|| format.indexOf('s')!=-1)) {
fmt.setTimeZone(tz);
}
return fmt.format(date);
}
}
return getDefaultDateFormatter(loc).format(date);
}
/**
* transform a complete pattern (following java standard) into a simplified one.
* (tolerance on the separators... )
*/
private static String getSimplifiedDateFormat(String javafmt) {
if( !StringUtil.isEmpty(javafmt) ) {
String fmt = formatCache.get(javafmt);
if( fmt==null ) {
StringBuilder b = new StringBuilder();
// special case for MMMM or MMM
javafmt = StringUtil.replace(javafmt, "MMMM", "J"); //$NON-NLS-1$ //$NON-NLS-2$
javafmt = StringUtil.replace(javafmt, "MMM", "j"); //$NON-NLS-1$ //$NON-NLS-2$
char lastch=0;
for( int i=0; i<javafmt.length(); i++ ){
char ch=javafmt.charAt(i);
if( ch!=lastch ) {
switch(ch) {
case 'y': b.append('Y'); break;
case 'M': b.append('M'); break;
case 'J': b.append('J'); break;
case 'j': b.append('j'); break;
case 'd': b.append('D'); break;
case 'h': case 'H': b.append('H'); break;
case 'm': b.append('N'); break;
case 's': b.append('S'); break;
case 'z': b.append('Z'); break;
case '/':
case '.':
case '-': b.append('/'); break;
case ':': b.append(':'); break;
}
}
lastch=ch;
}
fmt = b.toString();
formatCache.put(javafmt,fmt);
}
return fmt;
}
return ""; //$NON-NLS-1$
}
/**
* A cache for the formats
*/
private static HashMap<String, String> formatCache = new HashMap<String, String>();
/**
* Getting a Date from a String. (the string represents a date in JVM TZ)
* @param text the text of the date
* @param format the string format to use
* @ibm-api
*/
public static Date parseDate( String text, String format) throws ParseException {
return parseDate(text, format, TimeZone.getDefault(), Locale.getDefault());
}
/**
* Getting a Date from a String. (the string represents a date in JVM TZ)
* @param text the text of the date
* @param format the string format to use
* @param tz the time zone to use
* @ibm-api
*/
public static Date parseDate( String text, String format, TimeZone tz ) throws ParseException {
return parseDate(text, format, tz, Locale.getDefault());
}
/**
* Getting a Date from a String. (the string represents a date in JVM TZ)
* @param text the text of the date
* @param format the string format to use
* @param loc the locale to use
* @ibm-api
*/
public static Date parseDate( String text, String format, Locale loc ) throws ParseException {
return parseDate(text, format, TimeZone.getDefault(), loc);
}
/**
* Getting a Date from a String
* Warning ! here format must be an explicit format
* The date to parse can contain a TZ code (if pattern contains 'z').
* If there is no code, it is supposed to be in the given TZ.
* BUT, the returned date is in the JVM TZ.
* Note : Locale is only useful if the pattern contains MMM or MMMM, to interpret the name of the month
* Note : If the format does not contain time (only date), there is no conversion to the given tz
* @param text the text of the date
* @param format the string format to use
* @param loc the locale to use
* @param tz the time zone to use
* @ibm-api
*/
public static Date parseDate( String text, String format, TimeZone tz, Locale loc ) throws ParseException {
if (text==null){
return null;
}
if (tz==null) {
tz = TimeZone.getDefault();
}
if (loc==null) {
loc = Locale.getDefault();
}
String dt = text.toLowerCase().trim();
if( StringUtil.isEmpty(dt) ) {
return null;
}
// Get the simplified format
String fmt = getSimplifiedDateFormat(format);
// Parse the date content
int year=-1, month=-1, day=-1, hour=-1, minute=-1, second=-1, ampm=-1;
// String tzCode;
int pos = 0;
boolean hasDate=false; boolean hasTime=false;
// nb of characters for the year
int nbCharForYear = 0;
// if short name of month ends with a '.' : should be ignored
int point = dt.indexOf('.');
if (point!=-1 && (dt.charAt(point-1)>='a' && dt.charAt(point-1)<='z')) {
dt = dt.substring(0, point) + dt.substring(point+1);
}
for( int fmtpos=0; pos<dt.length(); ) {
int nbChar = 0;
char c = dt.charAt(pos++);
nbChar++;
if( c>='0' && c<='9' ) {
// try to read a number
int num = c-'0';
while( pos<dt.length() ) {
c = dt.charAt(pos);
if( c>='0' && c<='9' ) {
num = num*10 + (c-'0');
pos++;
nbChar++;
} else {
break;
}
}
if( fmtpos<fmt.length() ) {
switch( fmt.charAt(fmtpos) ) {
case 'Y': year = num; hasDate=true; nbCharForYear=nbChar; break;
case 'M': month = num; hasDate=true; break;
case 'J': month = num; hasDate=true; break;
case 'j': month = num; hasDate=true; break;
case 'D': day = num; hasDate=true; break;
case 'H': hour = num; hasTime=true; break;
case 'N': minute = num; hasTime=true; break;
case 'S': second = num; hasTime=true; break;
}
fmtpos++;
} else {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
} else if( Character.isLetter(c) /*c>='a' && c<='z'*/) {
// try to read a word (ex : AM, PM, name of a month, 3-letters for tz... )
StringBuilder b = new StringBuilder();
b.append(c);
while( pos<dt.length() ) {
c = dt.charAt(pos);
if( Character.isLetter(c) ) {
b.append(c);
pos++;
} else {
break;
}
}
String ss = b.toString();
if( ss.equals("am") ) { //$NON-NLS-1$
if( ampm>0 ) throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
ampm=1;
} else if( ss.equals("pm") ) { //$NON-NLS-1$
if( ampm>0 ) throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
ampm=2;
} else if( fmtpos<fmt.length() && (fmt.charAt(fmtpos)=='J' || fmt.charAt(fmtpos)=='j') ) {
// check if ss is a name of month
int i = computeMonth(ss, loc);
if (i!=-1) {
month = i;
fmtpos++;
} else {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
} else if( fmtpos<fmt.length() && fmt.charAt(fmtpos)=='Z' ) {
// PHIL: should be tested
// check if ss is a TZ code
boolean found = false;
String[] ids = TimeZone.getAvailableIDs();
for( int i=0; i<ids.length; i++ ) {
if( StringUtil.equalsIgnoreCase(ss,ids[i])) {
tz = TimeZone.getTimeZone(ids[i]);
fmtpos++;
found = true;
break;
}
}
if(!found) {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
// TStringArrayMatching strArray = new TStringArrayMatching(TimeZone.getAvailableIDs());
// if (strArray.containsIgnoreCase(ss)==TStringArrayMatching.COMPLETE) {
// tz = TimeZone.getTimeZone(strArray.getExactString(ss));
// fmtpos++;
// } else {
// throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
// }
} else {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
} else if( c=='/' || c=='.' || c=='-' ) {
if( fmtpos>=fmt.length() || fmt.charAt(fmtpos)!='/' ) {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
fmtpos++;
} else if( c==':' ) {
if( fmtpos>=fmt.length() || fmt.charAt(fmtpos)!=':' ) {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
fmtpos++;
} else if( c==' ' || c==',') {
// Ignore
} else {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
}
// Check the date part
if( hasDate ) {
if (nbCharForYear<=2) {
year = convertYearIfInf100(year);
}
int maxDay;
if((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
maxDay = 30;
} else if(month == 2) {
maxDay = ( ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
} else {
maxDay = 31;
}
if( (day<1 || day>maxDay)
|| (month<1 || month>12)
|| (year<=0) ) {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
} else {
day = month = year = 0;
}
// Check the time part
if( hasTime ) {
// Warning about US conventions for hours !!!
if (ampm==1 && hour==12) {
hour = 0; // 00:00 (midnight) is coded by 12:00 AM
} else if (ampm==2 && hour!=12) {
// no change if hour is 12, because 12:00 (noon) is coded by 12:00 PM
hour +=12;
} else if (ampm==-1 && hour==24) {
hour = 0; // 24:00 is accepted, it means 00:00
}
if( second==-1 ) second=0;
// hour must be between 0 and 23 !
if( (hour<0 || hour>23)
|| (minute<0 || minute>59)
|| (second!=-1 && (second<0 || second>59)) ) {
throw new ParseException( StringUtil.format("Invalid date '{0}'", text), pos ); //$NLS-DateTime.TFormatter.InvalidDate.Exception-1$
}
} else {
hour = minute = second = 0;
}
// Valid!
// case has only time : 1st january 1970
if (!hasDate && hasTime) {
year = 1970;
month = 1;
day = 1;
}
if( hasDate || hasTime ) {
// case the date comes from another time zone (and hasTime)
if (hasTime && ! tz.hasSameRules(TimeZone.getDefault())) {
TGregorianCalendar cal = getCalendar();
try {
cal.setTimeZone(tz);
cal.set(year, month-1, day, hour, minute, second);
cal.set(GregorianCalendar.MILLISECOND,0);
return cal.getTime();
}finally{
recycleCalendar(cal,true);
}
}
// case the date can be returned without conversion
else {
TGregorianCalendar cal = getCalendar();
try {
cal.set(year, month-1, day, hour, minute, second);
cal.set(GregorianCalendar.MILLISECOND,0);
return cal.getTime();
}finally{
recycleCalendar(cal,false);
}
}
}
return null;
}
/**
* Returns an int to represent the given month (ex : 1 for January)
* Returns -1 if the given string doesn't match any month
* Try to match with complete name and then with short names
*/
private static int computeMonth(String ss, Locale loc) {
DateFormatSymbols sym = new DateFormatSymbols(loc);
String[] monthsArray = sym.getMonths();
String[] shortMonthsArray = sym.getShortMonths();
for (int i=0; i<monthsArray.length; i++) {
if (StringUtil.equalsIgnoreCase(monthsArray[i], ss)) {
return i+1;
}
}
if (ss.endsWith(".")) { //$NON-NLS-1$
ss = ss.substring(0, ss.length()-1);
}
for (int i=0; i<shortMonthsArray.length; i++) {
if (shortMonthsArray[i].endsWith(".")) { //$NON-NLS-1$
shortMonthsArray[i] = shortMonthsArray[i].substring(0, shortMonthsArray[i].length()-1);
}
if (StringUtil.equalsIgnoreCase(shortMonthsArray[i], ss)) {
return i+1;
}
}
return -1;
}
// private int computeMonth(String ss) {
// return computeMonth(ss, Locale.getDefault());
// }
// NEVER USED !!!!!
// Getting a Date from a String
// public static java.util.Date getDateTime(String dateString,String format, Locale loc) {
// if (loc==null) {
// loc = Locale.getDefault();
// }
// if( StringUtil.isEmpty(dateString) ) {
// return null;
// }
// try{
// if( format.equals(SHORT_DATE) ) {
// return getShortDateFormatter().parse(dateString);
// }
// if( format.equals(LONG_DATE) ) {
// return getLongDatetimeFormatter().parse(dateString);
// }
// java.text.DateFormat fmt = new java.text.SimpleDateFormat(format);
// return fmt.parse(dateString);
// }catch(Exception e){
// com.ibm.workplace.designer.util.TDiag.exception(e);
// return null;
// }
// }
/**
* Convert a date from a user timezone to the JVM timezeone.
* @param date the date to convert
* @param userTZ the user timezone
* @return the converted date
* @ibm-api
*/
public static Date convertDateIntoJVMTimeZone(Date date, TimeZone userTZ) {
return timeZoneConversion(date, userTZ, TimeZone.getDefault());
}
/**
* Convert a date from the JVM timezeone to a user timezone.
* @param date the date to convert
* @param userTZ the user timezone
* @return the converted date
* @ibm-api
*/
public static Date convertDateFromJVMTimeZone(Date date, TimeZone userTZ) {
return timeZoneConversion(date, TimeZone.getDefault(), userTZ);
}
/**
* Convert a date from a source timezone to a target timezone.
* @param date the date to convert
* @param source the source timezone
* @param target the target timezone
* @return the converted date
* @ibm-api
*/
public static Date timeZoneConversion(Date date, TimeZone source, TimeZone target) {
if( !source.equals(target) ) {
// creation of a calendar for the date in the SOURCE tz
TGregorianCalendar calSource=getCalendar();
// creation of a calendar for the same 'absolute time' in TARGET tz
TGregorianCalendar calTarget=getCalendar();
try {
calSource.setTimeZone(source);
calSource.setTime(date);
// offset to convert : source -> GMT
int zoneOffsetSource=-calSource.get(Calendar.ZONE_OFFSET);
int dstOffsetSource=-calSource.get(Calendar.DST_OFFSET);
calTarget.setTimeZone(target);
calTarget.setMillis(calSource.getMillis());
// offset to convert : GMT -> JVM tz
int zoneOffsetTarget=calTarget.get(Calendar.ZONE_OFFSET);
int dstOffsetTarget=calTarget.get(Calendar.DST_OFFSET);
long totalOffset= ((long)zoneOffsetSource)+dstOffsetSource+zoneOffsetTarget+dstOffsetTarget;
// obtain a new date in JVM tz
date=new Date(date.getTime() + totalOffset);
} finally {
recycleCalendar(calSource,true);
recycleCalendar(calTarget,true);
}
}
return date;
}
/**
* Convert a java.sql.Timestamp from a user timezone to the JVM timezeone.
* @param date the date to convert
* @param userTZ the user timezone
* @return the converted date
* @ibm-api
*/
public static java.sql.Timestamp convertTimestampIntoJVMTimeZone(java.sql.Timestamp date, TimeZone userTZ) {
return timeZoneTimestampConversion(date, userTZ, TimeZone.getDefault());
}
/**
* Convert a java.sql.Timestamp from the JVM timezeone to a user timezone.
* @param date the date to convert
* @param userTZ the user timezone
* @return the converted date
* @ibm-api
*/
public static java.sql.Timestamp convertTimestampFromJVMTimeZone(java.sql.Timestamp date, TimeZone userTZ) {
return timeZoneTimestampConversion(date, TimeZone.getDefault(), userTZ);
}
/**
* Convert a java.sql.Timestamp from a source timezeone to a target timezone.
* @param date the date to convert
* @param source the source timezone
* @param target the target timezone
* @return the converted date
* @ibm-api
*/
public static java.sql.Timestamp timeZoneTimestampConversion(java.sql.Timestamp date, TimeZone source, TimeZone target) {
if( !source.equals(target) ) {
// creation of a calendar for the date in the SOURCE tz
TGregorianCalendar calSource=getCalendar();
// creation of a calendar for the same 'absolute time' in TARGET tz
TGregorianCalendar calTarget=getCalendar();
try {
calSource.setTimeZone(source);
calSource.setTime(date);
// offset to convert : source -> GMT
int zoneOffsetSource=-calSource.get(Calendar.ZONE_OFFSET);
int dstOffsetSource=-calSource.get(Calendar.DST_OFFSET);
calTarget.setTimeZone(target);
calTarget.setMillis(calSource.getMillis());
// offset to convert : GMT -> JVM tz
int zoneOffsetTarget=calTarget.get(Calendar.ZONE_OFFSET);
int dstOffsetTarget=calTarget.get(Calendar.DST_OFFSET);
long totalOffset= ((long)zoneOffsetSource)+dstOffsetSource+zoneOffsetTarget+dstOffsetTarget;
// obtain a new date in JVM tz
date=new java.sql.Timestamp(date.getTime()+totalOffset);
} finally {
recycleCalendar(calSource,true);
recycleCalendar(calTarget,true);
}
}
return date;
}
/**
* Get the real date format string.
* Return the actual format from the abreviated form.
* @param format the date formt
* @param loc the Locale to use
* @return the actual date format
* @ibm-api
*/
public static String getFormatString( String format, Locale loc ) {
if (loc==null) {
loc = Locale.getDefault();
}
// if it is a predefined format (one of the 6 constants)
if( !StringUtil.isEmpty(format) && format.charAt(0)=='<') {
java.text.DateFormat fmt = null;
if( format.equals(SHORT_DATE) ) {
fmt = getShortDateFormatter(loc);
} else if( format.equals(LONG_DATE) ) {
fmt = getLongDateFormatter(loc);
} else if( format.equals(SHORT_TIME) ) {
fmt = getShortTimeFormatter(loc);
} else if( format.equals(LONG_TIME) ) {
fmt = getLongTimeFormatter(loc);
} else if( format.equals(SHORT_DATETIME) ) {
fmt = getShortDatetimeFormatter(loc);
} else if( format.equals(LONG_DATETIME) ) {
fmt = getLongDatetimeFormatter(loc);
}
if( fmt!=null && fmt instanceof SimpleDateFormat ) {
return ((SimpleDateFormat)fmt).toPattern();
}
}
// in other cases, return the format string itself
return format;
}
/**
* Get the real date format string.
* Return the actual format from the abreviated form.
* @param format the date formt
* @param loc the Locale to use
* @param tZ the Timezone to use
* @return the actual date format
* @ibm-api
*/
public static String getFormatString( String format, Locale loc,TimeZone tZ ) {
if (loc==null) {
loc = Locale.getDefault();
}
// if it is a predefined format (one of the 6 constants)
if( !StringUtil.isEmpty(format) && format.charAt(0)=='<') {
java.text.DateFormat fmt = null;
if( format.equals(SHORT_DATE) ) {
fmt = getShortDateFormatter(loc,tZ);
} else if( format.equals(LONG_DATE) ) {
fmt = getLongDateFormatter(loc,tZ);
} else if( format.equals(SHORT_TIME) ) {
fmt = getShortTimeFormatter(loc,tZ);
} else if( format.equals(LONG_TIME) ) {
fmt = getLongTimeFormatter(loc,tZ);
} else if( format.equals(SHORT_DATETIME) ) {
fmt = getShortDatetimeFormatter(loc,tZ);
} else if( format.equals(LONG_DATETIME) ) {
fmt = getLongDatetimeFormatter(loc,tZ);
}
else if( format.equals(FULL_DATE) ) {
fmt = getFullDateFormatter(loc,tZ);
}
else if( format.equals(MEDIUM_DATE) ) {
fmt = getMediumDateFormatter(loc,tZ);
}
if( fmt!=null && fmt instanceof SimpleDateFormat ) {
return ((SimpleDateFormat)fmt).toPattern();
}
}
// in other cases, return the format string itself
return format;
}
/**
* Get the real date format string.
* Return the actual format from the abreviated form.
* @param format the date formt
* @return the actual date format
* @ibm-api
*/
public static String getFormatString( String format) {
return getFormatString(format, Locale.getDefault());
}
// DATE
/**
* Return the default formatter for a date.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultDateFormatter() {
return getShortDateFormatter();
}
/**
* Return the default short formatter for a date.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortDateFormatter() {
return DateFormat.getDateInstance(DateFormat.SHORT);
}
/**
* Return the default long formatter for a date.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongDateFormatter() {
return DateFormat.getDateInstance(DateFormat.LONG);
}
/**
* Return the default formatter for a date.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultDateFormatter(Locale loc) {
return getShortDateFormatter(loc);
}
/**
* Return the default short formatter for a date.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortDateFormatter(Locale loc) {
return DateFormat.getDateInstance(DateFormat.SHORT, loc);
}
/**
* Return the default long formatter for a date.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongDateFormatter(Locale loc) {
return DateFormat.getDateInstance(DateFormat.LONG, loc);
}
/**
* Return the default formatter for a date.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultDateFormatter(Locale loc, TimeZone tz) {
return getShortDateFormatter(loc, tz);
}
/**
* Return the default short formatter for a date.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortDateFormatter(Locale loc, TimeZone tz) {
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, loc);
df.setTimeZone(tz);
return df;
}
/**
* Return the default long formatter for a date.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongDateFormatter(Locale loc, TimeZone tz) {
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, loc);
df.setTimeZone(tz);
return df;
}
/**
* Return the default full formatter for a date.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getFullDateFormatter(Locale loc, TimeZone tz) {
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, loc);
df.setTimeZone(tz);
return df;
}
/**
* Return the default medium formatter for a date.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getMediumDateFormatter(Locale loc, TimeZone tz) {
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, loc);
df.setTimeZone(tz);
return df;
}
// TIME
/**
* Return the default formatter for a time.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultTimeFormatter() {
return getShortTimeFormatter();
}
/**
* Return the default short formatter for a time.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortTimeFormatter() {
return DateFormat.getTimeInstance(DateFormat.SHORT);
}
/**
* Return the default long formatter for a time.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongTimeFormatter() {
return DateFormat.getTimeInstance(DateFormat.LONG);
}
/**
* Return the default formatter for a time.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultTimeFormatter(Locale loc) {
return getShortTimeFormatter(loc);
}
/**
* Return the default short formatter for a time.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortTimeFormatter(Locale loc) {
return DateFormat.getTimeInstance(DateFormat.SHORT, loc);
}
/**
* Return the default long formatter for a time.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongTimeFormatter(Locale loc) {
return DateFormat.getTimeInstance(DateFormat.LONG, loc);
}
/**
* Return the default formatter for a time.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultTimeFormatter(Locale loc, TimeZone tz) {
return getShortTimeFormatter(loc);
}
/**
* Return the default short formatter for a time.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortTimeFormatter(Locale loc, TimeZone tz) {
DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT, loc);
df.setTimeZone(tz);
return df;
}
/**
* Return the default long formatter for a time.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongTimeFormatter(Locale loc, TimeZone tz) {
DateFormat df = DateFormat.getTimeInstance(DateFormat.LONG, loc);
df.setTimeZone(tz);
return df;
}
// DATETIME
/**
* Return the default formatter for a timestamp.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultDatetimeFormatter() {
return getShortDatetimeFormatter();
}
/**
* Return the default short formatter for a timestamp.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortDatetimeFormatter() {
return DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT);
}
/**
* Return the default long formatter for a timestamp.
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongDatetimeFormatter() {
return DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
}
/**
* Return the default formatter for a timestamp.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultDatetimeFormatter(Locale loc) {
return getShortDatetimeFormatter(loc);
}
/**
* Return the default short formatter for a timestamp.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortDatetimeFormatter(Locale loc) {
return DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT, loc);
}
/**
* Return the default long formatter for a timestamp.
* @param loc the Locale to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongDatetimeFormatter(Locale loc) {
return DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG, loc);
}
/**
* Return the default formatter for a timestamp.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getDefaultDatetimeFormatter(Locale loc, TimeZone tz) {
return getShortDatetimeFormatter(loc);
}
/**
* Return the default short formatter for a timestamp.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getShortDatetimeFormatter(Locale loc, TimeZone tz) {
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT, loc);
df.setTimeZone(tz);
return df;
}
/**
* Return the default long formatter for a timestamp.
* @param loc the Locale to use
* @param tz the Timezone to use
* @return the resulting DateFormat
* @ibm-api
*/
public static final DateFormat getLongDatetimeFormatter(Locale loc, TimeZone tz) {
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, loc);
df.setTimeZone(tz);
return df;
}
// ==== DATE UTILITIES ===========================================================================
public static final int limitDate = 39;
/**
* If a year is composed by only 2 characters, add 1900 or 2000.
* If a year is composed by more than 2 characters : no change
* @ibm-api
*/
public static int convertYear(String st) {
int result = Integer.parseInt(st);
if (st.length()<=2) {
return convertYearIfInf100(result);
}
return result;
}
/**
* Add 1900 or 2000 to the given year, if the given int is between 0 and 99.
* (else the year is returned without any change)
* This method shoud be called for a year value that comes from a 2-characters long string
* @ibm-api
*/
public static int convertYearIfInf100(int year) {
if( year>=0 && year<=limitDate ) {
year+=2000;
}
if( year>limitDate && year<=99 ) {
year+=1900;
}
return year;
}
/**
* java.util.Date gregorian structure representation.
* @ibm-not-published
*/
public static class DateStruct {
public DateStruct() {
this( System.currentTimeMillis() );
}
/**
* @param year - the normal year (ex : 2003)
* @param month - the month between 1-12.
*/
public DateStruct( int year, int month, int day, int hour, int minute, int second, int millis ) {
this.year = year;
this.month = month;
this.day = day;
this.hour = hour;
this.minute = minute;
this.second = second;
this.millis = millis;
}
public DateStruct( int year, int month, int day, int hour, int minute, int second ) {
this( year, month, day, hour, minute, second, 0 );
}
public DateStruct( java.util.Date dt ) {
this( dt.getTime() );
}
public DateStruct( long dt ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.setMillis(dt);
this.year = gregorianCalendar.get(Calendar.YEAR);
this.month = gregorianCalendar.get(Calendar.MONTH)+1;
this.day = gregorianCalendar.get(Calendar.DAY_OF_MONTH);
this.hour = gregorianCalendar.get(Calendar.HOUR_OF_DAY);
this.minute = gregorianCalendar.get(Calendar.MINUTE);
this.second = gregorianCalendar.get(Calendar.SECOND);
this.millis = gregorianCalendar.get(Calendar.MILLISECOND);
} finally {
recycleCalendar(gregorianCalendar);
}
}
// public String toISOString() {
// return TString.format( "{0}-{1}-{2}",
// TString.toString(year),
// TString.toString(month),
// TString.toString(day))
// + TString.format( " {0}:{1}:{2}.{3}",
// TString.toString(hour),
// TString.toString(minute),
// TString.toString(second)
// TString.toString(millis) );
// }
public java.util.Date createDate() {
return createDate(year,month,day,hour,minute,second,millis);
}
public static final java.util.Date createDate( int year, int month, int day, int hour, int minute, int second ) {
return createDate(year,month,day,hour,minute,second,0);
}
public static final java.util.Date createDate( int year, int month, int day, int hour, int minute, int second, int millis ) {
return new java.util.Date( createDateAsLong(year,month,day,hour,minute,second,millis) );
}
/**
*
* @param y The year (already adjusted, no need to add 1900 or 2000)
*/
public static final long createDateAsLong( int y, int m, int d, int h, int n, int s, int ms ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.set(y,m-1,d,h,n,s);
gregorianCalendar.set(GregorianCalendar.MILLISECOND,ms);
return gregorianCalendar.getMillis();
} finally {
recycleCalendar(gregorianCalendar);
}
}
/**
*
* @param y The year (already adjusted, no need to add 1900 or 2000)
*/
public static final long createDateAsLong( int y, int m, int d, int h, int n, int s ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.set(y,m-1,d,h,n,s);
gregorianCalendar.set(GregorianCalendar.MILLISECOND,0);
return gregorianCalendar.getMillis();
} finally {
recycleCalendar(gregorianCalendar);
}
}
public String toString() {
return toString( year, month, day, hour, minute, second, millis );
}
public static String toString( long ms ) {
return new DateStruct(ms).toString();
}
public static String toString( java.util.Date dt ) {
// return TFormatter.getDefaultDateFormatter().format(dt);
return new DateStruct(dt).toString();
}
public static String toString(int year, int month, int day, int hour, int minute, int second, int millis) {
return StringUtil.format( "{0}-{1}-{2}", //$NON-NLS-1$
StringUtil.toString(year),
StringUtil.toString(month),
StringUtil.toString(day))
+ StringUtil.format( " {0}:{1}:{2}", //.{3}", //$NON-NLS-1$
StringUtil.toString(hour),
StringUtil.toString(minute),
StringUtil.toString(second) );
// StringUtil.toString(millis));
}
public static int getYear( long dt ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.setMillis(dt);
return gregorianCalendar.get(Calendar.YEAR);
} finally {
recycleCalendar(gregorianCalendar);
}
}
public static int getYear( java.util.Date dt ) {
return getYear(dt.getTime());
}
public static int getMonth( long dt ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.setMillis(dt);
return gregorianCalendar.get(Calendar.MONTH)+1;
} finally {
recycleCalendar(gregorianCalendar);
}
}
public static int getMonth( java.util.Date dt ) {
return getMonth(dt.getTime());
}
public static int getDay( long dt ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.setMillis(dt);
return gregorianCalendar.get(Calendar.DAY_OF_MONTH);
} finally {
recycleCalendar(gregorianCalendar);
}
}
public static int getDay( java.util.Date dt ) {
return getDay(dt.getTime());
}
public static int getHour( long dt ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.setMillis(dt);
return gregorianCalendar.get(Calendar.HOUR_OF_DAY);
} finally {
recycleCalendar(gregorianCalendar);
}
}
public static int getHour( java.util.Date dt ) {
return getHour(dt.getTime());
}
public static int getMinute( long dt ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.setMillis(dt);
return gregorianCalendar.get(Calendar.MINUTE);
} finally {
recycleCalendar(gregorianCalendar);
}
}
public static int getMinute( java.util.Date dt ) {
return getMinute(dt.getTime());
}
public static int getSecond( long dt ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.setMillis(dt);
return gregorianCalendar.get(Calendar.SECOND);
} finally {
recycleCalendar(gregorianCalendar);
}
}
public static int getSecond( java.util.Date dt ) {
return getSecond(dt.getTime());
}
public static int getMilliSecond( long dt ) {
TGregorianCalendar gregorianCalendar = getCalendar();
try {
gregorianCalendar.setMillis(dt);
return gregorianCalendar.get(Calendar.MILLISECOND);
} finally {
recycleCalendar(gregorianCalendar);
}
}
public static int getMilliSecond( java.util.Date dt ) {
return getMilliSecond(dt.getTime());
}
public int day;
public int month;
public int year;
public int hour;
public int minute;
public int second;
public int millis;
}
/*
* We need to derive the gregorian calendar because getTimeInMillis() &
* setTimeInMillis() are protected (?!?) in the Calendar class.
*/
public static final class TGregorianCalendar extends GregorianCalendar {
private static final long serialVersionUID = 1L;
public final long getMillis() {
return getTimeInMillis();
}
public final void setMillis(long ms) {
setTimeInMillis(ms);
}
}
private static TGregorianCalendar[] gregorianCalendars = new TGregorianCalendar[16];
private static int gcCount = 0;
/**
* To obtain a TGregorianCalendar.
* Remember to call recycleCalendar when object is no more used.
* @ibm-not-published
*/
public static TGregorianCalendar getCalendar() {
synchronized(gregorianCalendars) {
if( gcCount==0 ) {
return new TGregorianCalendar();
}
return gregorianCalendars[--gcCount];
}
}
/**
* @ibm-not-published
*/
public static void recycleCalendar( TGregorianCalendar cal ) {
recycleCalendar(cal, true); // TODO Mark: Check this with Phil
}
/**
* @ibm-not-published
*/
public static void recycleCalendar( TGregorianCalendar cal, boolean resetTZ ) {
if(resetTZ) {
cal.setTimeZone(TimeZone.getDefault());
}
synchronized(gregorianCalendars) {
if( gcCount<gregorianCalendars.length ) {
gregorianCalendars[gcCount++] = cal;
}
}
}
}