Package railo.runtime.op.date

Source Code of railo.runtime.op.date.DateCaster

// 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;
  }
}
TOP

Related Classes of railo.runtime.op.date.DateCaster

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.