| 1 package gnu.xquery.util; 2 import gnu.xml.*; 3 import gnu.kawa.xml.*; 4 import gnu.math.*; 5 import gnu.mapping.WrongType; 6 import gnu.mapping.Values; 7 import java.math.BigDecimal ; 8 import java.math.BigInteger ; 9 import java.util.TimeZone ; 10 11 public class TimeUtils 12 { 13 static DateTime coerceToDateTime (String fun, Object value) 14 { 15 if (XTimeType.dateTimeType.isInstance(value)) 16 return (DateTime) value; 17 if (value instanceof KNode || value instanceof UntypedAtomic) 18 return XTimeType.parseDateTime(TextUtils.stringValue(value), 19 DateTime.DATE_MASK|DateTime.TIME_MASK); 20 throw new WrongType(fun, 1, value, "xs:dateTime"); 21 } 22 23 static DateTime coerceToDate (String fun, Object value) 24 { 25 if (XTimeType.dateType.isInstance(value)) 26 return (DateTime) value; 27 if (value instanceof KNode || value instanceof UntypedAtomic) 28 return XTimeType.parseDateTime(TextUtils.stringValue(value), 29 DateTime.DATE_MASK); 30 throw new WrongType(fun, 1, value, "xs:date"); 31 } 32 33 static DateTime coerceToTime (String fun, Object value) 34 { 35 if (XTimeType.timeType.isInstance(value)) 36 return (DateTime) value; 37 if (value instanceof KNode || value instanceof UntypedAtomic) 38 return XTimeType.parseDateTime(TextUtils.stringValue(value), 39 DateTime.TIME_MASK); 40 throw new WrongType(fun, 1, value, "xs:time"); 41 } 42 43 static Duration coerceToDuration (String fun, Object value) 44 { 45 if (value instanceof Duration) 46 return (Duration) value; 47 throw new WrongType(fun, 1, value, "xs:duration"); 48 } 49 50 static Object timeZoneFromXTime (DateTime time) 51 { 52 if (time.isZoneUnspecified()) 53 return Values.empty; 54 return Duration.makeMinutes(time.getZoneMinutes()); 55 } 56 57 static IntNum asInteger(int value) 58 { 59 return IntNum.make(value); 60 } 61 62 public static Object yearFromDateTime (Object arg) 63 { 64 if (arg == null || arg == Values.empty) return arg; 65 return asInteger(coerceToDateTime("year-from-dateTime", arg).getYear()); 66 } 67 68 public static Object monthFromDateTime (Object arg) 69 { 70 if (arg == null || arg == Values.empty) return arg; 71 return asInteger(coerceToDateTime("month-from-dateTime", arg).getMonth()); 72 } 73 74 public static Object dayFromDateTime (Object arg) 75 { 76 if (arg == null || arg == Values.empty) return arg; 77 return asInteger(coerceToDateTime("day-from-dateTime", arg).getDay()); 78 } 79 80 public static Object hoursFromDateTime (Object arg) 81 { 82 if (arg == null || arg == Values.empty) return arg; 83 return asInteger(coerceToDateTime("hours-from-dateTime", arg).getHours()); 84 } 85 86 public static Object minutesFromDateTime (Object arg) 87 { 88 if (arg == null || arg == Values.empty) return arg; 89 return asInteger(coerceToDateTime("minutes-from-dateTime", arg).getMinutes()); 90 } 91 92 static Number getSeconds (DateTime date) 93 { 94 int seconds = date.getSecondsOnly(); 95 long nanos = date.getNanoSecondsOnly(); 96 if (nanos == 0) 97 return IntNum.make(seconds); 98 nanos += seconds * 1000000000L; 99 return new BigDecimal (BigInteger.valueOf(nanos), 9); 100 } 101 102 public static Object secondsFromDateTime (Object arg) 103 { 104 if (arg == null || arg == Values.empty) return arg; 105 return getSeconds(coerceToDateTime("seconds-from-dateTime", arg)); 106 } 107 108 public static Object timezoneFromDateTime (Object arg) 109 { 110 if (arg == null || arg == Values.empty) return arg; 111 return timeZoneFromXTime(coerceToDateTime("timezone-from-datetime", arg)); 112 } 113 114 public static Object yearFromDate (Object arg) 115 { 116 if (arg == null || arg == Values.empty) return arg; 117 return asInteger(coerceToDate("year-from-date", arg).getYear()); 118 } 119 120 public static Object monthFromDate (Object arg) 121 { 122 if (arg == null || arg == Values.empty) return arg; 123 return asInteger(coerceToDate("month-from-date", arg).getMonth()); 124 } 125 126 public static Object dayFromDate (Object arg) 127 { 128 if (arg == null || arg == Values.empty) return arg; 129 return asInteger(coerceToDate("day-from-date", arg).getDay()); 130 } 131 132 public static Object timezoneFromDate (Object arg) 133 { 134 if (arg == null || arg == Values.empty) return arg; 135 return timeZoneFromXTime(coerceToDate("timezone-from-date", arg)); 136 } 137 138 public static Object hoursFromTime (Object arg) 139 { 140 if (arg == null || arg == Values.empty) return arg; 141 return asInteger(coerceToTime("hours-from-time", arg).getHours()); 142 } 143 144 public static Object minutesFromTime (Object arg) 145 { 146 if (arg == null || arg == Values.empty) return arg; 147 return asInteger(coerceToTime("minutes-from-time", arg).getMinutes()); 148 } 149 150 public static Object secondsFromTime (Object arg) 151 { 152 if (arg == null || arg == Values.empty) return arg; 153 return getSeconds(coerceToTime("seconds-from-time", arg)); 154 } 155 156 public static Object timezoneFromTime (Object arg) 157 { 158 if (arg == null || arg == Values.empty) return arg; 159 return timeZoneFromXTime(coerceToTime("timezone-from-time", arg)); 160 } 161 162 public static Object yearsFromDuration (Object arg) 163 { 164 if (arg == null || arg == Values.empty) return arg; 165 return asInteger(coerceToDuration("years-from-duration", arg).getYears()); 166 } 167 168 public static Object monthsFromDuration (Object arg) 169 { 170 if (arg == null || arg == Values.empty) return arg; 171 return asInteger(coerceToDuration("months-from-duration", arg).getMonths()); 172 } 173 174 public static Object daysFromDuration (Object arg) 175 { 176 if (arg == null || arg == Values.empty) return arg; 177 return asInteger(coerceToDuration("days-from-duration", arg).getDays()); 178 } 179 180 public static Object hoursFromDuration (Object arg) 181 { 182 if (arg == null || arg == Values.empty) return arg; 183 return asInteger(coerceToDuration("hours-from-duration", arg).getHours()); 184 } 185 186 public static Object minutesFromDuration (Object arg) 187 { 188 if (arg == null || arg == Values.empty) return arg; 189 return asInteger(coerceToDuration("minutes-from-duration", arg).getMinutes()); 190 } 191 192 public static BigDecimal secondsBigDecimalFromDuration (long s, int n) 193 { 194 if (n == 0) 195 return BigDecimal.valueOf(s); 196 int scale = 9; 197 boolean huge = (int) s != s; 199 long ns = huge ? n : s * 1000000000L + n; 200 while (ns % 10 == 0) 201 { 202 ns = ns / 10; 203 scale--; 204 } 205 BigDecimal dec = new BigDecimal (BigInteger.valueOf(ns), scale); 206 if (huge) 207 dec = BigDecimal.valueOf(s).add(dec); 208 return dec; 209 } 210 211 public static Object secondsFromDuration (Object arg) 212 { 213 if (arg == null || arg == Values.empty) return arg; 214 Duration d = coerceToDuration("seconds-from-duration", arg); 215 int s = d.getSecondsOnly(); 216 int n = d.getNanoSecondsOnly(); 217 if (n == 0) 218 return asInteger(s); 219 else 220 return secondsBigDecimalFromDuration(s, n); 221 } 222 223 public static Duration getImplicitTimezone () 224 { 225 return Duration.makeMinutes(TimeZone.getDefault().getRawOffset() / 60000); 226 } 227 228 public static Object adjustDateTimeToTimezone (Object time) 229 { 230 return adjustDateTimeToTimezone(time, getImplicitTimezone()); 231 } 232 233 public static Object adjustDateTimeToTimezone (Object time, Object zone) 234 { 235 if (time == Values.empty || time == null) 236 return time; 237 DateTime dtime = coerceToDateTime("adjust-dateTime-to-timezone", time); 238 return adjustDateTimeToTimezoneRaw(dtime, zone); 239 } 240 241 public static Object adjustDateToTimezone (Object time) 242 { 243 return adjustDateToTimezone(time, getImplicitTimezone()); 244 } 245 246 public static Object adjustDateToTimezone (Object time, Object zone) 247 { 248 if (time == Values.empty || time == null) 249 return time; 250 DateTime dtime = coerceToDate("adjust-date-to-timezone", time); 251 return adjustDateTimeToTimezoneRaw(dtime, zone); 252 } 253 254 public static Object adjustTimeToTimezone (Object time) 255 { 256 return adjustTimeToTimezone(time, getImplicitTimezone()); 257 } 258 259 public static Object adjustTimeToTimezone (Object time, Object zone) 260 { 261 if (time == Values.empty || time == null) 262 return time; 263 DateTime dtime = coerceToTime("adjust-time-to-timezone", time); 264 return adjustDateTimeToTimezoneRaw(dtime, zone); 265 } 266 267 static Object adjustDateTimeToTimezoneRaw (DateTime dtime, Object zone) 268 { 269 if (zone == Values.empty || zone == null) 270 return dtime.withZoneUnspecified(); 271 Duration d = (Duration) zone; 272 if (d.getNanoSecondsOnly() != 0 || d.getSecondsOnly() != 0) 273 throw new IllegalArgumentException ("timezone offset with fractional minute"); 274 int delta = (int) d.getTotalMinutes(); 275 if (delta < -14 * 60 || delta > 14 * 60) 276 throw new IllegalArgumentException ("timezone offset out of range"); 277 return dtime.adjustTimezone(delta); 278 } 279 280 public static DateTime now () 281 { 282 return gnu.kawa.xml.XTimeType.dateTimeType.now(); 283 } 284 285 public static Object dateTime (Object arg1, Object arg2) 286 { 287 if (arg1 == null || arg1 == Values.empty) return arg1; 288 if (arg2 == null || arg2 == Values.empty) return arg2; 289 DateTime date = coerceToDate("dateTime", arg1); 290 DateTime time = coerceToTime("dateTime", arg2); 291 StringBuffer sbuf = new StringBuffer (); 292 date.toStringDate(sbuf); 293 sbuf.append('T'); 294 time.toStringTime(sbuf); 295 boolean hasZone1 = ! date.isZoneUnspecified(); 296 boolean hasZone2 = ! time.isZoneUnspecified(); 297 if (hasZone1 || hasZone2) 298 { 299 int zone1 = date.getZoneMinutes(); 300 int zone2 = time.getZoneMinutes(); 301 if (hasZone1 && hasZone2 && zone1 != zone2) 302 throw new Error ("dateTime: incompatible timezone in arguments"); 303 DateTime.toStringZone(hasZone1 ? zone1 : zone2, sbuf); 304 } 305 return (DateTime) XTimeType.dateTimeType.valueOf(sbuf.toString()); 306 } 307 } 308 | Popular Tags |