00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 #ifndef HAVE_SYS_TIMEB_H
00027 #define HAVE_SYS_TIMEB_H 0
00028 #endif
00029
00030 #if TIME_WITH_SYS_TIME
00031 # include <sys/time.h>
00032 # include <time.h>
00033 #else
00034 #if HAVE_SYS_TIME_H
00035 #include <sys/time.h>
00036 #else
00037 # include <time.h>
00038 # endif
00039 #endif
00040 #if HAVE_SYS_TIMEB_H
00041 #include <sys/timeb.h>
00042 #endif
00043
00044 #ifdef HAVE_SYS_PARAM_H
00045 # include <sys/param.h>
00046 #endif // HAVE_SYS_PARAM_H
00047
00048 #include <math.h>
00049 #include <string.h>
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052 #include <locale.h>
00053 #include <ctype.h>
00054
00055 #include "date_object.h"
00056 #include "error_object.h"
00057 #include "operations.h"
00058
00059 #include "date_object.lut.h"
00060
00061 const time_t invalidDate = -1;
00062
00063 using namespace KJS;
00064
00065
00066
00067 const ClassInfo DateInstanceImp::info = {"Date", 0, 0, 0};
00068
00069 DateInstanceImp::DateInstanceImp(ObjectImp *proto)
00070 : ObjectImp(proto)
00071 {
00072 }
00073
00074
00075
00076 const ClassInfo DatePrototypeImp::info = {"Date", 0, &dateTable, 0};
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 DatePrototypeImp::DatePrototypeImp(ExecState *,
00131 ObjectPrototypeImp *objectProto)
00132 : DateInstanceImp(objectProto)
00133 {
00134 Value protect(this);
00135 setInternalValue(Number(NaN));
00136
00137 }
00138
00139 Value DatePrototypeImp::get(ExecState *exec, const Identifier &propertyName) const
00140 {
00141 return lookupGetFunction<DateProtoFuncImp, ObjectImp>( exec, propertyName, &dateTable, this );
00142 }
00143
00144
00145
00146 DateProtoFuncImp::DateProtoFuncImp(ExecState *exec, int i, int len)
00147 : InternalFunctionImp(
00148 static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
00149 ), id(abs(i)), utc(i<0)
00150
00151 {
00152 Value protect(this);
00153 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
00154 }
00155
00156 bool DateProtoFuncImp::implementsCall() const
00157 {
00158 return true;
00159 }
00160
00161 Value DateProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
00162 {
00163 if ((id == ToString || id == ValueOf || id == GetTime || id == SetTime) &&
00164 !thisObj.inherits(&DateInstanceImp::info)) {
00165
00166
00167
00168
00169 Object err = Error::create(exec,TypeError);
00170 exec->setException(err);
00171 return err;
00172 }
00173
00174
00175 Value result;
00176 UString s;
00177 const int bufsize=100;
00178 char timebuffer[bufsize];
00179 CString oldlocale = setlocale(LC_TIME,NULL);
00180 if (!oldlocale.c_str())
00181 oldlocale = setlocale(LC_ALL, NULL);
00182 Value v = thisObj.internalValue();
00183 double milli = v.toNumber(exec);
00184
00185 if (isNaN(milli)) {
00186 switch (id) {
00187 case ToString:
00188 case ToDateString:
00189 case ToTimeString:
00190 case ToGMTString:
00191 case ToUTCString:
00192 case ToLocaleString:
00193 case ToLocaleDateString:
00194 case ToLocaleTimeString:
00195 return String("Invalid Date");
00196 case ValueOf:
00197 case GetTime:
00198 case GetYear:
00199 case GetFullYear:
00200 case GetMonth:
00201 case GetDate:
00202 case GetDay:
00203 case GetHours:
00204 case GetMinutes:
00205 case GetSeconds:
00206 case GetMilliSeconds:
00207 case GetTimezoneOffset:
00208 return Number(NaN);
00209 }
00210 }
00211 time_t tv = (time_t) floor(milli / 1000.0);
00212 int ms = int(milli - tv * 1000.0);
00213
00214
00215
00216
00217
00218 if (sizeof(time_t) == 4)
00219 {
00220
00221 if ( (time_t)-1 < 0 ) {
00222 if ( floor(milli / 1000.0) > ((double)((uint)1<<31)-1) ) {
00223 #ifdef KJS_VERBOSE
00224 fprintf(stderr, "date above time_t limit. Year seems to be %d\n", (int)(milli/(1000.0*365.25*86400)+1970));
00225 #endif
00226 tv = ((uint)1<<31)-1;
00227 ms = 0;
00228 }
00229 }
00230 else
00231
00232 if ( floor(milli / 1000.0) > ((double)(uint)-1) ) {
00233 #ifdef KJS_VERBOSE
00234 fprintf(stderr, "date above time_t limit. Year seems to be %d\n", (int)(milli/(1000.0*365.25*86400)+1970));
00235 #endif
00236 tv = (uint)-1;
00237 ms = 0;
00238 }
00239 }
00240
00241 struct tm *t;
00242 if (utc)
00243 t = gmtime(&tv);
00244 else
00245 t = localtime(&tv);
00246
00247
00248 const char xFormat[] = "%x";
00249 const char cFormat[] = "%c";
00250
00251 switch (id) {
00252 case ToString:
00253 case ToDateString:
00254 case ToTimeString:
00255 case ToGMTString:
00256 case ToUTCString:
00257 setlocale(LC_TIME,"C");
00258 if (id == DateProtoFuncImp::ToDateString) {
00259 strftime(timebuffer, bufsize, xFormat, t);
00260 } else if (id == DateProtoFuncImp::ToTimeString) {
00261 strftime(timebuffer, bufsize, "%X",t);
00262 } else {
00263 t = (id == ToString ? localtime(&tv) : gmtime(&tv));
00264 strftime(timebuffer, bufsize, "%a, %d %b %Y %H:%M:%S %z", t);
00265 }
00266 setlocale(LC_TIME,oldlocale.c_str());
00267 result = String(timebuffer);
00268 break;
00269 case ToLocaleString:
00270 strftime(timebuffer, bufsize, cFormat, t);
00271 result = String(timebuffer);
00272 break;
00273 case ToLocaleDateString:
00274 strftime(timebuffer, bufsize, xFormat, t);
00275 result = String(timebuffer);
00276 break;
00277 case ToLocaleTimeString:
00278 strftime(timebuffer, bufsize, "%X", t);
00279 result = String(timebuffer);
00280 break;
00281 case ValueOf:
00282 result = Number(milli);
00283 break;
00284 case GetTime:
00285 result = Number(milli);
00286 break;
00287 case GetYear:
00288
00289 if ( exec->interpreter()->compatMode() != Interpreter::IECompat )
00290 result = Number(t->tm_year);
00291 else
00292 result = Number(1900 + t->tm_year);
00293 break;
00294 case GetFullYear:
00295 result = Number(1900 + t->tm_year);
00296 break;
00297 case GetMonth:
00298 result = Number(t->tm_mon);
00299 break;
00300 case GetDate:
00301 result = Number(t->tm_mday);
00302 break;
00303 case GetDay:
00304 result = Number(t->tm_wday);
00305 break;
00306 case GetHours:
00307 result = Number(t->tm_hour);
00308 break;
00309 case GetMinutes:
00310 result = Number(t->tm_min);
00311 break;
00312 case GetSeconds:
00313 result = Number(t->tm_sec);
00314 break;
00315 case GetMilliSeconds:
00316 result = Number(ms);
00317 break;
00318 case GetTimezoneOffset:
00319 #if defined BSD || defined(__APPLE__)
00320 result = Number(-(t->tm_gmtoff / 60) + (t->tm_isdst > 0 ? 60 : 0));
00321 #else
00322 # if defined(__BORLANDC__)
00323 #error please add daylight savings offset here!
00324 result = Number(_timezone / 60 - (t->tm_isdst > 0 ? 60 : 0));
00325 # else
00326 result = Number((timezone / 60 - (t->tm_isdst > 0 ? 60 : 0 )));
00327 # endif
00328 #endif
00329 break;
00330 case SetTime:
00331 milli = roundValue(exec,args[0]);
00332 result = Number(milli);
00333 thisObj.setInternalValue(result);
00334 break;
00335 case SetMilliSeconds:
00336 ms = args[0].toInt32(exec);
00337 break;
00338 case SetSeconds:
00339 t->tm_sec = args[0].toInt32(exec);
00340 if (args.size() >= 2)
00341 ms = args[1].toInt32(exec);
00342 break;
00343 case SetMinutes:
00344 t->tm_min = args[0].toInt32(exec);
00345 if (args.size() >= 2)
00346 t->tm_sec = args[1].toInt32(exec);
00347 if (args.size() >= 3)
00348 ms = args[2].toInt32(exec);
00349 break;
00350 case SetHours:
00351 t->tm_hour = args[0].toInt32(exec);
00352 if (args.size() >= 2)
00353 t->tm_min = args[1].toInt32(exec);
00354 if (args.size() >= 3)
00355 t->tm_sec = args[2].toInt32(exec);
00356 if (args.size() >= 4)
00357 ms = args[3].toInt32(exec);
00358 break;
00359 case SetDate:
00360 t->tm_mday = args[0].toInt32(exec);
00361 break;
00362 case SetMonth:
00363 t->tm_mon = args[0].toInt32(exec);
00364 if (args.size() >= 2)
00365 t->tm_mday = args[1].toInt32(exec);
00366 break;
00367 case SetFullYear:
00368 t->tm_year = args[0].toInt32(exec) - 1900;
00369 if (args.size() >= 2)
00370 t->tm_mon = args[1].toInt32(exec);
00371 if (args.size() >= 3)
00372 t->tm_mday = args[2].toInt32(exec);
00373 break;
00374 case SetYear:
00375 t->tm_year = args[0].toInt32(exec) >= 1900 ? args[0].toInt32(exec) - 1900 : args[0].toInt32(exec);
00376 break;
00377 }
00378
00379 if (id == SetYear || id == SetMilliSeconds || id == SetSeconds ||
00380 id == SetMinutes || id == SetHours || id == SetDate ||
00381 id == SetMonth || id == SetFullYear ) {
00382 result = Number(mktime(t) * 1000.0 + ms);
00383 thisObj.setInternalValue(result);
00384 }
00385
00386 return result;
00387 }
00388
00389
00390
00391
00392
00393 DateObjectImp::DateObjectImp(ExecState *exec,
00394 FunctionPrototypeImp *funcProto,
00395 DatePrototypeImp *dateProto)
00396 : InternalFunctionImp(funcProto)
00397 {
00398 Value protect(this);
00399
00400
00401 putDirect(prototypePropertyName, dateProto, DontEnum|DontDelete|ReadOnly);
00402
00403 static const Identifier parsePropertyName("parse");
00404 putDirect(parsePropertyName, new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::Parse, 1), DontEnum);
00405 static const Identifier UTCPropertyName("UTC");
00406 putDirect(UTCPropertyName, new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::UTC, 7), DontEnum);
00407
00408
00409 putDirect(lengthPropertyName, 7, ReadOnly|DontDelete|DontEnum);
00410 }
00411
00412 bool DateObjectImp::implementsConstruct() const
00413 {
00414 return true;
00415 }
00416
00417
00418 Object DateObjectImp::construct(ExecState *exec, const List &args)
00419 {
00420 int numArgs = args.size();
00421
00422 #ifdef KJS_VERBOSE
00423 fprintf(stderr,"DateObjectImp::construct - %d args\n", numArgs);
00424 #endif
00425 Value value;
00426
00427 if (numArgs == 0) {
00428 #if HAVE_SYS_TIMEB_H
00429 # if defined(__BORLANDC__)
00430 struct timeb timebuffer;
00431 ftime(&timebuffer);
00432 # else
00433 struct _timeb timebuffer;
00434 _ftime(&timebuffer);
00435 # endif
00436 double utc = floor((double)timebuffer.time * 1000.0 + (double)timebuffer.millitm);
00437 #else
00438 struct timeval tv;
00439 gettimeofday(&tv, 0L);
00440 double utc = floor((double)tv.tv_sec * 1000.0 + (double)tv.tv_usec / 1000.0);
00441 #endif
00442 value = Number(utc);
00443 } else if (numArgs == 1) {
00444 UString s = args[0].toString(exec);
00445 double d = s.toDouble();
00446 if (isNaN(d))
00447 value = parseDate(s);
00448 else
00449 value = Number(d);
00450 } else {
00451 struct tm t;
00452 memset(&t, 0, sizeof(t));
00453 int year = args[0].toInt32(exec);
00454
00455 t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
00456 t.tm_mon = args[1].toInt32(exec);
00457 t.tm_mday = (numArgs >= 3) ? args[2].toInt32(exec) : 1;
00458 t.tm_hour = (numArgs >= 4) ? args[3].toInt32(exec) : 0;
00459 t.tm_min = (numArgs >= 5) ? args[4].toInt32(exec) : 0;
00460 t.tm_sec = (numArgs >= 6) ? args[5].toInt32(exec) : 0;
00461 t.tm_isdst = -1;
00462 int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0;
00463 value = Number(mktime(&t) * 1000.0 + ms);
00464 }
00465
00466 Object proto = exec->interpreter()->builtinDatePrototype();
00467 Object ret(new DateInstanceImp(proto.imp()));
00468 ret.setInternalValue(timeClip(value));
00469 return ret;
00470 }
00471
00472 bool DateObjectImp::implementsCall() const
00473 {
00474 return true;
00475 }
00476
00477
00478 Value DateObjectImp::call(ExecState* , Object &, const List &)
00479 {
00480 #ifdef KJS_VERBOSE
00481 fprintf(stderr,"DateObjectImp::call - current time\n");
00482 #endif
00483 time_t t = time(0L);
00484 UString s(ctime(&t));
00485
00486
00487 return String(s.substr(0, s.size() - 1));
00488 }
00489
00490
00491
00492 DateObjectFuncImp::DateObjectFuncImp(ExecState* , FunctionPrototypeImp *funcProto,
00493 int i, int len)
00494 : InternalFunctionImp(funcProto), id(i)
00495 {
00496 Value protect(this);
00497 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
00498 }
00499
00500 bool DateObjectFuncImp::implementsCall() const
00501 {
00502 return true;
00503 }
00504
00505
00506 Value DateObjectFuncImp::call(ExecState *exec, Object &, const List &args)
00507 {
00508 if (id == Parse) {
00509 return parseDate(args[0].toString(exec));
00510 } else {
00511 struct tm t;
00512 memset(&t, 0, sizeof(t));
00513 int n = args.size();
00514 int year = args[0].toInt32(exec);
00515
00516 t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
00517 t.tm_mon = args[1].toInt32(exec);
00518 t.tm_mday = (n >= 3) ? args[2].toInt32(exec) : 1;
00519 t.tm_hour = (n >= 4) ? args[3].toInt32(exec) : 0;
00520 t.tm_min = (n >= 5) ? args[4].toInt32(exec) : 0;
00521 t.tm_sec = (n >= 6) ? args[5].toInt32(exec) : 0;
00522 int ms = (n >= 7) ? args[6].toInt32(exec) : 0;
00523 return Number(mktime(&t) * 1000.0 + ms);
00524 }
00525 }
00526
00527
00528
00529
00530 Value KJS::parseDate(const UString &u)
00531 {
00532 #ifdef KJS_VERBOSE
00533 fprintf(stderr,"KJS::parseDate %s\n",u.ascii());
00534 #endif
00535 double seconds = KRFCDate_parseDate( u );
00536 #ifdef KJS_VERBOSE
00537 fprintf(stderr,"KRFCDate_parseDate returned seconds=%g\n",seconds);
00538 bool withinLimits = true;
00539 if ( sizeof(time_t) == 4 )
00540 {
00541 int limit = ((time_t)-1 < 0) ? 2038 : 2115;
00542 if ( seconds > (limit-1970) * 365.25 * 86400 ) {
00543 fprintf(stderr, "date above time_t limit. Year seems to be %d\n", (int)(seconds/(365.25*86400)+1970));
00544 withinLimits = false;
00545 }
00546 }
00547 if ( withinLimits ) {
00548 time_t lsec = (time_t)seconds;
00549 fprintf(stderr, "this is: %s\n", ctime(&lsec));
00550 }
00551 #endif
00552
00553 return Number(seconds == -1 ? NaN : seconds * 1000.0);
00554 }
00555
00557
00558 static double ymdhms_to_seconds(int year, int mon, int day, int hour, int minute, int second)
00559 {
00560
00561
00562 double ret = (day - 32075)
00563 + 1461L * (year + 4800L + (mon - 14) / 12) / 4
00564 + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12
00565 - 3 * ((year + 4900L + (mon - 14) / 12) / 100) / 4
00566 - 2440588;
00567 ret = 24*ret + hour;
00568 ret = 60*ret + minute;
00569 ret = 60*ret + second;
00570
00571 return ret;
00572 }
00573
00574 static const char haystack[37]="janfebmaraprmayjunjulaugsepoctnovdec";
00575
00576
00577
00578 static const struct {
00579 const char tzName[4];
00580 int tzOffset;
00581 } known_zones[] = {
00582 { "UT", 0 },
00583 { "GMT", 0 },
00584 { "EST", -300 },
00585 { "EDT", -240 },
00586 { "CST", -360 },
00587 { "CDT", -300 },
00588 { "MST", -420 },
00589 { "MDT", -360 },
00590 { "PST", -480 },
00591 { "PDT", -420 },
00592 { { 0, 0, 0, 0 }, 0 }
00593 };
00594
00595 int KJS::local_timeoffset()
00596 {
00597 static int local_offset = -1;
00598
00599 if ( local_offset != -1 ) return local_offset;
00600
00601 time_t local = time(0);
00602 struct tm* tm_local = gmtime(&local);
00603 local_offset = local-mktime(tm_local);
00604 if(tm_local->tm_isdst)
00605 local_offset += 3600;
00606
00607 return local_offset;
00608 }
00609
00610 double KJS::KRFCDate_parseDate(const UString &_date)
00611 {
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 double result = -1;
00627 int offset = 0;
00628 bool have_tz = false;
00629 char *newPosStr;
00630 const char *dateString = _date.ascii();
00631 int day = 0;
00632 char monthStr[4];
00633 int month = -1;
00634 int year = 0;
00635 int hour = 0;
00636 int minute = 0;
00637 int second = 0;
00638 bool have_time = false;
00639
00640
00641 while(*dateString && isspace(*dateString))
00642 dateString++;
00643
00644 const char *wordStart = dateString;
00645
00646 while(*dateString && !isdigit(*dateString))
00647 {
00648 if ( isspace(*dateString) && dateString - wordStart >= 3 )
00649 {
00650 monthStr[0] = tolower(*wordStart++);
00651 monthStr[1] = tolower(*wordStart++);
00652 monthStr[2] = tolower(*wordStart++);
00653 monthStr[3] = '\0';
00654
00655 const char *str = strstr(haystack, monthStr);
00656 if (str) {
00657 int position = str - haystack;
00658 if (position % 3 == 0) {
00659 month = position / 3;
00660 }
00661 }
00662 while(*dateString && isspace(*dateString))
00663 dateString++;
00664 wordStart = dateString;
00665 }
00666 else
00667 dateString++;
00668 }
00669
00670 while(*dateString && isspace(*dateString))
00671 dateString++;
00672
00673 if (!*dateString)
00674 return invalidDate;
00675
00676
00677 day = strtol(dateString, &newPosStr, 10);
00678 dateString = newPosStr;
00679
00680 if ((day < 1) || (day > 31))
00681 return invalidDate;
00682 if (!*dateString)
00683 return invalidDate;
00684
00685 if (*dateString == '/' && day <= 12 && month == -1)
00686 {
00687 dateString++;
00688
00689 month = day - 1;
00690 day = strtol(dateString, &newPosStr, 10);
00691 dateString = newPosStr;
00692 if (*dateString == '/')
00693 dateString++;
00694 if (!*dateString)
00695 return invalidDate;
00696
00697 }
00698 else
00699 {
00700 if (*dateString == '-')
00701 dateString++;
00702
00703 while(*dateString && isspace(*dateString))
00704 dateString++;
00705
00706 if (*dateString == ',')
00707 dateString++;
00708
00709 if ( month == -1 )
00710 {
00711 for(int i=0; i < 3;i++)
00712 {
00713 if (!*dateString || (*dateString == '-') || isspace(*dateString))
00714 return invalidDate;
00715 monthStr[i] = tolower(*dateString++);
00716 }
00717 monthStr[3] = '\0';
00718
00719 newPosStr = (char*)strstr(haystack, monthStr);
00720
00721 if (!newPosStr || (newPosStr - haystack) % 3 != 0)
00722 return invalidDate;
00723
00724 month = (newPosStr-haystack)/3;
00725
00726 if ((month < 0) || (month > 11))
00727 return invalidDate;
00728
00729 while(*dateString && (*dateString != '-') && !isspace(*dateString))
00730 dateString++;
00731
00732 if (!*dateString)
00733 return invalidDate;
00734
00735
00736 if ((*dateString != '-') && (*dateString != '/') && !isspace(*dateString))
00737 return invalidDate;
00738 dateString++;
00739 }
00740
00741 if ((month < 0) || (month > 11))
00742 return invalidDate;
00743 }
00744
00745
00746 year = strtol(dateString, &newPosStr, 10);
00747
00748
00749 if (*newPosStr)
00750 {
00751
00752 if (!isspace(*newPosStr)) {
00753 if ( *newPosStr == ':' )
00754 year = -1;
00755 else
00756 return invalidDate;
00757 } else
00758 dateString = ++newPosStr;
00759
00760 have_time = true;
00761 hour = strtol(dateString, &newPosStr, 10);
00762 dateString = newPosStr;
00763
00764 if ((hour < 0) || (hour > 23))
00765 return invalidDate;
00766
00767 if (!*dateString)
00768 return invalidDate;
00769
00770
00771 if (*dateString++ != ':')
00772 return invalidDate;
00773
00774 minute = strtol(dateString, &newPosStr, 10);
00775 dateString = newPosStr;
00776
00777 if ((minute < 0) || (minute > 59))
00778 return invalidDate;
00779
00780
00781 if (*dateString && *dateString != ':' && !isspace(*dateString))
00782 return invalidDate;
00783
00784
00785 if (*dateString ==':') {
00786 dateString++;
00787
00788 second = strtol(dateString, &newPosStr, 10);
00789 dateString = newPosStr;
00790
00791 if ((second < 0) || (second > 59))
00792 return invalidDate;
00793 }
00794
00795 while(*dateString && isspace(*dateString))
00796 dateString++;
00797 }
00798 else
00799 dateString = newPosStr;
00800
00801
00802
00803
00804 if (*dateString) {
00805
00806 if ( (dateString[0] == 'G' && dateString[1] == 'M' && dateString[2] == 'T')
00807 || (dateString[0] == 'U' && dateString[1] == 'T' && dateString[2] == 'C') )
00808 {
00809 dateString += 3;
00810 have_tz = true;
00811 }
00812
00813 while (*dateString && isspace(*dateString))
00814 ++dateString;
00815
00816 if (strncasecmp(dateString, "GMT", 3) == 0) {
00817 dateString += 3;
00818 }
00819 if ((*dateString == '+') || (*dateString == '-')) {
00820 offset = strtol(dateString, &newPosStr, 10);
00821 dateString = newPosStr;
00822
00823 if ((offset < -9959) || (offset > 9959))
00824 return invalidDate;
00825
00826 int sgn = (offset < 0)? -1:1;
00827 offset = abs(offset);
00828 if ( *dateString == ':' ) {
00829 int offset2 = strtol(dateString, &newPosStr, 10);
00830 dateString = newPosStr;
00831 offset = (offset*60 + offset2)*sgn;
00832 }
00833 else
00834 offset = ((offset / 100)*60 + (offset % 100))*sgn;
00835 have_tz = true;
00836 } else {
00837 for (int i=0; known_zones[i].tzName != 0; i++) {
00838 if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
00839 offset = known_zones[i].tzOffset;
00840 have_tz = true;
00841 break;
00842 }
00843 }
00844 }
00845 }
00846
00847 while(*dateString && isspace(*dateString))
00848 dateString++;
00849
00850 if ( *dateString && year == -1 ) {
00851 year = strtol(dateString, &newPosStr, 10);
00852 }
00853
00854
00855 if ((year >= 0) && (year < 50))
00856 year += 2000;
00857
00858 if ((year >= 50) && (year < 100))
00859 year += 1900;
00860
00861 if ((year < 1900) || (year > 2500))
00862 return invalidDate;
00863
00864 if (!have_time && !have_tz) {
00865
00866 struct tm t;
00867 memset(&t, 0, sizeof(tm));
00868 t.tm_mday = day;
00869 t.tm_mon = month;
00870 t.tm_year = year - 1900;
00871 t.tm_isdst = -1;
00872 return mktime(&t);
00873 }
00874
00875 if(!have_tz)
00876 offset = local_timeoffset();
00877 else
00878 offset *= 60;
00879
00880 result = ymdhms_to_seconds(year, month+1, day, hour, minute, second);
00881
00882
00883 if ((offset > 0) && (offset > result))
00884 offset = 0;
00885
00886 result -= offset;
00887
00888
00889
00890
00891 if (result < 1) result = 1;
00892
00893 return result;
00894 }
00895
00896
00897 Value KJS::timeClip(const Value &t)
00898 {
00899
00900 return t;
00901 }
00902