1 3 22 package org.python.modules; 23 24 import org.python.core.*; 25 import java.text.DateFormatSymbols ; 26 import java.text.DateFormat ; 27 import java.lang.reflect.*; 28 import java.util.*; 29 30 class TimeFunctions extends PyBuiltinFunctionSet 31 { 32 public TimeFunctions(String name, int index, int argcount) { 33 super(name, index, argcount, argcount, false, null); 34 } 35 36 public PyObject __call__() { 37 switch (index) { 38 case 0: 39 return Py.newFloat(time.time$()); 40 case 1: 41 return Py.newFloat(time.clock$()); 42 default: 43 throw argCountError(0); 44 } 45 } 46 } 47 48 public class time implements ClassDictInit 49 { 50 public static PyString __doc__ = new PyString( 51 "This module provides various functions to manipulate time values.\n"+ 52 "\n"+ 53 "There are two standard representations of time. One is the "+ 54 "number\n"+ 55 "of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an "+ 56 "integer\n"+ 57 "or a floating point number (to represent fractions of seconds).\n"+ 58 "The Epoch is system-defined; on Unix, it is generally "+ 59 "January 1st, 1970.\n"+ 60 "The actual value can be retrieved by calling gmtime(0).\n"+ 61 "\n"+ 62 "The other representation is a tuple of 9 integers giving "+ 63 "local time.\n"+ 64 "The tuple items are:\n"+ 65 " year (four digits, e.g. 1998)\n"+ 66 " month (1-12)\n"+ 67 " day (1-31)\n"+ 68 " hours (0-23)\n"+ 69 " minutes (0-59)\n"+ 70 " seconds (0-59)\n"+ 71 " weekday (0-6, Monday is 0)\n"+ 72 " Julian day (day in the year, 1-366)\n"+ 73 " DST (Daylight Savings Time) flag (-1, 0 or 1)\n"+ 74 "If the DST flag is 0, the time is given in the regular time zone;\n"+ 75 "if it is 1, the time is given in the DST time zone;\n"+ 76 "if it is -1, mktime() should guess based on the date and time.\n"+ 77 "\n"+ 78 "Variables:\n"+ 79 "\n"+ 80 "timezone -- difference in seconds between UTC and local "+ 81 "standard time\n"+ 82 "altzone -- difference in seconds between UTC and local DST time\n"+ 83 "daylight -- whether local time should reflect DST\n"+ 84 "tzname -- tuple of (standard time zone name, DST time zone name)\n"+ 85 "\n"+ 86 "Functions:\n"+ 87 "\n"+ 88 "time() -- return current time in seconds since the Epoch "+ 89 "as a float\n"+ 90 "clock() -- return CPU time since process start as a float\n"+ 91 "sleep() -- delay for a number of seconds given as a float\n"+ 92 "gmtime() -- convert seconds since Epoch to UTC tuple\n"+ 93 "localtime() -- convert seconds since Epoch to local time tuple\n"+ 94 "asctime() -- convert time tuple to string\n"+ 95 "ctime() -- convert time in seconds to string\n"+ 96 "mktime() -- convert local time tuple to seconds since Epoch\n"+ 97 "strftime() -- convert time tuple to string according to "+ 98 "format specification\n"+ 99 "strptime() -- parse string to time tuple according to "+ 100 "format specification\n" 101 ); 102 103 public static void classDictInit(PyObject dict) { 104 dict.__setitem__("time", new TimeFunctions("time", 0, 0)); 105 dict.__setitem__("clock", new TimeFunctions("clock", 1, 0)); 106 107 TimeZone tz = TimeZone.getDefault(); 109 110 tzname = new PyTuple( 111 new PyObject[] { 112 new PyString(getDisplayName(tz, false, 0)), 113 new PyString(getDisplayName(tz, true, 0)) 114 }); 115 116 daylight = tz.useDaylightTime() ? 1 : 0; 117 timezone = -tz.getRawOffset() / 1000; 118 altzone = timezone - getDSTSavings(tz) / 1000; 119 } 120 121 public static double time$() { 122 return System.currentTimeMillis()/1000.0; 123 } 124 125 private static double __initialclock__ = 0.0; 126 public static double clock$() { 127 if(__initialclock__ == 0.0) { 128 __initialclock__ = time$(); 130 } 131 return time$() - __initialclock__; 132 } 133 134 private static void throwValueError(String msg) { 135 throw new PyException(Py.ValueError, new PyString(msg)); 136 } 137 138 private static int item(PyTuple tup, int i) { 139 int val = ((PyInteger)tup.__getitem__(i).__int__()).getValue(); 142 boolean valid = true; 143 switch (i) { 144 case 0: break; case 1: valid = (1 <= val && val <= 12); break; case 2: valid = (1 <= val && val <= 31); break; case 3: valid = (0 <= val && val <= 23); break; case 4: valid = (0 <= val && val <= 59); break; case 5: valid = (0 <= val && val <= 59); break; case 6: valid = (0 <= val && val <= 6); break; case 7: valid = (1 <= val && val < 367); break; case 8: valid = (-1 <= val && val <= 1); break; } 154 if (!valid) { 156 String msg; 157 switch (i) { 158 case 1: 159 msg = "month out of range (1-12)"; 160 break; 161 case 2: 162 msg = "day out of range (1-31)"; 163 break; 164 case 3: 165 msg = "hour out of range (0-23)"; 166 break; 167 case 4: 168 msg = "minute out of range (0-59)"; 169 break; 170 case 5: 171 msg = "second out of range (0-59)"; 172 break; 173 case 6: 174 msg = "day of week out of range (0-6)"; 175 break; 176 case 7: 177 msg = "day of year out of range (1-366)"; 178 break; 179 case 8: 180 msg = "daylight savings flag out of range (-1,0,1)"; 181 break; 182 default: 183 msg = "ignore"; 185 break; 186 } 187 throwValueError(msg); 188 } 189 if (i == 1) 191 val--; 192 return val; 193 } 194 195 private static GregorianCalendar _tupletocal(PyTuple tup) { 196 return new GregorianCalendar(item(tup, 0), 197 item(tup, 1), 198 item(tup, 2), 199 item(tup, 3), 200 item(tup, 4), 201 item(tup, 5)); 202 } 203 204 public static double mktime(PyTuple tup) { 205 GregorianCalendar cal; 206 try { 207 cal = _tupletocal(tup); 208 } 209 catch (PyException e) { 210 e.type = Py.OverflowError; 212 throw e; 213 } 214 int dst = item(tup, 8); 215 if (dst == 0 || dst == 1) { 216 cal.set(Calendar.DST_OFFSET, 217 dst * getDSTSavings(cal.getTimeZone())); 218 } 219 return (double)cal.getTime().getTime()/1000.0; 220 } 221 222 protected static PyTuple _timefields(double secs, TimeZone tz) { 223 GregorianCalendar cal = new GregorianCalendar(tz); 224 cal.clear(); 225 cal.setTime(new Date((long)(secs*1000))); 226 int dow = cal.get(Calendar.DAY_OF_WEEK)-2; 230 if (dow<0) 231 dow = dow+7; 232 boolean isdst = tz.inDaylightTime(cal.getTime()); 234 return new PyTuple(new PyObject[] { 235 new PyInteger(cal.get(Calendar.YEAR)), 236 new PyInteger(cal.get(Calendar.MONTH)+1), 237 new PyInteger(cal.get(Calendar.DAY_OF_MONTH)), 238 new PyInteger(cal.get(Calendar.HOUR) + 239 12*cal.get(Calendar.AM_PM)), 240 new PyInteger(cal.get(Calendar.MINUTE)), 241 new PyInteger(cal.get(Calendar.SECOND)), 242 new PyInteger(dow), 243 new PyInteger(cal.get(Calendar.DAY_OF_YEAR)), 244 new PyInteger(isdst ? 1 : 0) 245 }); 246 } 247 248 public static PyTuple localtime() { 249 return localtime(time$()); 250 } 251 252 public static PyTuple localtime(double secs) { 253 return _timefields(secs, TimeZone.getDefault()); 254 } 255 256 public static PyTuple gmtime() { 257 return gmtime(time$()); 258 } 259 260 public static PyTuple gmtime(double secs) { 261 return _timefields(secs, TimeZone.getTimeZone("GMT")); 262 } 263 264 public static String ctime() { 265 return ctime(time$()); 266 } 267 268 public static String ctime(double secs) { 269 return asctime(localtime(secs)); 270 } 271 272 protected static Locale currentLocale = null; 274 protected static DateFormatSymbols datesyms = new DateFormatSymbols (); 275 protected static String [] shortdays = null; 276 protected static String [] shortmonths = null; 277 278 private static String _shortday(int dow) { 279 try { 283 if (shortdays == null) { 284 shortdays = new String [7]; 285 String [] names = datesyms.getShortWeekdays(); 286 for (int i=0; i<6; i++) 287 shortdays[i] = names[i+2]; 288 shortdays[6] = names[1]; 289 } 290 } 291 catch (ArrayIndexOutOfBoundsException e) { 292 throwValueError("day of week out of range (0-6)"); 293 } 294 return shortdays[dow]; 295 } 296 297 private static String _shortmonth(int month0to11) { 298 try { 301 if (shortmonths == null) { 302 shortmonths = new String [12]; 303 String [] names = datesyms.getShortMonths(); 304 for (int i=0; i<12; i++) 305 shortmonths[i] = names[i]; 306 } 307 } 308 catch (ArrayIndexOutOfBoundsException e) { 309 throwValueError("month out of range (1-12)"); 310 } 311 return shortmonths[month0to11]; 312 } 313 314 private static String _padint(int i, int target) { 315 String s = Integer.toString(i); 316 int sz = s.length(); 317 if (target <= sz) 318 return s; 320 if (target == sz+1) 321 return "0"+s; 322 if (target == sz+2) 323 return "00"+s; 324 else { 325 char[] c = new char[target-sz]; 326 while (target > sz) { 327 c[target-sz] = '0'; 328 target--; 329 } 330 return new String (c) + s; 331 } 332 } 333 334 private static String _twodigit(int i) { 335 return _padint(i, 2); 336 } 337 338 private static String _truncyear(int year) { 339 String yearstr = _padint(year, 4); 340 return yearstr.substring(yearstr.length()-2, yearstr.length()); 341 } 342 343 public static String asctime() { 344 return asctime(localtime()); 345 } 346 347 public static String asctime(PyTuple tup) { 348 checkLocale(); 349 int day = item(tup, 6); 350 int mon = item(tup, 1); 351 return _shortday(day) + " " + _shortmonth(mon) + " " + 352 _twodigit(item(tup, 2)) + " " + 353 _twodigit(item(tup, 3)) + ":" + 354 _twodigit(item(tup, 4)) + ":" + 355 _twodigit(item(tup, 5)) + " " + 356 item(tup, 0); 357 } 358 359 public static void sleep(double secs) { 360 try { 361 java.lang.Thread.sleep((long)(secs * 1000)); 362 } 363 catch (java.lang.InterruptedException e) { 364 throw new PyException(Py.KeyboardInterrupt, "interrupted sleep"); 365 } 366 } 367 368 public static int timezone; 370 public static int altzone = -1; 371 public static int daylight; 372 public static PyTuple tzname = null; 373 public static final int accept2dyear = 0; 376 377 public static String strftime(String format) { 378 return strftime(format, localtime()); 379 } 380 381 public static String strftime(String format, PyTuple tup) { 382 checkLocale(); 383 384 String s = ""; 385 int lastc = 0; 386 int j; 387 String [] syms; 388 GregorianCalendar cal = null; 389 while (lastc < format.length()) { 390 int i = format.indexOf("%", lastc); 391 if (i < 0) { 392 s = s + format.substring(lastc); 394 break; 395 } 396 if (i == format.length() - 1) { 397 s = s + "%"; 401 break; 402 } 403 s = s + format.substring(lastc, i); 404 i++; 405 switch (format.charAt(i)) { 406 case 'a': 407 j = item(tup, 6); 409 s = s + _shortday(j); 410 break; 411 case 'A': 412 syms = datesyms.getWeekdays(); 415 j = item(tup, 6); 416 if (0 <= j && j < 6) 417 s = s + syms[j+2]; 418 else if (j== 6) 419 s = s + syms[1]; 420 else 421 throwValueError("day of week out of range (0 - 6)"); 422 break; 423 case 'b': 424 j = item(tup, 1); 426 s = s + _shortmonth(j); 427 break; 428 case 'B': 429 syms = datesyms.getMonths(); 431 j = item(tup, 1); 432 s = s + syms[j]; 433 break; 434 case 'c': 435 s = s + asctime(tup); 437 break; 438 case 'd': 439 s = s + _twodigit(item(tup, 2)); 441 break; 442 case 'H': 443 s = s + _twodigit(item(tup, 3)); 445 break; 446 case 'I': 447 j = item(tup, 3) % 12; 449 if (j == 0) 450 j = 12; s = s + _twodigit(j); 452 break; 453 case 'j': 454 s = _padint(item(tup, 7), 3); 456 break; 457 case 'm': 458 s = s + _twodigit(item(tup, 1) + 1); 460 break; 461 case 'M': 462 s = s + _twodigit(item(tup, 4)); 464 break; 465 case 'p': 466 j = item(tup, 3); 468 syms = datesyms.getAmPmStrings(); 469 if (0 <= j && j < 12) 470 s = s + syms[0]; 471 else if (12 <= j && j < 24) 472 s = s + syms[1]; 473 else 474 throwValueError("hour out of range (0-23)"); 475 break; 476 case 'S': 477 s = s + _twodigit(item(tup, 5)); 479 break; 480 case 'U': 481 if (cal == null) 485 cal = _tupletocal(tup); 486 cal.setFirstDayOfWeek(cal.SUNDAY); 487 cal.setMinimalDaysInFirstWeek(7); 488 j = cal.get(cal.WEEK_OF_YEAR); 489 if (cal.get(cal.MONTH) == cal.JANUARY && j >= 52) 490 j = 0; 491 s = s + _twodigit(j); 492 break; 493 case 'w': 494 j = (item(tup, 6) + 1) % 7; 497 s = s + _twodigit(j); 498 break; 499 case 'W': 500 if (cal == null) 504 cal = _tupletocal(tup); 505 cal.setFirstDayOfWeek(cal.MONDAY); 506 cal.setMinimalDaysInFirstWeek(7); 507 j = cal.get(cal.WEEK_OF_YEAR); 508 509 if (cal.get(cal.MONTH) == cal.JANUARY && j >= 52) 510 j = 0; 511 s = s + _twodigit(j); 512 break; 513 case 'x': 514 s = s + _twodigit(item(tup, 1) + 1) + "/" + 531 _twodigit(item(tup, 2)) + "/" + 532 _truncyear(item(tup, 0)); 533 break; 534 case 'X': 535 s = s + _twodigit(item(tup, 3)) + ":" + 537 _twodigit(item(tup, 4)) + ":" + 538 _twodigit(item(tup, 5)); 539 break; 540 case 'Y': 541 s = s + _padint(item(tup, 0), 4); 543 break; 544 case 'y': 545 s = s + _truncyear(item(tup, 0)); 547 break; 548 case 'Z': 549 if (cal == null) 551 cal = _tupletocal(tup); 552 s = s + getDisplayName(cal.getTimeZone(), 553 item(tup, 8) > 0, 0); 557 break; 558 case '%': 559 s = s + "%"; 561 break; 562 default: 563 s = s + "%" + format.charAt(i); 565 i++; 566 break; 567 } 568 lastc = i+1; 569 i++; 570 } 571 return s; 572 } 573 574 575 private static void checkLocale() { 576 if (!Locale.getDefault().equals(currentLocale)) { 577 currentLocale = Locale.getDefault(); 578 datesyms = new DateFormatSymbols (currentLocale); 579 shortdays = null; 580 shortmonths = null; 581 } 582 } 583 584 private static String getDisplayName(TimeZone tz, boolean dst, 585 int style) 586 { 587 String version = System.getProperty("java.version"); 588 if (version.compareTo("1.2") >= 0) { 589 try { 590 Method m = tz.getClass().getMethod("getDisplayName", 591 new Class [] { Boolean.TYPE, Integer.TYPE }); 592 return (String ) m.invoke(tz, new Object [] { 593 new Boolean (dst), new Integer (style) }); 594 } catch (Exception exc) { } 595 } 596 return tz.getID(); 597 } 598 599 private static int getDSTSavings(TimeZone tz) { 600 String version = System.getProperty("java.version"); 601 if (version.compareTo("1.2") >= 0) { 602 try { 603 Method m = tz.getClass().getMethod("getDSTSavings", (Class [])null); 604 return ((Integer ) m.invoke(tz, (Object [])null)).intValue(); 605 } catch (Exception exc) { } 606 } 607 return 0; 608 } 609 } 610 | Popular Tags |