001    package railo.commons.date;
002    
003    import java.util.Calendar;
004    import java.util.HashMap;
005    import java.util.Locale;
006    import java.util.Map;
007    import java.util.TimeZone;
008    
009    import railo.runtime.engine.ThreadLocalPageContext;
010    import railo.runtime.op.Caster;
011    import railo.runtime.type.dt.DateTime;
012    
013    public class JREDateTimeUtil extends DateTimeUtil {
014            
015            private static CalendarThreadLocal calendar=new CalendarThreadLocal();
016            
017            private Calendar year;
018            private Calendar month;
019            private Calendar day;
020            private Calendar hour;
021            private Calendar minute;
022            private Calendar second;
023            private Calendar milliSecond;
024            //private Calendar dayOfYear;
025            //private Calendar dayOfWeek;
026            //private Calendar week;
027            //private Calendar time;
028            private Calendar milliSecondsInDay;
029            private Calendar daysInMonth;
030            Calendar string;
031    
032            //private static Map tzCalendars=new HashMap();
033            private static Map<Locale,Calendar> localeCalendars=new HashMap<Locale,Calendar>();
034            
035            
036            
037            JREDateTimeUtil() {
038                    
039            }
040    
041             long _toTime(TimeZone tz, int year, int month, int day, int hour,int minute, int second, int milliSecond) {
042                    tz=ThreadLocalPageContext.getTimeZone(tz);
043                    Calendar time = getCalendar(tz);
044                    synchronized(time){
045                            time.set(year,month-1,day,hour,minute,second);
046                            time.set(Calendar.MILLISECOND,milliSecond);  
047                    return time.getTimeInMillis();
048                    }
049            
050            }
051    
052            private static int get(Calendar calendar,TimeZone tz, DateTime dt, int field) {
053                    //synchronized (calendar) {
054                            calendar.setTimeZone(tz); 
055                    calendar.setTimeInMillis(dt.getTime());         
056                    return calendar.get(field);
057            //}
058            }
059    
060            @Override
061            public synchronized int getYear(TimeZone tz, DateTime dt) {
062                    if(year==null)year=newInstance();
063                    return get(year,tz,dt,Calendar.YEAR);
064            }
065    
066            @Override
067            public synchronized int getMonth(TimeZone tz, DateTime dt) {
068                    if(month==null)month=newInstance();
069                    return get(month,tz,dt,Calendar.MONTH)+1;
070            }
071    
072            @Override
073            public synchronized int getDay(TimeZone tz, DateTime dt) {
074                    if(day==null)day=newInstance();
075                    return get(day,tz,dt,Calendar.DAY_OF_MONTH);
076            }
077    
078            @Override
079            public synchronized int getHour(TimeZone tz, DateTime dt) {
080                    if(hour==null)hour=newInstance();
081                    return get(hour,tz,dt,Calendar.HOUR_OF_DAY);
082            }
083    
084            @Override
085            public synchronized int getMinute(TimeZone tz, DateTime dt) {
086                    if(minute==null)minute=newInstance();
087                    return get(minute,tz,dt,Calendar.MINUTE);
088            }
089    
090            @Override
091            public synchronized int getSecond(TimeZone tz, DateTime dt) {
092                    if(second==null)second=newInstance();
093                    return get(second,tz,dt,Calendar.SECOND);
094            }
095    
096            @Override
097            public synchronized int getMilliSecond(TimeZone tz, DateTime dt) {
098                    if(milliSecond==null)milliSecond=newInstance();
099                    return get(milliSecond,tz,dt,Calendar.MILLISECOND);
100            }
101    
102            @Override
103            public synchronized int getWeekOfYear(Locale locale,TimeZone tz, DateTime dt) {
104                    Calendar c=getCalendar(locale);
105                    synchronized (c) {
106                            c.setTimeZone(tz); 
107                    c.setTimeInMillis(dt.getTime());         
108                    int week=c.get(Calendar.WEEK_OF_YEAR);
109                            
110                            if(week==1 && c.get(Calendar.MONTH)==Calendar.DECEMBER) {
111                                    if(isLeapYear(c.get(Calendar.YEAR)) && c.get(Calendar.DAY_OF_WEEK)==1){
112                                            return 54;
113                                    }
114                                    return 53;
115                            }
116                            return week;
117                    }
118            }
119    
120            @Override
121            public synchronized int getDayOfYear(Locale locale,TimeZone tz, DateTime dt) {
122                    Calendar c=getCalendar(locale);
123                    synchronized (c) {
124                            return get(c,tz,dt,Calendar.DAY_OF_YEAR);
125                    }
126            }
127    
128            @Override
129            public synchronized int getDayOfWeek(Locale locale,TimeZone tz, DateTime dt) {
130                    Calendar c=getCalendar(locale);
131                    synchronized (c) {
132                            return get(c,tz,dt,Calendar.DAY_OF_WEEK);
133                    }
134            }
135    
136            public synchronized long getMilliSecondsInDay(TimeZone tz,long time) {
137                    if(milliSecondsInDay==null)milliSecondsInDay=newInstance();
138                    milliSecondsInDay.clear();
139                    milliSecondsInDay.setTimeZone(ThreadLocalPageContext.getTimeZone(tz));
140                    milliSecondsInDay.setTimeInMillis(time);         
141            return  (milliSecondsInDay.get(Calendar.HOUR_OF_DAY)*3600000)+
142                    (milliSecondsInDay.get(Calendar.MINUTE)*60000)+
143                    (milliSecondsInDay.get(Calendar.SECOND)*1000)+
144                    (milliSecondsInDay.get(Calendar.MILLISECOND));
145        }
146    
147            public synchronized int getDaysInMonth(TimeZone tz, DateTime dt) {
148                    if(daysInMonth==null)daysInMonth=newInstance();
149                    daysInMonth.clear();
150                    daysInMonth.setTimeZone(tz); 
151                    daysInMonth.setTime(dt);         
152                    return daysInMonth(daysInMonth.get(Calendar.YEAR), daysInMonth.get(Calendar.MONTH)+1);
153            }
154    
155            public long getDiff(TimeZone tz, int datePart, DateTime left, DateTime right) {
156                    
157                    return 0;
158            }
159    
160            public synchronized String toString(DateTime dt, TimeZone tz) {
161                    if(string==null)string=newInstance();
162                    //synchronized (string) {
163                            tz=ThreadLocalPageContext.getTimeZone(tz);
164                            string.setTimeZone(tz);
165                            string.setTimeInMillis(dt.getTime());
166                            //"HH:mm:ss"
167                            StringBuilder sb=new StringBuilder();
168                    
169                    sb.append("{ts '");
170                    toString(sb,string.get(Calendar.YEAR),4);
171                    sb.append("-");
172                    toString(sb,string.get(Calendar.MONTH)+1,2);
173                    sb.append("-");
174                    toString(sb,string.get(Calendar.DATE),2);
175                    sb.append(" ");
176                    toString(sb,string.get(Calendar.HOUR_OF_DAY),2);
177                    sb.append(":");
178                    toString(sb,string.get(Calendar.MINUTE),2);
179                    sb.append(":");
180                    toString(sb,string.get(Calendar.SECOND),2);
181                    sb.append("'}");
182                     
183                    return sb.toString();
184            //}
185            }
186    
187    
188            public static Calendar newInstance() {
189                    return Calendar.getInstance(Locale.US);
190            }
191            
192            public static Calendar newInstance(Locale l) {
193                    return Calendar.getInstance(l);
194            }
195    
196            public static Calendar newInstance(TimeZone tz) {
197                    return Calendar.getInstance(tz,Locale.US);
198            }
199    
200            public static Calendar getCalendar(Locale l) {
201                    Calendar c=localeCalendars.get(l);
202                    if(c==null){
203                            c=Calendar.getInstance(l);
204                            localeCalendars.put(l, c);
205                    }
206                    return c;
207            }
208            
209            public static Calendar getCalendar(){
210                    return calendar.get();
211            }
212            
213            public static Calendar getCalendar(TimeZone tz){
214                    Calendar c=getCalendar();
215                    c.setTimeZone(tz);
216                    return c;
217            }
218            
219            
220            /*public  static Calendar newInstance(Locale l) {
221                    Calendar c=Calendar.getInstance(l);
222                    return c;
223            }*/
224    
225            void toString(StringBuilder sb,int i, int amount) {
226                    String str = Caster.toString(i);
227                    while(str.length()<(amount--)){
228                            sb.append( '0');
229                    }
230                    sb.append(str);
231            }
232    }
233    
234    
235    class CalendarThreadLocal extends ThreadLocal<Calendar> {
236            protected synchronized Calendar initialValue() {
237            return Calendar.getInstance();
238        }
239    }