package org.exist.xquery.value;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* Centralizes access to time-related utility functions. Mostly delegates to the
* XML datatype factory, serving as a central chokepoint to control concurrency
* issues. It's not clear if instances of the factory are in fact thread-safe or not;
* if they turn out not to be, it will be easy to either synchronize access or create
* more instances here as required.
*
* @author <a href="mailto:piotr@ideanest.com">Piotr Kaminski</a>
*/
public class TimeUtils {
private static final TimeUtils INSTANCE = new TimeUtils();
public static TimeUtils getInstance() {return INSTANCE;}
// assume it's thread-safe, if not synchronize all access
private final DatatypeFactory factory;
private int timezoneOffset;
private boolean timezoneOverriden;
private TimeUtils() {
// singleton, keep constructor private
try {
factory = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e) {
throw new RuntimeException("unable to instantiate an XML datatype factory", e);
}
}
/**
* Set the offset of the local timezone, ignoring the default provided by the OS.
* Mainly useful for testing.
*
* @param millis the timezone offset in milliseconds, positive or negative
*/
public void overrideLocalTimezoneOffset(int millis) {
timezoneOffset = millis;
timezoneOverriden = true;
}
/**
* Cancel any timezone override that may be in effect, reverting back to the OS value.
*/
public void resetLocalTimezoneOffset() {
timezoneOverriden = false;
}
public int getLocalTimezoneOffsetMillis() {
int dstOffset = Calendar.getInstance(TimeZone.getDefault()).get(Calendar.DST_OFFSET);
return timezoneOverriden ? timezoneOffset : TimeZone.getDefault().getRawOffset() + dstOffset;
}
public int getLocalTimezoneOffsetMinutes() {
return getLocalTimezoneOffsetMillis() / 60000;
}
public Duration newDuration(long arg0) {
return factory.newDuration(arg0);
}
public Duration newDuration(String arg0) {
return factory.newDuration(arg0);
}
public Duration newDuration(boolean arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) {
return factory.newDuration(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}
public Duration newDuration(boolean arg0, BigInteger arg1, BigInteger arg2, BigInteger arg3, BigInteger arg4, BigInteger arg5, BigDecimal arg6) {
return factory.newDuration(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}
public Duration newDurationDayTime(long arg0) {
return factory.newDurationDayTime(arg0);
}
public Duration newDurationDayTime(String arg0) {
return factory.newDurationDayTime(arg0);
}
public Duration newDurationDayTime(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
return factory.newDurationDayTime(arg0, arg1, arg2, arg3, arg4);
}
public Duration newDurationDayTime(boolean arg0, BigInteger arg1, BigInteger arg2, BigInteger arg3, BigInteger arg4) {
return factory.newDurationDayTime(arg0, arg1, arg2, arg3, arg4);
}
public Duration newDurationYearMonth(long arg0) {
return factory.newDurationYearMonth(arg0);
}
public Duration newDurationYearMonth(String arg0) {
return factory.newDurationYearMonth(arg0);
}
public Duration newDurationYearMonth(boolean arg0, int arg1, int arg2) {
return factory.newDurationYearMonth(arg0, arg1, arg2);
}
public Duration newDurationYearMonth(boolean arg0, BigInteger arg1, BigInteger arg2) {
return factory.newDurationYearMonth(arg0, arg1, arg2);
}
public XMLGregorianCalendar newXMLGregorianCalendar() {
return factory.newXMLGregorianCalendar();
}
public XMLGregorianCalendar newXMLGregorianCalendar(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) {
return factory.newXMLGregorianCalendar(arg0, arg1, arg2, arg3, arg4, arg5,
arg6, arg7);
}
public XMLGregorianCalendar newXMLGregorianCalendar(String arg0) {
return factory.newXMLGregorianCalendar(arg0);
}
public XMLGregorianCalendar newXMLGregorianCalendar(BigInteger arg0, int arg1, int arg2, int arg3, int arg4, int arg5, BigDecimal arg6, int arg7) {
return factory.newXMLGregorianCalendar(arg0, arg1, arg2, arg3, arg4, arg5,
arg6, arg7);
}
public XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar arg0) {
return factory.newXMLGregorianCalendar(arg0);
}
public XMLGregorianCalendar newXMLGregorianCalendarDate(int arg0, int arg1, int arg2, int arg3) {
return factory.newXMLGregorianCalendarDate(arg0, arg1, arg2, arg3);
}
public XMLGregorianCalendar newXMLGregorianCalendarTime(int arg0, int arg1, int arg2, int arg3) {
return factory.newXMLGregorianCalendarTime(arg0, arg1, arg2, arg3);
}
public XMLGregorianCalendar newXMLGregorianCalendarTime(int arg0, int arg1, int arg2, int arg3, int arg4) {
return factory.newXMLGregorianCalendarTime(arg0, arg1, arg2, arg3, arg4);
}
public XMLGregorianCalendar newXMLGregorianCalendarTime(int arg0, int arg1, int arg2, BigDecimal arg3, int arg4) {
return factory.newXMLGregorianCalendarTime(arg0, arg1, arg2, arg3, arg4);
}
}