// TODO Time constructor muss auch noch entfernt werden und durch DateUtil methode ersetzen package railo.runtime.op.date; import java.text.DateFormat; import java.text.ParsePosition; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.TimeZone; import railo.commons.date.DateTimeUtil; import railo.commons.date.JREDateTimeUtil; import railo.commons.date.TimeZoneConstants; import railo.commons.i18n.FormatUtil; import railo.commons.lang.StringUtil; import railo.runtime.Component; import railo.runtime.engine.ThreadLocalPageContext; import railo.runtime.exp.ExpressionException; import railo.runtime.exp.PageException; import railo.runtime.op.Castable; import railo.runtime.op.Caster; import railo.runtime.op.Decision; import railo.runtime.type.ObjectWrap; import railo.runtime.type.dt.DateTime; import railo.runtime.type.dt.DateTimeImpl; import railo.runtime.type.dt.Time; import railo.runtime.type.dt.TimeImpl; /** * Class to cast Strings to Date Objects */ public final class DateCaster { private static final Object NULL = new Object(); //private static short MODE_DAY_STR=1; //private static short MODE_MONTH_STR=2; //private static short MODE_NONE=4; private static long DEFAULT_VALUE=Long.MIN_VALUE; private static DateTimeUtil util=DateTimeUtil.getInstance(); public static boolean classicStyle=false; /** * converts a Object to a DateTime Object (Advanced but slower) * @param o Object to Convert * @param timezone * @return Date Time Object * @throws PageException */ public static DateTime toDateAdvanced(Object o,TimeZone timezone) throws PageException { if(o instanceof Date) { if(o instanceof DateTime) return (DateTime)o; return new DateTimeImpl((Date)o); } else if(o instanceof Castable) return ((Castable)o).castToDateTime(); else if(o instanceof String) { DateTime dt=toDateAdvanced((String)o,timezone,null); if(dt==null) throw new ExpressionException("can't cast ["+o+"] to date value"); return dt; } else if(o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); else if(o instanceof ObjectWrap) return toDateAdvanced(((ObjectWrap)o).getEmbededObject(),timezone); else if(o instanceof Calendar){ return new DateTimeImpl((Calendar)o); } throw new ExpressionException("can't cast ["+Caster.toClassName(o)+"] to date value"); } /** * converts a Object to a DateTime Object (Advanced but slower) * @param str String to Convert * @param timezone * @return Date Time Object * @throws PageException */ public static DateTime toDateAdvanced(String str,TimeZone timezone) throws PageException { DateTime dt=toDateAdvanced(str,timezone,null); if(dt==null) throw new ExpressionException("can't cast ["+str+"] to date value"); return dt; } /** * converts a Object to a DateTime Object (Advanced but slower), returns null if invalid string * @param o Object to Convert * @param timeZone * @param defaultValue * @return Date Time Object */ public static DateTime toDateAdvanced(Object o,TimeZone timeZone, DateTime defaultValue) { if(o instanceof DateTime) return (DateTime)o; else if(o instanceof Date) return new DateTimeImpl((Date)o); else if(o instanceof Castable) { return ((Castable)o).castToDateTime(defaultValue); } else if(o instanceof String) return toDateAdvanced(o.toString(),timeZone,defaultValue); else if(o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); else if(o instanceof Calendar){ return new DateTimeImpl((Calendar)o); } else if(o instanceof ObjectWrap) return toDateAdvanced(((ObjectWrap)o).getEmbededObject(defaultValue),timeZone,defaultValue); return defaultValue; } /** * converts a String to a DateTime Object (Advanced but slower), returns null if invalid string * @param str String to convert * @param timeZone * @param defaultValue * @return Date Time Object */ public static DateTime toDateAdvanced(String str,boolean alsoNumbers,TimeZone timeZone, DateTime defaultValue) { str=str.trim(); if(StringUtil.isEmpty(str)) return defaultValue; timeZone=ThreadLocalPageContext.getTimeZone(timeZone); DateTime dt=toDateSimple(str,alsoNumbers,true,timeZone,defaultValue); if(dt==null) { DateFormat[] formats = FormatUtil.getCFMLFormats(timeZone, true); synchronized(formats){ Date d; ParsePosition pp=new ParsePosition(0); for(int i=0;i<formats.length;i++) { //try { pp.setErrorIndex(-1); pp.setIndex(0); d = formats[i].parse(str,pp); if (pp.getIndex() == 0 || d==null || pp.getIndex()<str.length()) continue; dt= new DateTimeImpl(d.getTime(),false); return dt; //}catch (ParseException e) {} } } dt=toDateTime(Locale.US, str, timeZone,defaultValue, false); } return dt; } /** * parse a string to a Datetime Object * @param locale * @param str String representation of a locale Date * @param tz * @return DateTime Object * @throws PageException */ public static DateTime toDateTime(Locale locale,String str, TimeZone tz,boolean useCommomDateParserAsWell) throws PageException { DateTime dt=toDateTime(locale, str, tz,null,useCommomDateParserAsWell); if(dt==null){ /* FUTURE 4.1 String prefix=locale.getLanguage()+"-"+locale.getCountry()+"-"; throw new ExpressionException("can't cast ["+str+"] to date value", "to add custom formats for "+LocaleFactory.toString(locale)+ ", create/extend on of the following files ["+prefix+"datetime.df (for date time formats), "+prefix+"date.df (for date formats) or "+prefix+"time.df (for time formats)] in the following directory [<context>/railo/locales]."+ ""); */ throw new ExpressionException("can't cast ["+str+"] to date value"); } return dt; } /** * parse a string to a Datetime Object, returns null if can't convert * @param locale * @param str String representation of a locale Date * @param tz * @param defaultValue * @return datetime object */ public synchronized static DateTime toDateTime(Locale locale,String str, TimeZone tz, DateTime defaultValue,boolean useCommomDateParserAsWell) { str=str.trim(); tz=ThreadLocalPageContext.getTimeZone(tz); DateFormat[] df; // get Calendar Calendar c=JREDateTimeUtil.getThreadCalendar(locale); //synchronized(c){ // datetime ParsePosition pp=new ParsePosition(0); df=FormatUtil.getDateTimeFormats(locale,tz,false);//dfc[FORMATS_DATE_TIME]; Date d; //print.e(locale.getDisplayName(Locale.ENGLISH)); for(int i=0;i<df.length;i++) { //print.e(df[i].format(new Date())); pp.setErrorIndex(-1); pp.setIndex(0); //try { df[i].setTimeZone(tz); d = df[i].parse(str,pp); if (pp.getIndex() == 0 || d==null || pp.getIndex()<str.length()) continue; synchronized(c) { optimzeDate(c,tz,d); return new DateTimeImpl(c.getTime()); } //}catch (ParseException e) {} } // date df=FormatUtil.getDateFormats(locale,tz,false);//dfc[FORMATS_DATE]; //print.e(locale.getDisplayName(Locale.ENGLISH)); for(int i=0;i<df.length;i++) { //print.e(df[i].format(new Date())); pp.setErrorIndex(-1); pp.setIndex(0); //try { df[i].setTimeZone(tz); d=df[i].parse(str,pp); if (pp.getIndex() == 0 || d==null || pp.getIndex()<str.length()) continue; synchronized(c) { optimzeDate(c,tz,d); return new DateTimeImpl(c.getTime()); } //}catch (ParseException e) {} } // time df=FormatUtil.getTimeFormats(locale,tz,false);//dfc[FORMATS_TIME]; //print.e(locale.getDisplayName(Locale.ENGLISH)); for(int i=0;i<df.length;i++) { //print.e(df[i].format(new Date())); pp.setErrorIndex(-1); pp.setIndex(0); //try { df[i].setTimeZone(tz); d=df[i].parse(str,pp); if (pp.getIndex() == 0 || d==null || pp.getIndex()<str.length()) continue; synchronized(c) { c.setTimeZone(tz); c.setTime(d); c.set(Calendar.YEAR,1899); c.set(Calendar.MONTH,11); c.set(Calendar.DAY_OF_MONTH,30); c.setTimeZone(tz); } return new DateTimeImpl(c.getTime()); //}catch (ParseException e) {} } //} if(useCommomDateParserAsWell)return DateCaster.toDateSimple(str, false,true, tz, defaultValue); return defaultValue; } private static void optimzeDate(Calendar c, TimeZone tz, Date d) { c.setTimeZone(tz); c.setTime(d); int year=c.get(Calendar.YEAR); if(year<40) c.set(Calendar.YEAR,2000+year); else if(year<100) c.set(Calendar.YEAR,1900+year); } public static DateTime toDateAdvanced(String str, TimeZone timeZone, DateTime defaultValue) { return toDateAdvanced(str, true, timeZone,defaultValue); } /** * converts a boolean to a DateTime Object * @param b boolean to Convert * @param timeZone * @return coverted Date Time Object */ public static DateTime toDateSimple(boolean b, TimeZone timeZone) { return toDateSimple(b?1L:0L, timeZone); } /** * converts a char to a DateTime Object * @param c char to Convert * @param timeZone * @return coverted Date Time Object */ public static DateTime toDateSimple(char c, TimeZone timeZone) { return toDateSimple((long)c, timeZone); } /** * converts a double to a DateTime Object * @param d double to Convert * @param timeZone * @return coverted Date Time Object */ public static DateTime toDateSimple(double d, TimeZone timeZone) { return toDateSimple((long)d, timeZone); } /* * * converts a double to a DateTime Object * @param d double to Convert * @param timeZone * @return coverted Date Time Object * / public static DateTime toDateSimple(long l, TimeZone timezone) { return new DateTimeImpl(l,false); }*/ /** * converts a Object to a DateTime Object, returns null if invalid string * @param o Object to Convert * @param timeZone * @return coverted Date Time Object * @throws PageException */ public static DateTime toDateSimple(Object o, boolean alsoNumbers,boolean alsoMonthString, TimeZone timeZone) throws PageException { if(o instanceof DateTime) return (DateTime)o; else if(o instanceof Date) return new DateTimeImpl((Date)o); else if(o instanceof Castable) return ((Castable)o).castToDateTime(); else if(o instanceof String) return toDateSimple(o.toString(),alsoNumbers,alsoMonthString, timeZone); else if(o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); else if(o instanceof Calendar) return new DateTimeImpl((Calendar)o); else if(o instanceof ObjectWrap) return toDateSimple(((ObjectWrap)o).getEmbededObject(),alsoNumbers,alsoMonthString,timeZone); else if(o instanceof Calendar){ return new DateTimeImpl((Calendar)o); } if(o instanceof Component) throw new ExpressionException("can't cast component ["+((Component)o).getAbsName()+"] to date value"); throw new ExpressionException("can't cast ["+Caster.toTypeName(o)+"] to date value"); } public static DateTime toDateSimple(Object o, boolean alsoNumbers,boolean alsoMonthString, TimeZone timeZone, DateTime defaultValue) { if(o instanceof DateTime) return (DateTime)o; else if(o instanceof Date) return new DateTimeImpl((Date)o); else if(o instanceof Castable) return ((Castable)o).castToDateTime(defaultValue); else if(o instanceof String) return toDateSimple(o.toString(),alsoNumbers,alsoMonthString, timeZone,defaultValue); else if(o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); else if(o instanceof Calendar) return new DateTimeImpl((Calendar)o); else if(o instanceof ObjectWrap) { Object eo = ((ObjectWrap)o).getEmbededObject(NULL); if(eo==NULL) return defaultValue; return toDateSimple(eo,alsoNumbers,alsoMonthString,timeZone,defaultValue); } else if(o instanceof Calendar){ return new DateTimeImpl((Calendar)o); } return defaultValue; } /** * converts a Object to a DateTime Object, returns null if invalid string * @param str String to Convert * @param timeZone * @return coverted Date Time Object * @throws PageException */ public static DateTime toDateSimple(String str, TimeZone timeZone) throws PageException { DateTime dt=toDateSimple(str,true,true, timeZone,null); if(dt==null) throw new ExpressionException("can't cast ["+str+"] to date value"); return dt; } /** * converts a Object to a Time Object, returns null if invalid string * @param o Object to Convert * @return coverted Date Time Object * @throws PageException */ public static Time toTime(TimeZone timeZone,Object o) throws PageException { if(o instanceof Time) return (Time)o; else if(o instanceof Date) return new TimeImpl((Date)o); else if(o instanceof Castable) return new TimeImpl(((Castable)o).castToDateTime()); else if(o instanceof String) { Time dt=toTime(timeZone,o.toString(),null); if(dt==null) throw new ExpressionException("can't cast ["+o+"] to time value"); return dt; } else if(o instanceof ObjectWrap) return toTime(timeZone,((ObjectWrap)o).getEmbededObject()); else if(o instanceof Calendar){ // TODO check timezone offset return new TimeImpl(((Calendar)o).getTimeInMillis(),false); } throw new ExpressionException("can't cast ["+Caster.toClassName(o)+"] to time value"); } public static DateTime toDateAdvanced(Object o,boolean alsoNumbers, TimeZone timeZone, DateTime defaultValue) { return _toDateAdvanced(o, alsoNumbers, timeZone, defaultValue, true); } private static DateTime _toDateAdvanced(Object o,boolean alsoNumbers, TimeZone timeZone, DateTime defaultValue, boolean advanced) { if(o instanceof DateTime) return (DateTime)o; else if(o instanceof Date) return new DateTimeImpl((Date)o); else if(o instanceof Castable) { return ((Castable)o).castToDateTime(defaultValue); } else if(o instanceof String) { if(advanced)return toDateAdvanced(o.toString(),alsoNumbers, timeZone,defaultValue); return toDateSimple(o.toString(),alsoNumbers,true, timeZone,defaultValue); } else if(alsoNumbers && o instanceof Number) return util.toDateTime(((Number)o).doubleValue()); else if(o instanceof ObjectWrap) { return _toDateAdvanced(((ObjectWrap)o).getEmbededObject(defaultValue),alsoNumbers,timeZone,defaultValue,advanced); } else if(o instanceof Calendar){ return new DateTimeImpl((Calendar)o); } return defaultValue; } /** * converts a Object to a DateTime Object, returns null if invalid string * @param str Stringt to Convert * @param alsoNumbers * @param timeZone * @return coverted Date Time Object * @throws PageException */ public static DateTime toDateSimple(String str,boolean alsoNumbers,boolean alsoMonthString, TimeZone timeZone) throws PageException { DateTime dt = toDateSimple(str,alsoNumbers,alsoMonthString,timeZone,null); if(dt==null) throw new ExpressionException("can't cast value to a Date Object"); return dt; } public static DateTime toDateAdvanced(Object o,boolean alsoNumbers, TimeZone timeZone) throws PageException { DateTime dt = toDateAdvanced(o,alsoNumbers,timeZone,null); if(dt==null) throw new ExpressionException("can't cast value to a Date Object"); return dt; } /** * converts a String to a Time Object, returns null if invalid string * @param str String to convert * @param defaultValue * @return Time Object * @throws */ public static Time toTime(TimeZone timeZone,String str, Time defaultValue) { if(str==null || str.length()<3) { return defaultValue; } DateString ds=new DateString(str); // Timestamp if(ds.isCurrent('{') && ds.isLast('}')) { // Time // "^\\{t '([0-9]{1,2}):([0-9]{1,2}):([0-9]{2})'\\}$" if(ds.fwIfNext('t')) { // Time if(!(ds.fwIfNext(' ') && ds.fwIfNext('\'')))return defaultValue; ds.next(); // hour int hour=ds.readDigits(); if(hour==-1) return defaultValue; if(!ds.fwIfCurrent(':'))return defaultValue; // minute int minute=ds.readDigits(); if(minute==-1) return defaultValue; if(!ds.fwIfCurrent(':'))return defaultValue; // second int second=ds.readDigits(); if(second==-1) return defaultValue; if(!(ds.fwIfCurrent('\'') && ds.fwIfCurrent('}')))return defaultValue; if(ds.isAfterLast()){ long time=util.toTime(timeZone,1899,12,30,hour,minute,second,0,DEFAULT_VALUE); if(time==DEFAULT_VALUE)return defaultValue; return new TimeImpl(time,false); } return defaultValue; } return defaultValue; } // Time start with int /*else if(ds.isDigit()) { char sec=ds.charAt(1); char third=ds.charAt(2); // 16.10.2004 (02:15)? if(sec==':' || third==':') { // hour int hour=ds.readDigits(); if(hour==-1) return defaultValue; if(!ds.fwIfCurrent(':'))return defaultValue; // minutes int minutes=ds.readDigits(); if(minutes==-1) return defaultValue; if(ds.isAfterLast()) { long time=util.toTime(timeZone,1899,12,30,hour,minutes,0,0,DEFAULT_VALUE); if(time==DEFAULT_VALUE) return defaultValue; return new TimeImpl(time,false); } //else if(!ds.fwIfCurrent(':'))return null; else if(!ds.fwIfCurrent(':')) { if(!ds.fwIfCurrent(' '))return defaultValue; if(ds.fwIfCurrent('a') || ds.fwIfCurrent('A')) { if(ds.fwIfCurrent('m') || ds.fwIfCurrent('M')) { if(ds.isAfterLast()) { long time=util.toTime(timeZone,1899,12,30,hour,minutes,0,0,DEFAULT_VALUE); if(time==DEFAULT_VALUE) return defaultValue; return new TimeImpl(time,false); } } return defaultValue; } else if(ds.fwIfCurrent('p') || ds.fwIfCurrent('P')) { if(ds.fwIfCurrent('m') || ds.fwIfCurrent('M')) { if(ds.isAfterLast()) { long time=util.toTime(timeZone,1899,12,30,hour<13?hour+12:hour,minutes,0,0,DEFAULT_VALUE); if(time==DEFAULT_VALUE) return defaultValue; return new TimeImpl(time,false); } } return defaultValue; } return defaultValue; } // seconds int seconds=ds.readDigits(); if(seconds==-1) return defaultValue; if(ds.isAfterLast()) { long time=util.toTime(timeZone,1899,12,30,hour,minutes,seconds,0,DEFAULT_VALUE); if(time==DEFAULT_VALUE) return defaultValue; return new TimeImpl(time,false); } } }*/ // TODO bessere impl ds.reset(); DateTime rtn = parseTime(timeZone, new int[]{1899,12,30}, ds, defaultValue,-1); if(rtn==defaultValue) return defaultValue; return new TimeImpl(rtn); //return defaultValue; } /** * converts a String to a DateTime Object, returns null if invalid string * @param str String to convert * @param alsoNumbers * @param alsoMonthString allow that the month is a english name * @param timeZone * @param defaultValue * @return Date Time Object */ private static DateTime parseDateTime(String str,DateString ds,boolean alsoNumbers,boolean alsoMonthString,TimeZone timeZone, DateTime defaultValue) { int month=0; int first=ds.readDigits(); // first if(first==-1) { if(!alsoMonthString) return defaultValue; first=ds.readMonthString(); if(first==-1)return defaultValue; month=1; } if(ds.isAfterLast()) return month==1?defaultValue:toNumberDate(str,alsoNumbers,defaultValue); char del=ds.current(); if(del!='.' && del!='/' && del!='-' && del!=' ' && del!='\t') { if(ds.fwIfCurrent(':')){ return parseTime(timeZone, new int[]{1899,12,30}, ds, defaultValue,first); } return defaultValue; } ds.next(); ds.removeWhitespace(); // second int second=ds.readDigits(); if(second==-1){ if(!alsoMonthString) return defaultValue; second=ds.readMonthString(); if(second==-1)return defaultValue; month=2; } if(ds.isAfterLast()) { return toDate(month,timeZone,first,second,defaultValue); } char del2=ds.current(); if(del!=del2) { ds.fwIfCurrent(' '); ds.fwIfCurrent('T'); ds.fwIfCurrent(' '); return parseTime(timeZone,_toDate(timeZone,month, first, second),ds,defaultValue,-1); } ds.next(); ds.removeWhitespace(); int third=ds.readDigits(); if(third==-1){ return defaultValue; } if(ds.isAfterLast()) { if(classicStyle() && del=='.')return toDate(month,timeZone,second,first,third,defaultValue); return toDate(month,timeZone,first,second,third,defaultValue); } ds.fwIfCurrent(' '); ds.fwIfCurrent('T'); ds.fwIfCurrent(' '); if(classicStyle() && del=='.')return parseTime(timeZone,_toDate(month, second,first,third),ds,defaultValue,-1); return parseTime(timeZone,_toDate(month, first, second,third),ds,defaultValue,-1); } private static boolean classicStyle() { return classicStyle; } private static DateTime parseTime(TimeZone timeZone,int[] date, DateString ds,DateTime defaultValue, int hours) { if(date==null)return defaultValue; ds.removeWhitespace(); // hour boolean next=false; if(hours==-1){ ds.removeWhitespace(); hours=ds.readDigits(); ds.removeWhitespace(); if(hours==-1) { return parseOffset(ds,timeZone,date,0,0,0,0,defaultValue); } } else next=true; int minutes=0; if(next || ds.fwIfCurrent(':')){ ds.removeWhitespace(); minutes=ds.readDigits(); ds.removeWhitespace(); if(minutes==-1) return defaultValue; } int seconds=0; if(ds.fwIfCurrent(':')){ ds.removeWhitespace(); seconds=ds.readDigits(); ds.removeWhitespace(); if(seconds==-1) return defaultValue; } int msSeconds=0; if(ds.fwIfCurrent('.')){ ds.removeWhitespace(); msSeconds=ds.readDigits(); ds.removeWhitespace(); if(msSeconds==-1) return defaultValue; } if(ds.isAfterLast()){ return DateTimeUtil.getInstance().toDateTime(timeZone, date[0], date[1], date[2], hours, minutes, seconds, msSeconds, defaultValue); } ds.fwIfCurrent(' '); if(ds.fwIfCurrent('a') || ds.fwIfCurrent('A')) { if(!ds.fwIfCurrent('m'))ds.fwIfCurrent('M'); if(ds.isAfterLast()) return DateTimeUtil.getInstance().toDateTime(timeZone, date[0], date[1], date[2], hours<12?hours:hours-12, minutes, seconds, msSeconds, defaultValue); return defaultValue; } else if(ds.fwIfCurrent('p') || ds.fwIfCurrent('P')) { if(!ds.fwIfCurrent('m'))ds.fwIfCurrent('M'); if(hours>24) return defaultValue; if(ds.isAfterLast()) return DateTimeUtil.getInstance().toDateTime(timeZone, date[0], date[1], date[2], hours<12?hours+12:hours, minutes, seconds, msSeconds,defaultValue); return defaultValue; } ds.fwIfCurrent(' '); return parseOffset(ds,timeZone,date,hours,minutes,seconds,msSeconds,defaultValue); } private static DateTime parseOffset(DateString ds, TimeZone timeZone, int[] date,int hours, int minutes, int seconds, int msSeconds,DateTime defaultValue) { if(ds.isLast() && (ds.fwIfCurrent('Z') || ds.fwIfCurrent('z'))) { return util.toDateTime(TimeZoneConstants.UTC, date[0], date[1], date[2], hours, minutes, seconds, msSeconds,defaultValue); } else if(ds.fwIfCurrent('+')){ DateTime rtn = util.toDateTime(timeZone, date[0], date[1], date[2], hours, minutes, seconds, msSeconds,defaultValue); if(rtn==defaultValue) return rtn; return readOffset(true,timeZone,rtn,date[0], date[1], date[2], hours, minutes, seconds, msSeconds,ds,defaultValue); } else if(ds.fwIfCurrent('-')){ DateTime rtn = util.toDateTime(timeZone, date[0], date[1], date[2], hours, minutes, seconds, msSeconds, defaultValue); if(rtn==defaultValue) return rtn; return readOffset(false,timeZone,rtn,date[0], date[1], date[2], hours, minutes, seconds, msSeconds,ds,defaultValue); } return defaultValue; } private static DateTime toDate(int month, TimeZone timeZone,int first, int second, DateTime defaultValue) { int[] d = _toDate(timeZone,month, first, second); if(d==null)return defaultValue; return util.toDateTime(timeZone, d[0], d[1], d[2],0,0,0,0,defaultValue); } private static int[] _toDate(TimeZone tz,int month, int first, int second) { int YEAR=year(tz); if(first<=12 && month<2){ if(util.daysInMonth(YEAR, first)>=second) return new int[]{YEAR, first, second}; return new int[]{util.toYear(second), first, 1}; } // first>12 if(second<=12){ if(util.daysInMonth(YEAR, second)>=first) return new int[]{YEAR, second, first}; return new int[]{util.toYear(first), second, 1}; } return null; } private static int year(TimeZone tz) { return util.getYear(ThreadLocalPageContext.getTimeZone(tz),new DateTimeImpl()); } private static DateTime toDate(int month, TimeZone timeZone,int first, int second, int third, DateTime defaultValue) { int[] d = _toDate(month, first, second, third); if(d==null) return defaultValue; return util.toDateTime(timeZone, d[0], d[1], d[2], 0, 0, 0,0,defaultValue); } private static int[] _toDate(int month, int first, int second, int third) { if(first<=12){ if(month==2) return new int[]{util.toYear(third), second, first}; if(util.daysInMonth(util.toYear(third), first)>=second) return new int[]{util.toYear(third), first, second}; return null; } if(second>12)return null; if(month==2){ int tmp=first; first=third; third=tmp; } if(util.daysInMonth(util.toYear(first), second)<third) { if(util.daysInMonth(util.toYear(third), second)>=first) return new int[]{util.toYear(third), second, first}; return null; } return new int[]{util.toYear(first), second, third}; } /** * converts the given string to a date following simple and fast parsing rules (no international formats) * @param str * @param alsoNumbers * @param alsoMonthString allow that the month is defined as english word (jan,janauary ...) * @param timeZone * @param defaultValue * @return */ public static DateTime toDateSimple(String str,boolean alsoNumbers,boolean alsoMonthString, TimeZone timeZone, DateTime defaultValue) { str=StringUtil.trim(str,""); DateString ds=new DateString(str); // Timestamp if(ds.isCurrent('{') && ds.isLast('}')) { return _toDateSimpleTS(ds,timeZone,defaultValue); } DateTime res = parseDateTime(str,ds,alsoNumbers,alsoMonthString,timeZone,defaultValue); if(alsoNumbers && res==defaultValue && Decision.isNumeric(str)) { double dbl = Caster.toDoubleValue(str,Double.NaN); if(Decision.isValid(dbl))return util.toDateTime(dbl); } return res; } private static DateTime _toDateSimpleTS(DateString ds, TimeZone timeZone, DateTime defaultValue) { // Date // "^\\{d '([0-9]{2,4})-([0-9]{1,2})-([0-9]{1,2})'\\}$" if(ds.fwIfNext('d')) { if(!(ds.fwIfNext(' ') && ds.fwIfNext('\'')))return defaultValue; ds.next(); // year int year=ds.readDigits(); if(year==-1) return defaultValue; if(!ds.fwIfCurrent('-'))return defaultValue; // month int month=ds.readDigits(); if(month==-1) return defaultValue; if(!ds.fwIfCurrent('-'))return defaultValue; // day int day=ds.readDigits(); if(day==-1) return defaultValue; if(!(ds.fwIfCurrent('\'') && ds.fwIfCurrent('}')))return defaultValue; if(ds.isAfterLast()) return util.toDateTime(timeZone,year, month, day, 0, 0, 0, 0, defaultValue);//new DateTimeImpl(year,month,day); return defaultValue; } // DateTime // "^\\{ts '([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{2}):([0-9]{1,2}):([0-9]{2})'\\}$" else if(ds.fwIfNext('t')) { if(!(ds.fwIfNext('s') && ds.fwIfNext(' ') && ds.fwIfNext('\''))) { // Time if(!(ds.fwIfNext(' ') && ds.fwIfNext('\'')))return defaultValue; ds.next(); // hour int hour=ds.readDigits(); if(hour==-1) return defaultValue; if(!ds.fwIfCurrent(':'))return defaultValue; // minute int minute=ds.readDigits(); if(minute==-1) return defaultValue; if(!ds.fwIfCurrent(':'))return defaultValue; // second int second=ds.readDigits(); if(second==-1) return defaultValue; // Milli Second int millis=0; if(ds.fwIfCurrent('.')){ millis=ds.readDigits(); } if(!(ds.fwIfCurrent('\'') && ds.fwIfCurrent('}')))return defaultValue; if(ds.isAfterLast()){ long time=util.toTime(timeZone,1899,12,30,hour,minute,second,millis,DEFAULT_VALUE); if(time==DEFAULT_VALUE)return defaultValue; return new TimeImpl(time,false); } return defaultValue; } ds.next(); // year int year=ds.readDigits(); if(year==-1) return defaultValue; if(!ds.fwIfCurrent('-'))return defaultValue; // month int month=ds.readDigits(); if(month==-1) return defaultValue; if(!ds.fwIfCurrent('-'))return defaultValue; // day int day=ds.readDigits(); if(day==-1) return defaultValue; if(!ds.fwIfCurrent(' '))return defaultValue; // hour int hour=ds.readDigits(); if(hour==-1) return defaultValue; if(!ds.fwIfCurrent(':'))return defaultValue; // minute int minute=ds.readDigits(); if(minute==-1) return defaultValue; if(!ds.fwIfCurrent(':'))return defaultValue; // second int second=ds.readDigits(); if(second==-1) return defaultValue; // Milli Second int millis=0; if(ds.fwIfCurrent('.')){ millis=ds.readDigits(); } if(!(ds.fwIfCurrent('\'') && ds.fwIfCurrent('}')))return defaultValue; if(ds.isAfterLast())return util.toDateTime(timeZone,year, month, day,hour,minute,second,millis,defaultValue);//new DateTimeImpl(year,month,day,hour,minute,second); return defaultValue; } else return defaultValue; } private static DateTime toNumberDate(String str,boolean alsoNumbers, DateTime defaultValue) { if(!alsoNumbers) return defaultValue; double dbl = Caster.toDoubleValue(str,Double.NaN); if(Decision.isValid(dbl))return util.toDateTime(dbl); return defaultValue; } /** * reads a offset definition at the end of a date string * @param timeZone * @param dt previous parsed date Object * @param ds DateString to parse * @param defaultValue * @return date Object with offset */ 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) { //timeZone=ThreadLocalPageContext.getTimeZone(timeZone); if(timeZone==null) return defaultValue; // HOUR int hourLength=ds.getPos(); int hour=ds.readDigits(); hourLength=ds.getPos()-hourLength; if(hour==-1) return defaultValue; // MINUTE int minute=0; if(!ds.isAfterLast()) { if(!ds.fwIfCurrent(':'))return defaultValue; minute=ds.readDigits(); if(minute==-1) return defaultValue; } else if(hourLength>2){ int h=hour/100; minute=hour-(h*100); hour=h; } if(hour>12) return defaultValue; if(minute>59) return defaultValue; if(hour==12 && minute>0) return defaultValue; long offset = hour*60L*60L*1000L; offset+=minute*60*1000; if(ds.isAfterLast()) { long time= util.toTime(TimeZoneConstants.UTC, years, months, days, hours, minutes, seconds, milliSeconds, 0); if(isPlus)time-=offset; else time+=offset; return new DateTimeImpl(time,false); } return defaultValue; } public static String toUSDate(Object o, TimeZone timeZone) throws PageException { if(Decision.isUSDate(o)) return Caster.toString(o); DateTime date = DateCaster.toDateAdvanced(o, timeZone); return new railo.runtime.format.DateFormat(Locale.US).format(date,"mm/dd/yyyy"); } public static String toEuroDate(Object o, TimeZone timeZone) throws PageException { if(Decision.isEuroDate(o)) return Caster.toString(o); DateTime date = DateCaster.toDateAdvanced(o, timeZone); return new railo.runtime.format.DateFormat(Locale.US).format(date,"dd.mm.yyyy"); } public static String toShortTime(long time) { return Long.toString(time/1000,36); } public static long fromShortTime(String str) { return Long.parseLong(str,36)*1000; } }