/* DateFormats.java
Purpose:
Description:
History:
91/01/17 15:22:22, Create, Tom M. Yeh.
Copyright (C) 2001 Potix Corporation. All Rights Reserved.
{{IS_RIGHT
This program is distributed under LGPL Version 2.1 in the hope that
it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.text;
import java.util.Locale;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import org.zkoss.util.Locales;
/**
* DateFormat relevant utilities.
*
* @author tomyeh
*/
public class DateFormats {
private final static
InheritableThreadLocal<DateFormatInfo> _thdLocale = new InheritableThreadLocal<DateFormatInfo>();
/** Sets the info of date/time format for the current thread.
* It does not have effect on other threads.
* <p>When Invoking this method under a thread,
* remember to clean up the setting upon completing each request.
*
* <pre><code>DateFormatInfo old = DateFormats.setLocalFormatFormatInfo(info);
*try {
* ...
*} finally {
* DateFormats.setLocalFormatInfo(old);
*}</code></pre>
* @param info the format info. It could be null (and the JVM's default
* is used).
* @return the previous format info being set, or null if not set.
* @since 5.0.7
*/
public static DateFormatInfo setLocalFormatInfo(DateFormatInfo info) {
DateFormatInfo old = _thdLocale.get();
_thdLocale.set(info);
return old;
}
/** Returns the info of date/time format for the current thread,
* or null if not set.
* @since 5.0.7
*/
public static DateFormatInfo getLocalFormatInfo() {
return _thdLocale.get();
}
/** Returns the current date format; never null.
* <p>If a format info is set by {@link #setLocalFormatInfo},
* {@link DateFormatInfo#getDateFormat} of the info will be called first.
* If no info is set or the info returns null,
* <code>java.text.DateFormat.getDateInstance(style, locale)</code>
* will be called instead.
* If no format is found and the value of <code>defaultFormat</code> is not null,
* <code>defaultFormat</code> will be returned.
* Otherwise, "M/d/yy" is returned.
*
* @param style the giving formatting style. For example,
* {@link DateFormat#SHORT} for "M/d/yy" in the US locale.
* @param locale the locale. If null, {@link Locales#getCurrent}
* is assumed.
* @param defaultFormat the default format. It is used if no default
* format. If null, "M/d/yy" is assumed.
* @since 5.0.7
*/
public static
String getDateFormat(int style, Locale locale, String defaultFormat) {
if (locale == null)
locale = Locales.getCurrent();
final DateFormatInfo info = getLocalFormatInfo();
if (info != null) {
final String fmt = info.getDateFormat(style, locale);
if (fmt != null)
return fmt;
}
final DateFormat df = DateFormat.getDateInstance(style, locale);
if (df instanceof SimpleDateFormat) {
final String fmt = ((SimpleDateFormat)df).toPattern();
if (fmt != null && !"M/d/yy h:mm a".equals(fmt))
return fmt; // note: JVM use "M/d/yy h:mm a" if not found!
}
return defaultFormat != null ? defaultFormat: "M/d/yy";
}
/** Returns the current time format; never null.
* <p>If a format info is set by {@link #setLocalFormatInfo},
* {@link DateFormatInfo#getTimeFormat} of the info will be called first.
* If no info is set or the info returns null,
* <code>java.text.DateFormat.getTimeInstance(style, locale)</code>
* will be called instead.
* If no format is found and the value of <code>defaultFormat</code> is not null,
* <code>defaultFormat</code> will be returned.
* Otherwise, "h:mm a" is returned.
*
* @param style the giving formatting style. For example,
* {@link DateFormat#SHORT} for "h:mm a" in the US locale.
* @param locale the locale. If null, {@link Locales#getCurrent}
* is assumed.
* @param defaultFormat the default format. It is used if no default
* format. If null, "h:mm a" is assumed.
* @since 5.0.7
*/
public static final
String getTimeFormat(int style, Locale locale, String defaultFormat) {
if (locale == null)
locale = Locales.getCurrent();
final DateFormatInfo info = getLocalFormatInfo();
if (info != null) {
final String fmt = info.getTimeFormat(style, locale);
if (fmt != null)
return fmt;
}
final DateFormat df = DateFormat.getTimeInstance(style, locale);
if (df instanceof SimpleDateFormat) {
final String fmt = ((SimpleDateFormat)df).toPattern();
if (fmt != null && !"M/d/yy h:mm a".equals(fmt))
return fmt; // note: JVM use "M/d/yy h:mm a" if not found!
}
return "h:mm a";
}
/** Returns the current date/time format; never null.
* <p>If a format info is set by {@link #setLocalFormatInfo},
* {@link DateFormatInfo#getDateTimeFormat} of the info will be called first.
* If no info is set or the info returns null,
* <code>java.text.DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale)</code>
* will be called instead.
* If no format is found and the value of <code>defaultFormat</code> is not null,
* <code>defaultFormat</code> will be returned.
* Otherwise, "M/d/yy h:mm a" is returned.
*
* @param dateStyle the giving formatting style. For example,
* {@link DateFormat#SHORT} for "M/d/yy" in the US locale.
* @param timeStyle the giving formatting style. For example,
* {@link DateFormat#SHORT} for "h:mm a" in the US locale.
* @param locale the locale. If null, {@link Locales#getCurrent}
* is assumed.
* @since 5.0.7
*/
public static final
String getDateTimeFormat(int dateStyle, int timeStyle, Locale locale,
String defaultFormat) {
if (locale == null)
locale = Locales.getCurrent();
final DateFormatInfo info = getLocalFormatInfo();
if (info != null) {
final String fmt = info.getDateTimeFormat(dateStyle, timeStyle, locale);
if (fmt != null)
return fmt;
}
final DateFormat df =
DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
if (df instanceof SimpleDateFormat) {
final String fmt = ((SimpleDateFormat)df).toPattern();
if (fmt != null)
return fmt;
}
return defaultFormat != null ? defaultFormat: "M/d/yy h:mm a";
}
/** Formats a Date object based on the current Locale
* and the default date format ({@link DateFormat#DEFAULT}.
*
* @param dateOnly indicates whether to show only date; false to show
* both date and time
*/
public static final String format(Date d, boolean dateOnly) {
return getDateFormat(dateOnly).format(d);
}
/**
* Parses a string, that is formatted by {@link #format}, to a date.
* It assumes the current locale is {@link Locales#getCurrent}.
*
* @param dateOnly indicates whether to show only date; false to show
* both date and time
* @since 5.0.5
*/
public static final Date parse(String s, boolean dateOnly)
throws ParseException {
return getDateFormat(dateOnly).parse(s);
}
private static final DateFormat getDateFormat(boolean dateOnly) {
final Locale locale = Locales.getCurrent();
return dateOnly ?
DateFormat.getDateInstance(DateFormat.DEFAULT, locale):
DateFormat.getDateTimeInstance(
DateFormat.DEFAULT, DateFormat.DEFAULT, locale);
}
}