package railo.commons.date;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.op.Caster;
import railo.runtime.type.dt.DateTime;
public class JREDateTimeUtil extends DateTimeUtil {
private static CalendarThreadLocal _calendar=new CalendarThreadLocal();
private static CalendarThreadLocal calendar=new CalendarThreadLocal();
private static LocaleCalendarThreadLocal _localeCalendar=new LocaleCalendarThreadLocal();
private static LocaleCalendarThreadLocal localeCalendar=new LocaleCalendarThreadLocal();
//Calendar string;
JREDateTimeUtil() {
}
long _toTime(TimeZone tz, int year, int month, int day, int hour,int minute, int second, int milliSecond) {
if(tz==null)tz=ThreadLocalPageContext.getTimeZone(tz);
Calendar time = _getThreadCalendar(tz);
time.set(year,month-1,day,hour,minute,second);
time.set(Calendar.MILLISECOND,milliSecond);
return time.getTimeInMillis();
}
private static int _get(TimeZone tz, DateTime dt, int field) {
Calendar c = _getThreadCalendar(tz);
c.setTimeInMillis(dt.getTime());
return c.get(field);
}
private static int _get(Locale l,TimeZone tz, DateTime dt, int field) {
Calendar c = _getThreadCalendar(l,tz);
c.setTimeInMillis(dt.getTime());
return c.get(field);
}
@Override
public int getYear(TimeZone tz, DateTime dt) {
return _get(tz,dt,Calendar.YEAR);
}
@Override
public int getMonth(TimeZone tz, DateTime dt) {
return _get(tz,dt,Calendar.MONTH)+1;
}
@Override
public int getDay(TimeZone tz, DateTime dt) {
return _get(tz,dt,Calendar.DAY_OF_MONTH);
}
@Override
public int getHour(TimeZone tz, DateTime dt) {
return _get(tz,dt,Calendar.HOUR_OF_DAY);
}
@Override
public int getMinute(TimeZone tz, DateTime dt) {
return _get(tz,dt,Calendar.MINUTE);
}
@Override
public int getSecond(TimeZone tz, DateTime dt) {
return _get(tz,dt,Calendar.SECOND);
}
@Override
public int getMilliSecond(TimeZone tz, DateTime dt) {
return _get(tz,dt,Calendar.MILLISECOND);
}
@Override
public synchronized int getDayOfYear(Locale locale,TimeZone tz, DateTime dt) {
return _get(locale,tz,dt,Calendar.DAY_OF_YEAR);
}
@Override
public synchronized int getDayOfWeek(Locale locale,TimeZone tz, DateTime dt) {
return _get(locale,tz,dt,Calendar.DAY_OF_WEEK);
}
@Override
public synchronized int getFirstDayOfMonth(TimeZone tz, DateTime dt) {
Calendar c = _getThreadCalendar(tz);
c.setTimeInMillis(dt.getTime());
c.set(Calendar.DATE,1);
return c.get(Calendar.DAY_OF_YEAR);
}
@Override
public synchronized int getWeekOfYear(Locale locale,TimeZone tz, DateTime dt) {
Calendar c=_getThreadCalendar(locale,tz);
c.setTimeInMillis(dt.getTime());
int week=c.get(Calendar.WEEK_OF_YEAR);
if(week==1 && c.get(Calendar.MONTH)==Calendar.DECEMBER) {
if(isLeapYear(c.get(Calendar.YEAR)) && c.get(Calendar.DAY_OF_WEEK)==1){
return 54;
}
return 53;
}
return week;
}
public synchronized long getMilliSecondsInDay(TimeZone tz,long time) {
Calendar c = _getThreadCalendar(tz);
c.setTimeInMillis(time);
return (c.get(Calendar.HOUR_OF_DAY)*3600000)+
(c.get(Calendar.MINUTE)*60000)+
(c.get(Calendar.SECOND)*1000)+
(c.get(Calendar.MILLISECOND));
}
public synchronized int getDaysInMonth(TimeZone tz, DateTime dt) {
Calendar c = _getThreadCalendar(tz);
c.setTimeInMillis(dt.getTime());
return daysInMonth(c.get(Calendar.YEAR), c.get(Calendar.MONTH)+1);
}
public String toString(DateTime dt, TimeZone tz) {
Calendar c = _getThreadCalendar(tz);
c.setTimeInMillis(dt.getTime());
//"HH:mm:ss"
StringBuilder sb=new StringBuilder();
sb.append("{ts '");
toString(sb,c.get(Calendar.YEAR),4);
sb.append("-");
toString(sb,c.get(Calendar.MONTH)+1,2);
sb.append("-");
toString(sb,c.get(Calendar.DATE),2);
sb.append(" ");
toString(sb,c.get(Calendar.HOUR_OF_DAY),2);
sb.append(":");
toString(sb,c.get(Calendar.MINUTE),2);
sb.append(":");
toString(sb,c.get(Calendar.SECOND),2);
sb.append("'}");
return sb.toString();
}
public static Calendar newInstance() {
return Calendar.getInstance(Locale.US);
}
public static Calendar newInstance(Locale l) {
return Calendar.getInstance(l);
}
public static Calendar newInstance(TimeZone tz) {
if(tz==null)tz=ThreadLocalPageContext.getTimeZone();
return Calendar.getInstance(tz,Locale.US);
}
public static Calendar newInstance(TimeZone tz,Locale l) {
if(tz==null)tz=ThreadLocalPageContext.getTimeZone();
return Calendar.getInstance(tz,l);
}
/**
* important:this function returns always the same instance for a specific thread,
* so make sure only use one thread calendar instance at time.
* @return calendar instance
*/
public static Calendar getThreadCalendar(){
Calendar c = calendar.get();
c.clear();
return c;
}
/**
* important:this function returns always the same instance for a specific thread,
* so make sure only use one thread calendar instance at time.
* @return calendar instance
*/
public static Calendar getThreadCalendar(TimeZone tz){
Calendar c = calendar.get();
c.clear();
if(tz==null)tz=ThreadLocalPageContext.getTimeZone();
c.setTimeZone(tz);
return c;
}
/**
* important:this function returns always the same instance for a specific thread,
* so make sure only use one thread calendar instance at time.
* @return calendar instance
*/
public static Calendar getThreadCalendar(Locale l){
return localeCalendar.get(l);
}
/**
* important:this function returns always the same instance for a specific thread,
* so make sure only use one thread calendar instance at time.
* @return calendar instance
*/
public static Calendar getThreadCalendar(Locale l,TimeZone tz){
Calendar c = localeCalendar.get(l);
if(tz==null)tz=ThreadLocalPageContext.getTimeZone();
c.setTimeZone(tz);
return c;
}
/*
* internally we use a other instance to avoid conflicts
*/
private static Calendar _getThreadCalendar(TimeZone tz){
Calendar c = _calendar.get();
c.clear();
if(tz==null)tz=ThreadLocalPageContext.getTimeZone();
c.setTimeZone(tz);
return c;
}
/*
* internally we use a other instance to avoid conflicts
*/
private static Calendar _getThreadCalendar(Locale l,TimeZone tz){
Calendar c = _localeCalendar.get(l);
if(tz==null)tz=ThreadLocalPageContext.getTimeZone();
c.setTimeZone(tz);
return c;
}
/*public static Calendar newInstance(Locale l) {
Calendar c=Calendar.getInstance(l);
return c;
}*/
static void toString(StringBuilder sb,int i, int amount) {
String str = Caster.toString(i);
amount = amount - str.length();
while( amount-- > 0 ){
sb.append( '0');
}
sb.append(str);
}
}
class CalendarThreadLocal extends ThreadLocal<Calendar> {
protected synchronized Calendar initialValue() {
return Calendar.getInstance();
}
}
class LocaleCalendarThreadLocal extends ThreadLocal<Map<Locale,Calendar>> {
protected synchronized Map<Locale,Calendar> initialValue() {
return new HashMap<Locale, Calendar>();
}
public Calendar get(Locale l) {
Map<Locale, Calendar> map = get();
Calendar c = map.get(l);
if(c==null) {
c=JREDateTimeUtil.newInstance(l);
map.put(l, c);
}
else c.clear();
return c;
}
}