001 package railo.runtime.format; 002 003 import java.text.DateFormat; 004 import java.util.Calendar; 005 import java.util.Date; 006 import java.util.Locale; 007 import java.util.TimeZone; 008 009 import railo.commons.date.JREDateTimeUtil; 010 import railo.commons.lang.StringUtil; 011 import railo.runtime.engine.ThreadLocalPageContext; 012 import railo.runtime.functions.dateTime.Beat; 013 import railo.runtime.op.Caster; 014 import railo.runtime.type.dt.DateTime; 015 import railo.runtime.type.dt.DateTimeImpl; 016 017 public final class TimeFormat extends BaseFormat implements Format { 018 019 private final Calendar calendar; 020 021 022 /** 023 * constructor of the class 024 * @param locale 025 */ 026 public TimeFormat(Locale locale) { 027 super(locale); 028 calendar=JREDateTimeUtil.newInstance(locale); 029 } 030 031 032 /** 033 * formats a date to a cfml date format (short) 034 * @param date 035 * @return formated date 036 */ 037 public String format(Date date) { 038 return format(date,"short"); 039 } 040 041 /** 042 * formats a date to a cfml date format 043 * @param date 044 * @param mask 045 * @return formated date 046 */ 047 public String format(Date date,String mask) { 048 DateTime dt=(date instanceof DateTime)?(DateTime)date:new DateTimeImpl(date.getTime(),false); 049 return format(dt,mask,null); 050 } 051 052 053 public String format(DateTime date,String mask, TimeZone tz) { 054 //DateUtil.setTimeZone(null,calendar,date); 055 calendar.setTimeZone(tz=ThreadLocalPageContext.getTimeZone(tz)); 056 calendar.setTime(date); 057 058 059 String lcMask=StringUtil.toLowerCase(mask); 060 if(lcMask.equals("short")) return getAsString(DateFormat.SHORT,tz); 061 else if(lcMask.equals("medium")) return getAsString(DateFormat.MEDIUM,tz); 062 else if(lcMask.equals("long")) return getAsString(DateFormat.LONG,tz); 063 else if(lcMask.equals("full")) return getAsString(DateFormat.FULL,tz); 064 else if(lcMask.equals("beat")) { 065 return Caster.toString(Beat.format(date)); 066 } 067 068 int len=mask.length(); 069 int pos=0; 070 if(len==0) return ""; 071 072 StringBuffer formated=new StringBuffer(); 073 074 075 076 for(;pos<len;pos++) { 077 char c=mask.charAt(pos); 078 char next=(len>pos+1)?mask.charAt(pos+1):(char)0; 079 080 switch(c) { 081 082 // h: Hours; no leading zero for single-digit hours (12-hour clock) 083 // hh: Hours; leading zero for single-digit hours. (12-hour clock) 084 case 'h': 085 int hour1=calendar.get(Calendar.HOUR_OF_DAY); 086 if(hour1==0)hour1=12; 087 if(hour1>12)hour1=hour1-12; 088 if(next=='h') { 089 formated.append(hour1<10?"0"+hour1:""+hour1); 090 pos++; 091 } 092 else { 093 formated.append(hour1); 094 } 095 break; 096 097 // H: Hours; no leading zero for single-digit hours (24-hour clock) 098 // HH: Hours; leading zero for single-digit hours (24-hour clock) 099 case 'H': 100 int hour2=calendar.get(Calendar.HOUR_OF_DAY); 101 if(next=='H') { 102 formated.append(hour2<10?"0"+hour2:""+hour2); 103 pos++; 104 } 105 else { 106 formated.append(hour2); 107 } 108 break; 109 110 // m: Minutes; no leading zero for single-digit minutes 111 // mm: Minutes; leading zero for single-digit minutes 112 case 'M': 113 case 'm': 114 int minute=calendar.get(Calendar.MINUTE); 115 if(next=='M' || next=='m') { 116 formated.append(minute<10?"0"+minute:""+minute); 117 pos++; 118 } 119 else { 120 formated.append(minute); 121 } 122 break; 123 124 // s: Seconds; no leading zero for single-digit seconds 125 // ss: Seconds; leading zero for single-digit seconds 126 case 's': 127 case 'S': 128 int second=calendar.get(Calendar.SECOND); 129 if(next=='S' || next=='s') { 130 formated.append(second<10?"0"+second:""+second); 131 pos++; 132 } 133 else { 134 formated.append(second); 135 } 136 break; 137 138 // l: Milliseconds 139 case 'l': 140 case 'L': 141 char nextnext=(len>pos+2)?mask.charAt(pos+2):(char)0; 142 143 String millis=Caster.toString(calendar.get(Calendar.MILLISECOND)); 144 if(next=='L' || next=='l') { 145 if(millis.length()==1)millis="0"+millis; 146 pos++; 147 } 148 if(nextnext=='L' || nextnext=='l') { 149 if(millis.length()==2)millis="0"+millis; 150 pos++; 151 } 152 formated.append(millis); 153 154 155 156 break; 157 158 // t: One-character time marker string, such as A or P. 159 // tt: Multiple-character time marker string, such as AM or PM 160 case 't': 161 case 'T': 162 boolean isAm=calendar.get(Calendar.HOUR_OF_DAY)<12; 163 if(next=='T' || next=='t') { 164 formated.append(isAm?"AM":"PM"); 165 pos++; 166 } 167 else { 168 formated.append(isAm?"A":"P"); 169 } 170 break; 171 case 'z': 172 case 'Z': 173 // count next z and jump to last z (max 6) 174 int start=pos; 175 while((pos+1)<len && Character.toLowerCase(mask.charAt(pos+1))=='z'){ 176 pos++; 177 if(pos-start>4)break; 178 } 179 if(pos-start>2)formated.append(tz.getDisplayName(getLocale())); 180 else formated.append(tz.getID()); 181 182 break; 183 184 // Otherwise 185 default: 186 formated.append(c); 187 } 188 } 189 return formated.toString(); 190 } 191 192 private String getAsString(int style,TimeZone tz) { 193 DateFormat df = DateFormat.getTimeInstance(style,getLocale()); 194 df.setTimeZone(tz); 195 return df.format(calendar.getTime()); 196 } 197 198 }