1 10 11 package org.mmbase.datatypes; 12 13 import java.text.*; 14 import java.util.*; 15 import org.mmbase.util.LocalizedString; 16 import org.mmbase.util.DateFormats; 17 import org.mmbase.util.logging.Logging; 18 import org.mmbase.util.logging.Logger; 19 20 31 32 public class DateTimePattern implements Cloneable , java.io.Serializable { 33 private static final Logger log = Logging.getLoggerInstance(DateTimePattern.class); 34 35 public static final DateTimePattern DEFAULT = new DateTimePattern("yyyy-MM-dd HH:mm:ss"); 36 37 private static final long serialVersionUID = 1L; 39 protected LocalizedString pattern; 40 41 public DateTimePattern(String pattern) { 42 this.pattern = new LocalizedString(pattern); 43 } 44 45 public void set(String pattern, Locale locale) { 46 this.pattern.set(pattern, locale); 47 } 48 public void set(String pattern) { 49 this.pattern.setKey(pattern); 50 } 51 52 55 public DateFormat getDateFormat(Locale locale) { 56 if (locale == null) locale = LocalizedString.getDefault(); 57 return DateFormats.getInstance(pattern.get(locale), null, locale); 58 } 59 60 61 64 public LocalizedString getPattern() { 65 return pattern; 66 } 67 68 private static final char DONTAPPEND = (char) -1; 69 private static List parse(String p) { 70 List parsed = new ArrayList(); 71 StringBuffer buf = new StringBuffer (); 72 boolean inString = false; 73 boolean inQuote = false; 74 75 char nonStringChar = (char) -1; 76 for (int i = 0; i < p.length(); i++) { 77 char c = p.charAt(i); 78 if ((c >= 'a' && c <= 'z') || 79 (c >= 'A' && c <= 'Z')) { if (inString) { 81 if (! inQuote) { 82 if (buf.length() > 0) { 83 parsed.add(buf.toString()); 84 buf.setLength(0); 85 } 86 inString = false; 87 nonStringChar = c; 88 } 89 } else { 90 if (nonStringChar != c) { 91 parsed.add(buf.toString()); 92 buf.setLength(0); 93 nonStringChar = c; 94 } 95 } 96 } else { 97 if (! inString) { 98 if (i != 0) { 99 parsed.add(buf.toString()); 100 buf.setLength(0); 101 } 102 buf.append("\'"); 103 inQuote = false; 104 inString = true; 105 } 106 if (inString) { 107 if (c == '\'') { 108 if (inQuote && i > 0 && p.charAt(i -1) == '\'') { 109 } else { 111 c = DONTAPPEND; 112 } 113 inQuote = ! inQuote; 114 115 } 116 } 117 118 } 119 if (c != DONTAPPEND) { 120 buf.append(c); 121 } 122 } 123 if (inQuote) { 124 throw new IllegalArgumentException ("Unterminated quote"); 125 } 126 if (buf.length() > 0) { 127 parsed.add(buf.toString()); 128 } 129 return parsed; 130 } 131 132 133 144 public List getList(Locale locale) { 145 String p = pattern.get(locale); 146 return parse(p); 147 } 148 149 private static final Element HOUR_OF_DAY = new Element("hour", Calendar.HOUR_OF_DAY, 0, 23); 150 private static final Element HOUR = new Element("hourinampm", Calendar.HOUR, 0, 11); 151 private static final Element HOUR_OF_DAY_1 = new Element("hour", Calendar.HOUR_OF_DAY, 1, 24, 1); 152 private static final Element HOUR_1 = new Element("hour", Calendar.HOUR, 1, 12, 1); 153 private static final Element MINUTE = new Element("minute", Calendar.MINUTE, 0, 59); 154 private static final Element SECOND = new Element("second", Calendar.SECOND, 0, 59); 155 private static final Element DAY_OF_WEEK = new Element("dayofweek", Calendar.DAY_OF_WEEK, 1, 7) { 156 public String toString(int value, Locale locale, int length) { 157 SimpleDateFormat format = new SimpleDateFormat("EEEEEEEEEEEEE".substring(0, length), locale); 158 Calendar help = Calendar.getInstance(); 159 help.clear(); 160 help.set(field, value); 161 return format.format(help.getTime()); 162 } 163 }; 164 private static final Element WEEK_OF_YEAR = new Element("weekinyear", Calendar.WEEK_OF_YEAR, 1, 53); 165 private static final Element DAY_OF_YEAR = new Element("dayinyear", Calendar.DAY_OF_YEAR, 1, 366); 166 private static final Element DAY_OF_WEEK_IN_MONTH = new Element("dayofweekinmonth", Calendar.DAY_OF_WEEK_IN_MONTH, 1, 5) { 167 public String toString(int value, Locale locale, int length) { 168 if (length > 0) { 169 ResourceBundle bundle = ResourceBundle.getBundle("org.mmbase.datatypes.resources.ordinals", locale); 170 return bundle.getString("" + value); 171 } else { 172 return super.toString(value, locale, length); 173 } 174 } 175 }; 176 177 private static final Element AM_PM = new Element("am_pm", Calendar.AM_PM, 0, 1 ) { 180 public String toString(int value, Locale locale, int length) { 181 SimpleDateFormat format = new SimpleDateFormat("aaaaaaaaaaaaaa".substring(0, length), locale); 182 Calendar help = Calendar.getInstance(); 183 help.clear(); 184 help.set(field, value); 185 return format.format(help.getTime()); 186 } 187 }; 188 private static final Element MILLISECOND = new Element("millisecond", Calendar.MILLISECOND, 0, 999); 189 190 191 201 public static Element getElement(final char c, Calendar minDate, Calendar maxDate) { 202 switch(c) { 203 case 'G': { 204 int startEra = minDate.get(Calendar.ERA); 205 int endEra = maxDate.get(Calendar.ERA); 206 return new Element("era", Calendar.ERA, startEra, endEra ) { 209 public String toString(int value, Locale locale, int length) { 210 SimpleDateFormat format = new SimpleDateFormat("GGGGGGGGGGGG".substring(0, length), locale); 211 Calendar help = Calendar.getInstance(); 212 help.clear(); 213 help.set(field, value); 214 return format.format(help.getTime()); 215 } 216 }; 217 } 218 case 'y': { 219 int startEra = minDate.get(Calendar.ERA); 220 int endEra = maxDate.get(Calendar.ERA); 221 int startYear = minDate.get(Calendar.YEAR); 222 int endYear = maxDate.get(Calendar.YEAR); 223 if (startEra < endEra) { endYear = endYear > startYear ? endYear : startYear; 225 startYear = minDate.getActualMinimum(Calendar.YEAR); 226 } 227 return new Element("year", Calendar.YEAR, startYear, endYear) { 228 public int getNullValue() { 229 return Integer.MAX_VALUE; 230 } 231 }; 232 } 233 case 'u': { int startEra = minDate.get(Calendar.ERA); 235 int endEra = maxDate.get(Calendar.ERA); 236 int startYear = minDate.get(Calendar.YEAR); 237 if (minDate instanceof GregorianCalendar && startEra == GregorianCalendar.BC) startYear = -1 * (startYear - 1); 238 int endYear = maxDate.get(Calendar.YEAR); 239 if (maxDate instanceof GregorianCalendar && endEra == GregorianCalendar.BC) endYear = -1 * (endYear - 1); 240 return new Element("year", Calendar.YEAR, startYear, endYear) { 241 public int getValue(Calendar cal) { 242 int era = cal.get(Calendar.ERA); 243 int year = cal.get(Calendar.YEAR); 244 if (cal instanceof GregorianCalendar && era == GregorianCalendar.BC) year = -1 * (year - 1); 245 return year; 246 } 247 public int getNullValue() { 248 return Integer.MAX_VALUE; 249 } 250 }; 251 } 252 case 'M': { 253 int startYear = minDate.get(Calendar.YEAR); 254 int endYear = maxDate.get(Calendar.YEAR); 255 int min, max; 256 if (startYear == endYear) { 257 min = minDate.get(Calendar.MONTH) + 1; 258 max = maxDate.get(Calendar.MONTH) + 1; 259 } else { 260 min = 1; 261 max = 12; 262 } 263 return new Element("month", Calendar.MONTH, min, max, 1) { 264 public String toString(int value, Locale locale, int length) { 265 SimpleDateFormat format = new SimpleDateFormat("MMMMMMMMMMMMMMMMMM".substring(0, length), locale); 266 Calendar help = Calendar.getInstance(); 267 help.clear(); 268 help.set(field, value); 269 return format.format(help.getTime()); 270 } 271 }; 272 } 273 case 'd': { 274 int startYear = minDate.get(Calendar.YEAR); 275 int endYear = maxDate.get(Calendar.YEAR); 276 int min, max; 277 if (startYear == endYear) { 278 int minMonth = minDate.get(Calendar.MONTH) + 1; 279 int maxMonth = maxDate.get(Calendar.MONTH) + 1; 280 if (minMonth == maxMonth) { 281 min = minDate.get(Calendar.DAY_OF_MONTH); 282 max = maxDate.get(Calendar.DAY_OF_MONTH); 283 } else { 284 min = 1; 285 max = 31; 286 } 287 } else { 288 min = 1; 289 max = 31; 290 } 291 return new Element("day", Calendar.DAY_OF_MONTH, min, max); 292 } 293 case 'H': return HOUR_OF_DAY; 295 case 'K': return HOUR; 296 case 'h': return HOUR_OF_DAY_1; 297 case 'k': return HOUR_1; 298 case 'm': return MINUTE; 299 case 's': return SECOND; 300 case 'E': return DAY_OF_WEEK; 301 case 'w': return WEEK_OF_YEAR; 302 case 'D': return DAY_OF_YEAR; 303 case 'F': return DAY_OF_WEEK_IN_MONTH; 304 case 'a': return AM_PM; 305 case 'S': return MILLISECOND; 306 default: 307 log.warn("Unknown pattern " + c); 308 return null; 309 } 310 } 311 312 317 public static class Element { 318 private final String name; 319 final int field; 320 private final int min; 321 private final int max; 322 private final int offset; 323 Element(String n, int field, int min, int max) { 324 this(n, field, min, max, 0); 325 } 326 Element(String n, int field, int min, int max, int offset) { 327 name = n; 328 this.field = field; 329 this.min = min; 330 this.max = max; 331 this.offset = offset; 332 } 333 336 public final String getName() { 337 return name; 338 } 339 343 public final int getField() { 344 return field; 345 } 346 349 public final int getMin() { 350 return min; 351 } 352 355 public final int getMax() { 356 return max; 357 } 358 362 public final int getOffset() { 363 return offset; 364 } 365 366 370 public int getValue(Calendar cal) { 371 return cal.get(getField()); 372 } 373 382 public String toString(int value, Locale locale, int length) { 383 StringBuffer buf = new StringBuffer ("" + value); 384 while(buf.length() < length) { 385 buf.insert(0, "0"); 386 } 387 return buf.toString(); 388 } 389 390 public String toString() { 391 return getName() + " [" + min + ", " + max + "] + " + getOffset(); 392 } 393 397 public int getNullValue() { 398 return -1; 399 } 400 } 401 402 403 public Object clone() { 404 try { 405 DateTimePattern clone = (DateTimePattern) super.clone(); 406 clone.pattern = (LocalizedString) pattern.clone(); 407 return clone; 408 } catch (CloneNotSupportedException cns) { 409 throw new RuntimeException (cns); 411 } 412 } 413 414 public String toString() { 415 return pattern.toString(); 416 } 417 418 public static void main(String argv[]) { 419 String input; 420 if (argv.length > 0) { 421 input = argv[0]; 422 } else { 423 input = "yyyy-MM-dd"; 424 } 425 DateTimePattern df = new DateTimePattern(input); 426 df.set("yyyy-MM-dd", Locale.FRANCE); 427 428 DateTimePattern df2 = (DateTimePattern) df.clone(); 429 df2.set("HH:mm:ss"); 430 df2.set("yyyy;MM;dd", Locale.FRANCE); 431 432 System.out.println("" + df.getList(Locale.FRANCE)); 433 System.out.println("" + df2.getList(Locale.FRANCE)); 434 435 } 436 437 } 438 | Popular Tags |