001    package railo.runtime.format;
002    
003    import java.util.Calendar;
004    import java.util.Date;
005    import java.util.Locale;
006    import java.util.TimeZone;
007    
008    import railo.commons.date.JREDateTimeUtil;
009    import railo.commons.lang.StringUtil;
010    import railo.runtime.engine.ThreadLocalPageContext;
011    
012    public final class DateFormat extends BaseFormat implements Format {
013            
014            private final Calendar calendar;
015            
016            /**
017             * constructor of the class
018             * @param locale
019             */
020            public DateFormat(Locale locale) {
021                    super(locale);
022                    calendar=JREDateTimeUtil.newInstance(locale);
023            }
024            
025    
026            /**
027             * formats a date to a cfml date format (short)
028             * @param date
029             * @return formated date
030             */
031            public String format(Date date) {
032                    return format(date,"medium");
033            }
034            
035            /**
036             * formats a date to a cfml date format
037             * @param date
038             * @param mask
039             * @return formated date as string
040             */
041            public String format(Date date,String mask) {
042                    return format(date,mask,null);
043            }
044            public String format(Date date,String mask, TimeZone tz) {
045                    //DateUtil.setTimeZone(null,calendar,date); 
046                    calendar.setTimeZone(tz=ThreadLocalPageContext.getTimeZone(tz));  
047                    calendar.setTime(date);     
048                    
049    
050                    String lcMask=StringUtil.toLowerCase(mask);
051                    if(lcMask.equals("short"))                      return getAsString(java.text.DateFormat.SHORT,tz);
052                    else if(lcMask.equals("medium"))                return getAsString(java.text.DateFormat.MEDIUM,tz);
053                    else if(lcMask.equals("long"))          return getAsString(java.text.DateFormat.LONG,tz);
054                    else if(lcMask.equals("full"))          return getAsString(java.text.DateFormat.FULL,tz);
055                    
056                    int len=mask.length();
057                    int pos=0;
058                    if(len==0) return "";
059                    
060                    StringBuffer formated=new StringBuffer();
061                    
062                    
063                    
064                    for(;pos<len;pos++) {
065                            char c=mask.charAt(pos);
066                            char next=(len>pos+1)?mask.charAt(pos+1):(char)0;
067                            switch(c) {
068    
069                            // d: Day of month. Digits; no leading zero for single-digit days 
070                            // dd: Day of month. Digits; leading zero for single-digit days 
071                            // ddd: Day of week, abbreviation 
072                            // dddd: Day of week. Full name 
073                                    case 'd':
074                                    case 'D':
075                                            char next2=(len>pos+2)?mask.charAt(pos+2):(char)0;
076                                            char next3=(len>pos+3)?mask.charAt(pos+3):(char)0;
077                                            
078                                            int day=calendar.get(Calendar.DATE);
079                                            if(next=='d' || next=='D') {
080                                                    if(next2=='d' || next2=='D') {
081                                                            if(next3=='d' || next3=='D') {
082                                                                    formated.append(getDayOfWeekAsString(calendar.get(Calendar.DAY_OF_WEEK)));
083                                                                    pos+=3;
084                                                            }
085                                                            else {
086                                                                    formated.append(getDayOfWeekShortAsString(calendar.get(Calendar.DAY_OF_WEEK)));
087                                                                    pos+=2;                                                         
088                                                            }
089                                                    }
090                                                    else {
091                                                            formated.append(day<10?"0"+day:""+day);
092                                                            pos++;
093                                                    }
094                                            }
095                                            else {
096                                                    formated.append(day);
097                                            }                                       
098                                    break;
099    
100                            // m: Month. Digits; no leading zero for single-digit months 
101                            // mm: Month. Digits; leading zero for single-digit months 
102                            // mmm: Month. abbreviation (if appropriate) 
103                            // mmmm: Month. Full name 
104                                    case 'm':
105                                    case 'M':
106                                            char next_2=(len>pos+2)?mask.charAt(pos+2):(char)0;
107                                            char next_3=(len>pos+3)?mask.charAt(pos+3):(char)0;
108                                            
109                                            int month=calendar.get(Calendar.MONTH)+1;
110                                            if(next=='m' || next=='M') {
111                                                    if(next_2=='m' || next_2=='M') {
112                                                            if(next_3=='m' || next_3=='M') {
113                                                                    formated.append(getMonthAsString(month));
114                                                                    pos+=3;
115                                                            }
116                                                            else {
117                                                                    formated.append(getMonthShortAsString(month));
118                                                                    pos+=2;                                                         
119                                                            }
120                                                    }
121                                                    else {
122                                                            formated.append(month<10?"0"+month:""+month);
123                                                            pos++;
124                                                    }
125                                            }
126                                            else {
127                                                    formated.append(month);
128                                            }                                       
129                                    break;
130    
131                            // y: Year. Last two digits; no leading zero for years less than 10 
132                            // yy: Year. Last two digits; leading zero for years less than 10 
133                            // yyyy: Year. Four digits 
134                                    case 'y':
135                                    case 'Y':
136                                            char next__2=(len>pos+2)?mask.charAt(pos+2):(char)0;
137                                            char next__3=(len>pos+3)?mask.charAt(pos+3):(char)0;
138                                            
139                                            int year4=calendar.get(Calendar.YEAR);
140                                            int year2=year4%100;
141                                            if(next=='y' || next=='Y') {
142                                                    if((next__2=='y' || next__2=='Y') && (next__3=='y' || next__3=='Y')) {
143                                                            formated.append(year4);
144                                                            pos+=3;
145                                                    }
146                                                    else {
147                                                            formated.append(year2<10?"0"+year2:""+year2);
148                                                            pos++;
149                                                    }
150                                            }
151                                            else {
152                                                    formated.append(year2);
153                                            }                                       
154                                    break;
155                                    
156                            // Otherwise
157                                    default:
158                                            formated.append(c);
159                            }
160                    }
161                    return formated.toString();
162            }
163            
164    
165            private String getAsString(int style, TimeZone tz) {
166                    java.text.DateFormat df = java.text.DateFormat.getDateInstance(style,getLocale());
167                    df.setTimeZone(tz);
168                    
169                    return df.format(calendar.getTime());   
170            }
171            
172    }