001 /** 002 * Implements the Cold Fusion Function datediff 003 */ 004 package railo.runtime.functions.dateTime; 005 006 import java.util.Calendar; 007 import java.util.TimeZone; 008 009 import railo.commons.date.JREDateTimeUtil; 010 import railo.runtime.PageContext; 011 import railo.runtime.exp.ExpressionException; 012 import railo.runtime.exp.FunctionException; 013 import railo.runtime.ext.function.Function; 014 import railo.runtime.op.Decision; 015 import railo.runtime.type.dt.DateTime; 016 017 /** 018 * 019 */ 020 public final class DateDiff implements Function { 021 //private static Calendar calendar; 022 //private static Calendar cLeft; 023 //private static Calendar cRight; 024 025 private static final int DATEPART_S = 0; 026 private static final int DATEPART_N = 1; 027 private static final int DATEPART_H = 2; 028 private static final int DATEPART_D = 3; 029 private static final int DATEPART_Y = DATEPART_D; 030 private static final int DATEPART_YYYY = 10; 031 private static final int DATEPART_M = 11; 032 private static final int DATEPART_W = 12; 033 private static final int DATEPART_WW = DATEPART_W; 034 private static final int DATEPART_Q = 20; 035 036 private static Calendar _cRight; 037 private static Calendar _cLeft; 038 039 040 /** 041 * @param pc 042 * @param s 043 * @param date 044 * @param date1 045 * @return 046 * @throws ExpressionException 047 */ 048 public synchronized static double call(PageContext pc , String datePart, DateTime left, DateTime right) throws ExpressionException { 049 long msLeft = left.getTime(); 050 long msRight = right.getTime(); 051 TimeZone tz = pc.getTimeZone(); 052 //if(true)return 0; 053 // Date Part 054 datePart=datePart.toLowerCase().trim(); 055 int dp; 056 if("s".equals(datePart)) return diffSeconds(msLeft, msRight); 057 else if("n".equals(datePart)) return diffSeconds(msLeft, msRight)/60L; 058 else if("h".equals(datePart)) return diffSeconds(msLeft, msRight)/3600L; 059 else if("d".equals(datePart)) dp=DATEPART_D; 060 else if("y".equals(datePart)) dp=DATEPART_Y; 061 else if("yyyy".equals(datePart))dp=DATEPART_YYYY; 062 else if("m".equals(datePart)) dp=DATEPART_M; 063 else if("w".equals(datePart)) dp=DATEPART_W; 064 else if("ww".equals(datePart)) dp=DATEPART_WW; 065 else if("q".equals(datePart)) dp=DATEPART_Q; 066 else throw new FunctionException(pc,"dateDiff",3,"datePart","invalid value ["+datePart+"], valid values has to be [q,s,n,h,d,m,y,yyyy,w,ww]"); 067 068 069 070 // dates 071 if(_cLeft==null) _cLeft = JREDateTimeUtil.newInstance(tz); 072 //synchronized(_cLeft){ 073 _cLeft.clear(); 074 _cLeft.setTimeZone(tz); 075 _cLeft.setTimeInMillis(msLeft); 076 //long msLeft = _cLeft.getTimeInMillis(); 077 078 if(_cRight==null) _cRight = JREDateTimeUtil.newInstance(tz); 079 else { 080 _cRight.clear(); 081 _cRight.setTimeZone(tz); 082 } 083 _cRight.setTimeInMillis(msRight); 084 //long msRight = _cRight.getTimeInMillis(); 085 086 087 if(msLeft>msRight) 088 return -_call(pc,dp, _cRight, msRight, _cLeft, msLeft); 089 090 return _call(pc,dp, _cLeft, msLeft, _cRight, msRight); 091 //} 092 } 093 094 public static long diffSeconds(long msLeft, long msRight) { 095 if(msLeft>msRight) 096 return -(long)((msLeft-msRight)/1000D); 097 return (long)((msRight-msLeft)/1000D); 098 } 099 100 /*private static long _call(int datepart, long msLeft, long msRight) throws ExpressionException { 101 102 long msDiff = msRight-msLeft; 103 double diff = msDiff/1000D; 104 if(DATEPART_S==datepart) { 105 return (long) diff; 106 } 107 if(DATEPART_N==datepart) { 108 return (long)(diff/60D); 109 } 110 if(DATEPART_H==datepart) { 111 return (long)(diff/3600D); 112 } 113 return 0; 114 }*/ 115 116 private static long _call(PageContext pc , int datepart, Calendar cLeft, long msLeft, Calendar cRight, long msRight) throws ExpressionException { 117 118 //long msDiff = msRight-msLeft; 119 //double diff = msDiff/1000D; 120 /*if(DATEPART_S==datepart) { 121 return (long) diff; 122 } 123 if(DATEPART_N==datepart) { 124 return (long)(diff/60D); 125 } 126 if(DATEPART_H==datepart) { 127 return (long)(diff/3600D); 128 }*/ 129 130 long dDiff = cRight.get(Calendar.DATE)-cLeft.get(Calendar.DATE); 131 long hDiff = cRight.get(Calendar.HOUR_OF_DAY)-cLeft.get(Calendar.HOUR_OF_DAY); 132 long nDiff = cRight.get(Calendar.MINUTE)-cLeft.get(Calendar.MINUTE); 133 long sDiff = cRight.get(Calendar.SECOND)-cLeft.get(Calendar.SECOND); 134 135 136 if(DATEPART_D==datepart || DATEPART_W==datepart) { 137 138 int tmp=0; 139 if(hDiff<0) tmp=-1; 140 else if(hDiff>0); 141 else if(nDiff<0) tmp=-1; 142 else if(nDiff>0); 143 else if(sDiff<0) tmp=-1; 144 else if(sDiff>0); 145 long rst = dayDiff(cLeft, cRight)+tmp; 146 if(DATEPART_W==datepart)rst/=7; 147 return rst; 148 } 149 150 long yDiff = cRight.get(Calendar.YEAR)-cLeft.get(Calendar.YEAR); 151 long mDiff = cRight.get(Calendar.MONTH)-cLeft.get(Calendar.MONTH); 152 if(DATEPART_YYYY==datepart) { 153 int tmp=0; 154 if(mDiff<0) tmp=-1; 155 else if(mDiff>0); 156 else if(dDiff<0) tmp=-1; 157 else if(dDiff>0); 158 else if(hDiff<0) tmp=-1; 159 else if(hDiff>0); 160 else if(nDiff<0) tmp=-1; 161 else if(nDiff>0); 162 else if(sDiff<0) tmp=-1; 163 else if(sDiff>0); 164 return yDiff+tmp; 165 } 166 if(DATEPART_M==datepart || DATEPART_Q==datepart) { 167 168 int tmp=0; 169 if(dDiff<0) tmp=-1; 170 else if(dDiff>0); 171 else if(hDiff<0) tmp=-1; 172 else if(hDiff>0); 173 else if(nDiff<0) tmp=-1; 174 else if(nDiff>0); 175 else if(sDiff<0) tmp=-1; 176 else if(sDiff>0); 177 long rst = mDiff+(yDiff*12)+tmp; 178 if(DATEPART_Q==datepart)rst/=3; 179 return rst; 180 } 181 if(DATEPART_D==datepart) { 182 183 long rst = dDiff; 184 //if(DATEPART_Q==datepart)rst/=3; 185 return rst; 186 } 187 188 189 throw new FunctionException(pc,"dateDiff",3,"datePart","invalid value, valid values has to be [q,s,n,h,d,m,y,yyyy,w,ww]"); 190 191 } 192 193 194 195 private static long dayDiff(Calendar l, Calendar r) { 196 int lYear = l.get(Calendar.YEAR); 197 int rYear = r.get(Calendar.YEAR); 198 int lDayOfYear=l.get(Calendar.DAY_OF_YEAR); 199 int rDayOfYear=r.get(Calendar.DAY_OF_YEAR); 200 201 202 // same year 203 if(lYear==rYear){ 204 return rDayOfYear-lDayOfYear; 205 } 206 207 long diff=rDayOfYear; 208 diff-=lDayOfYear; 209 for(int year=lYear;year<rYear;year++){ 210 diff+=Decision.isLeapYear(year)?366L:365L; 211 } 212 return diff; 213 } 214 215 }