001 // TODO Time constructor muss auch noch entfernt werden und durch DateUtil methode ersetzen 002 package railo.runtime.op.date; 003 004 import java.text.DateFormat; 005 import java.text.ParsePosition; 006 import java.util.Calendar; 007 import java.util.Date; 008 import java.util.Locale; 009 import java.util.TimeZone; 010 011 import railo.commons.date.DateTimeUtil; 012 import railo.commons.date.TimeZoneConstants; 013 import railo.commons.i18n.FormatUtil; 014 import railo.commons.lang.StringUtil; 015 import railo.runtime.Component; 016 import railo.runtime.engine.ThreadLocalPageContext; 017 import railo.runtime.exp.ExpressionException; 018 import railo.runtime.exp.PageException; 019 import railo.runtime.op.Castable; 020 import railo.runtime.op.Caster; 021 import railo.runtime.op.Decision; 022 import railo.runtime.type.ObjectWrap; 023 import railo.runtime.type.dt.DateTime; 024 import railo.runtime.type.dt.DateTimeImpl; 025 import railo.runtime.type.dt.Time; 026 import railo.runtime.type.dt.TimeImpl; 027 028 /** 029 * Class to cast Strings to Date Objects 030 */ 031 public final class DateCaster { 032 033 //private static short MODE_DAY_STR=1; 034 //private static short MODE_MONTH_STR=2; 035 //private static short MODE_NONE=4; 036 private static long DEFAULT_VALUE=Long.MIN_VALUE; 037 038 private static DateTimeUtil util=DateTimeUtil.getInstance(); 039 public static boolean classicStyle=false; 040 041 /** 042 * converts a Object to a DateTime Object (Advanced but slower) 043 * @param o Object to Convert 044 * @param timezone 045 * @return Date Time Object 046 * @throws PageException 047 */ 048 public static DateTime toDateAdvanced(Object o,TimeZone timezone) throws PageException { 049 if(o instanceof Date) { 050 if(o instanceof DateTime) return (DateTime)o; 051 return new DateTimeImpl((Date)o); 052 } 053 else if(o instanceof Castable) return ((Castable)o).castToDateTime(); 054 else if(o instanceof String) { 055 DateTime dt=toDateAdvanced((String)o,timezone,null); 056 if(dt==null) 057 throw new ExpressionException("can't cast ["+o+"] to date value"); 058 return dt; 059 } 060 else if(o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); 061 else if(o instanceof ObjectWrap) return toDateAdvanced(((ObjectWrap)o).getEmbededObject(),timezone); 062 else if(o instanceof Calendar){ 063 064 return new DateTimeImpl((Calendar)o); 065 } 066 throw new ExpressionException("can't cast ["+Caster.toClassName(o)+"] to date value"); 067 } 068 069 /** 070 * converts a Object to a DateTime Object (Advanced but slower) 071 * @param str String to Convert 072 * @param timezone 073 * @return Date Time Object 074 * @throws PageException 075 */ 076 public static DateTime toDateAdvanced(String str,TimeZone timezone) throws PageException { 077 DateTime dt=toDateAdvanced(str,timezone,null); 078 if(dt==null) 079 throw new ExpressionException("can't cast ["+str+"] to date value"); 080 return dt; 081 } 082 083 /** 084 * converts a Object to a DateTime Object (Advanced but slower), returns null if invalid string 085 * @param o Object to Convert 086 * @param timeZone 087 * @param defaultValue 088 * @return Date Time Object 089 */ 090 public static DateTime toDateAdvanced(Object o,TimeZone timeZone, DateTime defaultValue) { 091 if(o instanceof DateTime) return (DateTime)o; 092 else if(o instanceof Date) return new DateTimeImpl((Date)o); 093 else if(o instanceof Castable) { 094 return ((Castable)o).castToDateTime(defaultValue); 095 } 096 else if(o instanceof String) return toDateAdvanced(o.toString(),timeZone,defaultValue); 097 else if(o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); 098 else if(o instanceof Calendar){ 099 return new DateTimeImpl((Calendar)o); 100 } 101 else if(o instanceof ObjectWrap) return toDateAdvanced(((ObjectWrap)o).getEmbededObject(defaultValue),timeZone,defaultValue); 102 return defaultValue; 103 } 104 105 /** 106 * converts a String to a DateTime Object (Advanced but slower), returns null if invalid string 107 * @param str String to convert 108 * @param timeZone 109 * @param defaultValue 110 * @return Date Time Object 111 */ 112 public static DateTime toDateAdvanced(String str,boolean alsoNumbers,TimeZone timeZone, DateTime defaultValue) { 113 str=str.trim(); 114 timeZone=ThreadLocalPageContext.getTimeZone(timeZone); 115 DateTime dt=toDateSimple(str,alsoNumbers,timeZone,defaultValue); 116 if(dt==null) { 117 DateFormat[] formats = FormatUtil.getCFMLFormats(timeZone, true); 118 synchronized(formats){ 119 Date d; 120 ParsePosition pp=new ParsePosition(0); 121 for(int i=0;i<formats.length;i++) { 122 //try { 123 pp.setErrorIndex(-1); 124 pp.setIndex(0); 125 d = formats[i].parse(str,pp); 126 if (pp.getIndex() == 0 || d==null || pp.getIndex()<str.length()) continue; 127 dt= new DateTimeImpl(d.getTime(),false); 128 return dt; 129 //}catch (ParseException e) {} 130 } 131 } 132 dt=Caster.toDateTime(Locale.US, str, timeZone,defaultValue, false); 133 } 134 return dt; 135 } 136 137 public static DateTime toDateAdvanced(String str, TimeZone timeZone, DateTime defaultValue) { 138 return toDateAdvanced(str, true, timeZone,defaultValue); 139 } 140 141 /** 142 * converts a boolean to a DateTime Object 143 * @param b boolean to Convert 144 * @param timeZone 145 * @return coverted Date Time Object 146 */ 147 public static DateTime toDateSimple(boolean b, TimeZone timeZone) { 148 return toDateSimple(b?1L:0L, timeZone); 149 } 150 151 /** 152 * converts a char to a DateTime Object 153 * @param c char to Convert 154 * @param timeZone 155 * @return coverted Date Time Object 156 */ 157 public static DateTime toDateSimple(char c, TimeZone timeZone) { 158 return toDateSimple((long)c, timeZone); 159 } 160 161 /** 162 * converts a double to a DateTime Object 163 * @param d double to Convert 164 * @param timeZone 165 * @return coverted Date Time Object 166 */ 167 public static DateTime toDateSimple(double d, TimeZone timeZone) { 168 return toDateSimple((long)d, timeZone); 169 } 170 171 /* * 172 * converts a double to a DateTime Object 173 * @param d double to Convert 174 * @param timeZone 175 * @return coverted Date Time Object 176 * / 177 public static DateTime toDateSimple(long l, TimeZone timezone) { 178 return new DateTimeImpl(l,false); 179 }*/ 180 181 /** 182 * converts a Object to a DateTime Object, returns null if invalid string 183 * @param o Object to Convert 184 * @param timeZone 185 * @return coverted Date Time Object 186 * @throws PageException 187 */ 188 public static DateTime toDateSimple(Object o, TimeZone timeZone) throws PageException { 189 if(o instanceof DateTime) return (DateTime)o; 190 else if(o instanceof Date) return new DateTimeImpl((Date)o); 191 else if(o instanceof Castable) return ((Castable)o).castToDateTime(); 192 else if(o instanceof String) return toDateSimple(o.toString(),true, timeZone); 193 else if(o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); 194 else if(o instanceof Calendar) return new DateTimeImpl((Calendar)o); 195 else if(o instanceof ObjectWrap) return toDateSimple(((ObjectWrap)o).getEmbededObject(),timeZone); 196 else if(o instanceof Calendar){ 197 return new DateTimeImpl((Calendar)o); 198 } 199 200 if(o instanceof Component) 201 throw new ExpressionException("can't cast component ["+((Component)o).getAbsName()+"] to date value"); 202 203 throw new ExpressionException("can't cast ["+Caster.toTypeName(o)+"] to date value"); 204 } 205 206 /** 207 * converts a Object to a DateTime Object, returns null if invalid string 208 * @param str String to Convert 209 * @param timeZone 210 * @return coverted Date Time Object 211 * @throws PageException 212 */ 213 public static DateTime toDateSimple(String str, TimeZone timeZone) throws PageException { 214 DateTime dt=toDateSimple(str,true, timeZone,null); 215 if(dt==null) 216 throw new ExpressionException("can't cast ["+str+"] to date value"); 217 return dt; 218 } 219 220 /** 221 * converts a Object to a Time Object, returns null if invalid string 222 * @param o Object to Convert 223 * @return coverted Date Time Object 224 * @throws PageException 225 */ 226 public static Time toTime(TimeZone timeZone,Object o) throws PageException { 227 if(o instanceof Time) return (Time)o; 228 else if(o instanceof Date) return new TimeImpl((Date)o); 229 else if(o instanceof Castable) return new TimeImpl(((Castable)o).castToDateTime()); 230 else if(o instanceof String) { 231 Time dt=toTime(timeZone,o.toString(),null); 232 if(dt==null) 233 throw new ExpressionException("can't cast ["+o+"] to time value"); 234 return dt; 235 } 236 else if(o instanceof ObjectWrap) return toTime(timeZone,((ObjectWrap)o).getEmbededObject()); 237 else if(o instanceof Calendar){ 238 // TODO check timezone offset 239 return new TimeImpl(((Calendar)o).getTimeInMillis(),false); 240 } 241 throw new ExpressionException("can't cast ["+Caster.toClassName(o)+"] to time value"); 242 } 243 244 /** 245 * converts a Object to a DateTime Object, returns null if invalid string 246 * @param o Object to Convert 247 * @param alsoNumbers 248 * @param timeZone 249 * @param defaultValue 250 * @return coverted Date Time Object 251 */ 252 public static DateTime toDateSimple(Object o,boolean alsoNumbers, TimeZone timeZone, DateTime defaultValue) { 253 return _toDateAdvanced(o, alsoNumbers, timeZone, defaultValue, false); 254 } 255 256 public static DateTime toDateAdvanced(Object o,boolean alsoNumbers, TimeZone timeZone, DateTime defaultValue) { 257 return _toDateAdvanced(o, alsoNumbers, timeZone, defaultValue, true); 258 } 259 260 private static DateTime _toDateAdvanced(Object o,boolean alsoNumbers, TimeZone timeZone, DateTime defaultValue, boolean advanced) { 261 if(o instanceof DateTime) return (DateTime)o; 262 else if(o instanceof Date) return new DateTimeImpl((Date)o); 263 else if(o instanceof Castable) { 264 return ((Castable)o).castToDateTime(defaultValue); 265 } 266 else if(o instanceof String) { 267 if(advanced)return toDateAdvanced(o.toString(),alsoNumbers, timeZone,defaultValue); 268 return toDateSimple(o.toString(),alsoNumbers, timeZone,defaultValue); 269 } 270 else if(alsoNumbers && o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); 271 else if(o instanceof ObjectWrap) { 272 return _toDateAdvanced(((ObjectWrap)o).getEmbededObject(defaultValue),alsoNumbers,timeZone,defaultValue,advanced); 273 } 274 else if(o instanceof Calendar){ 275 return new DateTimeImpl((Calendar)o); 276 } 277 return defaultValue; 278 } 279 280 281 282 /** 283 * converts a Object to a DateTime Object, returns null if invalid string 284 * @param o Object to Convert 285 * @param alsoNumbers 286 * @param timeZone 287 * @return coverted Date Time Object 288 * @throws PageException 289 */ 290 public static DateTime toDateSimple(Object o,boolean alsoNumbers, TimeZone timeZone) throws PageException { 291 DateTime dt = toDateSimple(o,alsoNumbers,timeZone,null); 292 if(dt==null) throw new ExpressionException("can't cast value to a Date Object"); 293 return dt; 294 } 295 296 public static DateTime toDateAdvanced(Object o,boolean alsoNumbers, TimeZone timeZone) throws PageException { 297 DateTime dt = toDateAdvanced(o,alsoNumbers,timeZone,null); 298 if(dt==null) throw new ExpressionException("can't cast value to a Date Object"); 299 return dt; 300 } 301 302 303 304 /** 305 * converts a String to a Time Object, returns null if invalid string 306 * @param str String to convert 307 * @param defaultValue 308 * @return Time Object 309 * @throws 310 */ 311 public static Time toTime(TimeZone timeZone,String str, Time defaultValue) { 312 313 if(str==null || str.length()<3) { 314 return defaultValue; 315 } 316 DateString ds=new DateString(str); 317 // Timestamp 318 if(ds.isCurrent('{') && ds.isLast('}')) { 319 320 // Time 321 // "^\\{t '([0-9]{1,2}):([0-9]{1,2}):([0-9]{2})'\\}$" 322 if(ds.fwIfNext('t')) { 323 324 // Time 325 if(!(ds.fwIfNext(' ') && ds.fwIfNext('\'')))return defaultValue; 326 ds.next(); 327 // hour 328 int hour=ds.readDigits(); 329 if(hour==-1) return defaultValue; 330 331 if(!ds.fwIfCurrent(':'))return defaultValue; 332 333 // minute 334 int minute=ds.readDigits(); 335 if(minute==-1) return defaultValue; 336 337 if(!ds.fwIfCurrent(':'))return defaultValue; 338 339 // second 340 int second=ds.readDigits(); 341 if(second==-1) return defaultValue; 342 343 if(!(ds.fwIfCurrent('\'') && ds.fwIfCurrent('}')))return defaultValue; 344 345 if(ds.isAfterLast()){ 346 long time=util.toTime(timeZone,1899,12,30,hour,minute,second,0,DEFAULT_VALUE); 347 if(time==DEFAULT_VALUE)return defaultValue; 348 return new TimeImpl(time,false); 349 } 350 return defaultValue; 351 352 353 } 354 return defaultValue; 355 } 356 // Time start with int 357 /*else if(ds.isDigit()) { 358 char sec=ds.charAt(1); 359 char third=ds.charAt(2); 360 // 16.10.2004 (02:15)? 361 if(sec==':' || third==':') { 362 // hour 363 int hour=ds.readDigits(); 364 if(hour==-1) return defaultValue; 365 366 if(!ds.fwIfCurrent(':'))return defaultValue; 367 368 // minutes 369 int minutes=ds.readDigits(); 370 if(minutes==-1) return defaultValue; 371 372 if(ds.isAfterLast()) { 373 long time=util.toTime(timeZone,1899,12,30,hour,minutes,0,0,DEFAULT_VALUE); 374 if(time==DEFAULT_VALUE) return defaultValue; 375 376 return new TimeImpl(time,false); 377 } 378 //else if(!ds.fwIfCurrent(':'))return null; 379 else if(!ds.fwIfCurrent(':')) { 380 if(!ds.fwIfCurrent(' '))return defaultValue; 381 382 if(ds.fwIfCurrent('a') || ds.fwIfCurrent('A')) { 383 if(ds.fwIfCurrent('m') || ds.fwIfCurrent('M')) { 384 if(ds.isAfterLast()) { 385 long time=util.toTime(timeZone,1899,12,30,hour,minutes,0,0,DEFAULT_VALUE); 386 if(time==DEFAULT_VALUE) return defaultValue; 387 return new TimeImpl(time,false); 388 } 389 } 390 return defaultValue; 391 } 392 else if(ds.fwIfCurrent('p') || ds.fwIfCurrent('P')) { 393 if(ds.fwIfCurrent('m') || ds.fwIfCurrent('M')) { 394 if(ds.isAfterLast()) { 395 long time=util.toTime(timeZone,1899,12,30,hour<13?hour+12:hour,minutes,0,0,DEFAULT_VALUE); 396 if(time==DEFAULT_VALUE) return defaultValue; 397 return new TimeImpl(time,false); 398 } 399 } 400 return defaultValue; 401 } 402 return defaultValue; 403 } 404 405 406 // seconds 407 int seconds=ds.readDigits(); 408 if(seconds==-1) return defaultValue; 409 410 if(ds.isAfterLast()) { 411 long time=util.toTime(timeZone,1899,12,30,hour,minutes,seconds,0,DEFAULT_VALUE); 412 if(time==DEFAULT_VALUE) return defaultValue; 413 return new TimeImpl(time,false); 414 } 415 416 } 417 }*/ 418 419 // TODO bessere impl 420 ds.reset(); 421 DateTime rtn = parseTime(timeZone, new int[]{1899,12,30}, ds, defaultValue,-1); 422 if(rtn==defaultValue) return defaultValue; 423 return new TimeImpl(rtn); 424 425 426 427 //return defaultValue; 428 } 429 430 431 432 /** 433 * converts a String to a DateTime Object, returns null if invalid string 434 * @param str String to convert 435 * @param alsoNumbers 436 * @param timeZone 437 * @param defaultValue 438 * @return Date Time Object 439 */ 440 private static DateTime parseDateTime(String str,DateString ds,boolean alsoNumbers,TimeZone timeZone, DateTime defaultValue) { 441 int month=0; 442 int first=ds.readDigits(); 443 // first 444 if(first==-1) { 445 first=ds.readMonthString(); 446 if(first==-1)return defaultValue; 447 month=1; 448 } 449 450 if(ds.isAfterLast()) return month==1?defaultValue:toNumberDate(str,alsoNumbers,defaultValue); 451 452 char del=ds.current(); 453 if(del!='.' && del!='/' && del!='-' && del!=' ' && del!='\t') { 454 if(ds.fwIfCurrent(':')){ 455 return parseTime(timeZone, new int[]{1899,12,30}, ds, defaultValue,first); 456 } 457 return defaultValue; 458 } 459 ds.next(); 460 ds.removeWhitespace(); 461 462 // second 463 int second=ds.readDigits(); 464 if(second==-1){ 465 second=ds.readMonthString(); 466 if(second==-1)return defaultValue; 467 month=2; 468 } 469 470 if(ds.isAfterLast()) { 471 return toDate(month,timeZone,first,second,defaultValue); 472 } 473 474 char del2=ds.current(); 475 if(del!=del2) { 476 ds.fwIfCurrent(' '); 477 ds.fwIfCurrent('T'); 478 ds.fwIfCurrent(' '); 479 return parseTime(timeZone,_toDate(timeZone,month, first, second),ds,defaultValue,-1); 480 } 481 ds.next(); 482 ds.removeWhitespace(); 483 484 485 486 int third=ds.readDigits(); 487 if(third==-1){ 488 return defaultValue; 489 } 490 491 if(ds.isAfterLast()) { 492 if(classicStyle() && del=='.')return toDate(month,timeZone,second,first,third,defaultValue); 493 return toDate(month,timeZone,first,second,third,defaultValue); 494 } 495 ds.fwIfCurrent(' '); 496 ds.fwIfCurrent('T'); 497 ds.fwIfCurrent(' '); 498 if(classicStyle() && del=='.')return parseTime(timeZone,_toDate(month, second,first,third),ds,defaultValue,-1); 499 return parseTime(timeZone,_toDate(month, first, second,third),ds,defaultValue,-1); 500 501 502 } 503 504 private static boolean classicStyle() { 505 return classicStyle; 506 } 507 508 private static DateTime parseTime(TimeZone timeZone,int[] date, DateString ds,DateTime defaultValue, int hours) { 509 if(date==null)return defaultValue; 510 511 512 ds.removeWhitespace(); 513 514 // hour 515 boolean next=false; 516 if(hours==-1){ 517 ds.removeWhitespace(); 518 hours=ds.readDigits(); 519 ds.removeWhitespace(); 520 if(hours==-1) { 521 return parseOffset(ds,timeZone,date,0,0,0,0,defaultValue); 522 } 523 } 524 else next=true; 525 526 int minutes=0; 527 if(next || ds.fwIfCurrent(':')){ 528 ds.removeWhitespace(); 529 minutes=ds.readDigits(); 530 ds.removeWhitespace(); 531 if(minutes==-1) return defaultValue; 532 } 533 534 535 int seconds=0; 536 if(ds.fwIfCurrent(':')){ 537 ds.removeWhitespace(); 538 seconds=ds.readDigits(); 539 ds.removeWhitespace(); 540 if(seconds==-1) return defaultValue; 541 } 542 543 int msSeconds=0; 544 if(ds.fwIfCurrent('.')){ 545 ds.removeWhitespace(); 546 msSeconds=ds.readDigits(); 547 ds.removeWhitespace(); 548 if(msSeconds==-1) return defaultValue; 549 } 550 551 if(ds.isAfterLast()){ 552 return DateTimeUtil.getInstance().toDateTime(timeZone, date[0], date[1], date[2], hours, minutes, seconds, msSeconds, defaultValue); 553 } 554 ds.fwIfCurrent(' '); 555 556 if(ds.fwIfCurrent('a') || ds.fwIfCurrent('A')) { 557 if(!ds.fwIfCurrent('m'))ds.fwIfCurrent('M'); 558 if(ds.isAfterLast()) 559 return DateTimeUtil.getInstance().toDateTime(timeZone, date[0], date[1], date[2], 560 hours<12?hours:hours-12, minutes, seconds, msSeconds, defaultValue); 561 return defaultValue; 562 } 563 else if(ds.fwIfCurrent('p') || ds.fwIfCurrent('P')) { 564 if(!ds.fwIfCurrent('m'))ds.fwIfCurrent('M'); 565 if(hours>24) return defaultValue; 566 if(ds.isAfterLast()) 567 return DateTimeUtil.getInstance().toDateTime(timeZone, date[0], date[1], date[2], 568 hours<12?hours+12:hours, minutes, seconds, msSeconds,defaultValue); 569 return defaultValue; 570 } 571 572 ds.fwIfCurrent(' '); 573 return parseOffset(ds,timeZone,date,hours,minutes,seconds,msSeconds,defaultValue); 574 575 } 576 577 private static DateTime parseOffset(DateString ds, TimeZone timeZone, int[] date,int hours, int minutes, int seconds, int msSeconds,DateTime defaultValue) { 578 if(ds.isLast() && (ds.fwIfCurrent('Z') || ds.fwIfCurrent('z'))) { 579 return util.toDateTime(TimeZoneConstants.UTC, date[0], date[1], date[2], hours, minutes, seconds, msSeconds,defaultValue); 580 } 581 else if(ds.fwIfCurrent('+')){ 582 DateTime rtn = util.toDateTime(timeZone, date[0], date[1], date[2], hours, minutes, seconds, msSeconds,defaultValue); 583 if(rtn==defaultValue) return rtn; 584 return readOffset(true,timeZone,rtn,date[0], date[1], date[2], hours, minutes, seconds, msSeconds,ds,defaultValue); 585 } 586 else if(ds.fwIfCurrent('-')){ 587 DateTime rtn = util.toDateTime(timeZone, date[0], date[1], date[2], hours, minutes, seconds, msSeconds, defaultValue); 588 if(rtn==defaultValue) return rtn; 589 return readOffset(false,timeZone,rtn,date[0], date[1], date[2], hours, minutes, seconds, msSeconds,ds,defaultValue); 590 } 591 return defaultValue; 592 } 593 594 private static DateTime toDate(int month, TimeZone timeZone,int first, int second, DateTime defaultValue) { 595 int[] d = _toDate(timeZone,month, first, second); 596 if(d==null)return defaultValue; 597 return util.toDateTime(timeZone, d[0], d[1], d[2],0,0,0,0,defaultValue); 598 } 599 600 private static int[] _toDate(TimeZone tz,int month, int first, int second) { 601 int YEAR=year(tz); 602 if(first<=12 && month<2){ 603 if(util.daysInMonth(YEAR, first)>=second) 604 return new int[]{YEAR, first, second}; 605 return new int[]{util.toYear(second), first, 1}; 606 } 607 // first>12 608 if(second<=12){ 609 if(util.daysInMonth(YEAR, second)>=first) 610 return new int[]{YEAR, second, first}; 611 return new int[]{util.toYear(first), second, 1}; 612 } 613 return null; 614 } 615 private static int year(TimeZone tz) { 616 return util.getYear(ThreadLocalPageContext.getTimeZone(tz),new DateTimeImpl()); 617 } 618 619 private static DateTime toDate(int month, TimeZone timeZone,int first, int second, int third, DateTime defaultValue) { 620 int[] d = _toDate(month, first, second, third); 621 if(d==null) return defaultValue; 622 return util.toDateTime(timeZone, d[0], d[1], d[2], 0, 0, 0,0,defaultValue); 623 } 624 625 private static int[] _toDate(int month, int first, int second, int third) { 626 if(first<=12){ 627 if(month==2) 628 return new int[]{util.toYear(third), second, first}; 629 if(util.daysInMonth(util.toYear(third), first)>=second) 630 return new int[]{util.toYear(third), first, second}; 631 return null; 632 } 633 if(second>12)return null; 634 if(month==2){ 635 int tmp=first; 636 first=third; 637 third=tmp; 638 } 639 if(util.daysInMonth(util.toYear(first), second)<third) { 640 if(util.daysInMonth(util.toYear(third), second)>=first) 641 return new int[]{util.toYear(third), second, first}; 642 return null; 643 } 644 return new int[]{util.toYear(first), second, third}; 645 } 646 647 648 public static DateTime toDateSimple(String str,boolean alsoNumbers, TimeZone timeZone, DateTime defaultValue) { 649 str=StringUtil.trim(str,""); 650 651 652 DateString ds=new DateString(str); 653 654 // Timestamp 655 if(ds.isCurrent('{') && ds.isLast('}')) { 656 return _toDateSimpleTS(ds,timeZone,defaultValue); 657 } 658 DateTime res = parseDateTime(str,ds,alsoNumbers,timeZone,defaultValue); 659 if(alsoNumbers && res==defaultValue && Decision.isNumeric(str)) { 660 double dbl = Caster.toDoubleValue(str,Double.NaN); 661 if(Decision.isValid(dbl))return util.toDateTime(dbl); 662 } 663 return res; 664 } 665 666 private static DateTime _toDateSimpleTS(DateString ds, TimeZone timeZone, DateTime defaultValue) { 667 // Date 668 // "^\\{d '([0-9]{2,4})-([0-9]{1,2})-([0-9]{1,2})'\\}$" 669 if(ds.fwIfNext('d')) { 670 if(!(ds.fwIfNext(' ') && ds.fwIfNext('\'')))return defaultValue; 671 ds.next(); 672 // year 673 int year=ds.readDigits(); 674 if(year==-1) return defaultValue; 675 676 if(!ds.fwIfCurrent('-'))return defaultValue; 677 678 // month 679 int month=ds.readDigits(); 680 if(month==-1) return defaultValue; 681 682 if(!ds.fwIfCurrent('-'))return defaultValue; 683 684 // day 685 int day=ds.readDigits(); 686 if(day==-1) return defaultValue; 687 688 if(!(ds.fwIfCurrent('\'') && ds.fwIfCurrent('}')))return defaultValue; 689 690 if(ds.isAfterLast()) return util.toDateTime(timeZone,year, month, day, 0, 0, 0, 0, defaultValue);//new DateTimeImpl(year,month,day); 691 692 return defaultValue; 693 694 } 695 696 // DateTime 697 // "^\\{ts '([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{2}):([0-9]{1,2}):([0-9]{2})'\\}$" 698 else if(ds.fwIfNext('t')) { 699 if(!(ds.fwIfNext('s') && ds.fwIfNext(' ') && ds.fwIfNext('\''))) { 700 701 // Time 702 if(!(ds.fwIfNext(' ') && ds.fwIfNext('\'')))return defaultValue; 703 ds.next(); 704 // hour 705 int hour=ds.readDigits(); 706 if(hour==-1) return defaultValue; 707 708 if(!ds.fwIfCurrent(':'))return defaultValue; 709 710 // minute 711 int minute=ds.readDigits(); 712 if(minute==-1) return defaultValue; 713 714 if(!ds.fwIfCurrent(':'))return defaultValue; 715 716 // second 717 int second=ds.readDigits(); 718 if(second==-1) return defaultValue; 719 720 721 // Milli Second 722 int millis=0; 723 724 if(ds.fwIfCurrent('.')){ 725 millis=ds.readDigits(); 726 } 727 728 729 if(!(ds.fwIfCurrent('\'') && ds.fwIfCurrent('}')))return defaultValue; 730 731 732 733 if(ds.isAfterLast()){ 734 long time=util.toTime(timeZone,1899,12,30,hour,minute,second,millis,DEFAULT_VALUE); 735 if(time==DEFAULT_VALUE)return defaultValue; 736 return new TimeImpl(time,false); 737 } 738 return defaultValue; 739 } 740 ds.next(); 741 // year 742 int year=ds.readDigits(); 743 if(year==-1) return defaultValue; 744 745 if(!ds.fwIfCurrent('-'))return defaultValue; 746 747 // month 748 int month=ds.readDigits(); 749 if(month==-1) return defaultValue; 750 751 if(!ds.fwIfCurrent('-'))return defaultValue; 752 753 // day 754 int day=ds.readDigits(); 755 if(day==-1) return defaultValue; 756 757 if(!ds.fwIfCurrent(' '))return defaultValue; 758 759 // hour 760 int hour=ds.readDigits(); 761 if(hour==-1) return defaultValue; 762 763 if(!ds.fwIfCurrent(':'))return defaultValue; 764 765 // minute 766 int minute=ds.readDigits(); 767 if(minute==-1) return defaultValue; 768 769 if(!ds.fwIfCurrent(':'))return defaultValue; 770 771 // second 772 int second=ds.readDigits(); 773 if(second==-1) return defaultValue; 774 775 776 777 // Milli Second 778 int millis=0; 779 780 if(ds.fwIfCurrent('.')){ 781 millis=ds.readDigits(); 782 } 783 784 if(!(ds.fwIfCurrent('\'') && ds.fwIfCurrent('}')))return defaultValue; 785 if(ds.isAfterLast())return util.toDateTime(timeZone,year, month, day,hour,minute,second,millis,defaultValue);//new DateTimeImpl(year,month,day,hour,minute,second); 786 return defaultValue; 787 788 } 789 else return defaultValue; 790 } 791 792 private static DateTime toNumberDate(String str,boolean alsoNumbers, DateTime defaultValue) { 793 if(!alsoNumbers) return defaultValue; 794 double dbl = Caster.toDoubleValue(str,Double.NaN); 795 if(Decision.isValid(dbl))return util.toDateTime(dbl); 796 return defaultValue; 797 } 798 799 /** 800 * reads a offset definition at the end of a date string 801 * @param timeZone 802 * @param dt previous parsed date Object 803 * @param ds DateString to parse 804 * @param defaultValue 805 * @return date Object with offset 806 */ 807 private static DateTime readOffset(boolean isPlus,TimeZone timeZone,DateTime dt,int years, int months, int days, int hours, int minutes, int seconds, int milliSeconds, DateString ds,DateTime defaultValue) { 808 //timeZone=ThreadLocalPageContext.getTimeZone(timeZone); 809 if(timeZone==null) return defaultValue; 810 // HOUR 811 int hourLength=ds.getPos(); 812 int hour=ds.readDigits(); 813 hourLength=ds.getPos()-hourLength; 814 if(hour==-1) return defaultValue; 815 816 // MINUTE 817 int minute=0; 818 if(!ds.isAfterLast()) { 819 if(!ds.fwIfCurrent(':'))return defaultValue; 820 minute=ds.readDigits(); 821 if(minute==-1) return defaultValue; 822 823 } 824 else if(hourLength>2){ 825 int h=hour/100; 826 minute=hour-(h*100); 827 hour=h; 828 } 829 830 if(hour>12) return defaultValue; 831 if(minute>59) return defaultValue; 832 if(hour==12 && minute>0) return defaultValue; 833 834 long offset = hour*60L*60L*1000L; 835 offset+=minute*60*1000; 836 837 if(ds.isAfterLast()) { 838 long time= util.toTime(TimeZoneConstants.UTC, years, months, days, hours, minutes, seconds, milliSeconds, 0); 839 840 if(isPlus)time-=offset; 841 else time+=offset; 842 return new DateTimeImpl(time,false); 843 } 844 return defaultValue; 845 } 846 847 public static String toUSDate(Object o, TimeZone timeZone) throws PageException { 848 if(Decision.isUSDate(o)) return Caster.toString(o); 849 DateTime date = DateCaster.toDateAdvanced(o, timeZone); 850 return new railo.runtime.format.DateFormat(Locale.US).format(date,"mm/dd/yyyy"); 851 } 852 853 public static String toEuroDate(Object o, TimeZone timeZone) throws PageException { 854 if(Decision.isEuroDate(o)) return Caster.toString(o); 855 DateTime date = DateCaster.toDateAdvanced(o, timeZone); 856 return new railo.runtime.format.DateFormat(Locale.US).format(date,"dd.mm.yyyy"); 857 } 858 859 860 }