blob: 0fd191f1d2630a299c59e65fb466f65c110eec1e [file] [log] [blame]
/*
* Copyright (C) 2005 db4objects Inc. http://www.db4o.com
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* db4objects - Initial API and implementation
* Tom Schindl<tom.schindl@bestsolution.at> - bugfix for 217940
*/
package org.eclipse.core.internal.databinding.conversion;
import java.text.ParsePosition;
import java.util.Date;
import org.eclipse.core.internal.databinding.BindingMessages;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
/**
* Base support for date/string conversion handling according to the default
* locale or in plain long milliseconds.
* <p>
* NOTE: parse(format(date)) will generally *not* be equal to date, since the
* string representation may not cover the sub-second range, time-only string
* representations will be counted from the beginning of the era, etc.
* </p>
*/
public abstract class DateConversionSupport {
private final static int DATE_FORMAT=DateFormat.SHORT;
private final static int DEFAULT_FORMATTER_INDEX=0;
private final static int NUM_VIRTUAL_FORMATTERS=1;
/**
* Alternative formatters for date, time and date/time.
* Raw milliseconds are covered as a special case.
*/
// TODO: These could be shared, but would have to be synchronized.
private DateFormat[] formatters = {
new SimpleDateFormat(BindingMessages.getString(BindingMessages.DATE_FORMAT_DATE_TIME)),
new SimpleDateFormat(BindingMessages.getString(BindingMessages.DATEFORMAT_TIME)),
DateFormat.getDateTimeInstance(DATE_FORMAT, DateFormat.SHORT),
DateFormat.getDateInstance(DATE_FORMAT),
DateFormat.getTimeInstance(DateFormat.SHORT),
DateFormat.getDateTimeInstance(DATE_FORMAT,DateFormat.MEDIUM),
DateFormat.getTimeInstance(DateFormat.MEDIUM)
};
/**
* Tries all available formatters to parse the given string according to the
* default locale or as a raw millisecond value and returns the result of the
* first successful run.
*
* @param str A string specifying a date according to the default locale or in raw milliseconds
* @return The parsed date, or null, if no available formatter could interpret the input string
*/
protected Date parse(String str) {
for (int formatterIdx = 0; formatterIdx < formatters.length; formatterIdx++) {
Date parsed=parse(str,formatterIdx);
if(parsed!=null) {
return parsed;
}
}
return null;
}
protected Date parse(String str,int formatterIdx) {
if(formatterIdx>=0) {
ParsePosition pos=new ParsePosition(0);
if (str == null) {
return null;
}
Date date=formatters[formatterIdx].parse(str,pos);
if(pos.getErrorIndex()!=-1||pos.getIndex()!=str.length()) {
return null;
}
return date;
}
try {
long millisecs=Long.parseLong(str);
return new Date(millisecs);
}
catch(NumberFormatException exc) {
}
return null;
}
/**
* Formats the given date with the default formatter according to the default locale.
* @param date a date
* @return a string representation of the given date according to the default locale
*/
protected String format(Date date) {
return format(date,DEFAULT_FORMATTER_INDEX);
}
protected String format(Date date,int formatterIdx) {
if(formatterIdx>=0) {
return formatters[formatterIdx].format(date);
}
return String.valueOf(date.getTime());
}
protected int numFormatters() {
return formatters.length+NUM_VIRTUAL_FORMATTERS;
}
/**
* Returns the date format for the provided <code>index</code>.
* <p>
* This is for testing purposes only and should not be a part of the API if
* this class was to be exposed.
* </p>
*
* @param index
* @return date format
*/
protected DateFormat getDateFormat(int index) {
if (index < 0 || index >= formatters.length) {
throw new IllegalArgumentException("'index' [" + index + "] is out of bounds."); //$NON-NLS-1$//$NON-NLS-2$
}
return formatters[index];
}
}