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(__linux__) || defined(__APPLE__)
00320 result = Number(-(t->tm_gmtoff / 60) );
00321 #else
00322 # if defined(__BORLANDC__)
00323
00324 #error please add daylight savings offset here!
00325 result = Number(_timezone / 60 - (t->tm_isdst > 0 ? 60 : 0));
00326 # else
00327 result = Number((timezone / 60 - (t->tm_isdst > 0 ? 60 : 0 )));
00328 # endif
00329 #endif
00330 break;
00331 case SetTime:
00332 milli = roundValue(exec,args[0]);
00333 result = Number(milli);
00334 thisObj.setInternalValue(result);
00335 break;
00336 case SetMilliSeconds:
00337 ms = args[0].toInt32(exec);
00338 break;
00339 case SetSeconds:
00340 t->tm_sec = args[0].toInt32(exec);
00341 if (args.size() >= 2)
00342 ms = args[1].toInt32(exec);
00343 break;
00344 case SetMinutes:
00345 t->tm_min = args[0].toInt32(exec);
00346 if (args.size() >= 2)
00347 t->tm_sec = args[1].toInt32(exec);
00348 if (args.size() >= 3)
00349 ms = args[2].toInt32(exec);
00350 break;
00351 case SetHours:
00352 t->tm_hour = args[0].toInt32(exec);
00353 if (args.size() >= 2)
00354 t->tm_min = args[1].toInt32(exec);
00355 if (args.size() >= 3)
00356 t->tm_sec = args[2].toInt32(exec);
00357 if (args.size() >= 4)
00358 ms = args[3].toInt32(exec);
00359 break;
00360 case SetDate:
00361 t->tm_mday = args[0].toInt32(exec);
00362 break;
00363 case SetMonth:
00364 t->tm_mon = args[0].toInt32(exec);
00365 if (args.size() >= 2)
00366 t->tm_mday = args[1].toInt32(exec);
00367 break;
00368 case SetFullYear:
00369 t->tm_year = args[0].toInt32(exec) - 1900;
00370 if (args.size() >= 2)
00371 t->tm_mon = args[1].toInt32(exec);
00372 if (args.size() >= 3)
00373 t->tm_mday = args[2].toInt32(exec);
00374 break;
00375 case SetYear:
00376 t->tm_year = args[0].toInt32(exec) >= 1900 ? args[0].toInt32(exec) - 1900 : args[0].toInt32(exec);
00377 break;
00378 }
00379
00380 if (id == SetYear || id == SetMilliSeconds || id == SetSeconds ||
00381 id == SetMinutes || id == SetHours || id == SetDate ||
00382 id == SetMonth || id == SetFullYear ) {
00383 result = makeTime(t, ms, utc);
00384 thisObj.setInternalValue(result);
00385 }
00386
00387 return result;
00388 }
00389
00390
00391
00392
00393
00394 DateObjectImp::DateObjectImp(ExecState *exec,
00395 FunctionPrototypeImp *funcProto,
00396 DatePrototypeImp *dateProto)
00397 : InternalFunctionImp(funcProto)
00398 {
00399 Value protect(this);
00400
00401
00402 putDirect(prototypePropertyName, dateProto, DontEnum|DontDelete|ReadOnly);
00403
00404 static const Identifier parsePropertyName("parse");
00405 putDirect(parsePropertyName, new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::Parse, 1), DontEnum);
00406 static const Identifier UTCPropertyName("UTC");
00407 putDirect(UTCPropertyName, new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::UTC, 7), DontEnum);
00408
00409
00410 putDirect(lengthPropertyName, 7, ReadOnly|DontDelete|DontEnum);
00411 }
00412
00413 bool DateObjectImp::implementsConstruct() const
00414 {
00415 return true;
00416 }
00417
00418
00419 Object DateObjectImp::construct(ExecState *exec, const List &args)
00420 {
00421 int numArgs = args.size();
00422
00423 #ifdef KJS_VERBOSE
00424 fprintf(stderr,"DateObjectImp::construct - %d args\n", numArgs);
00425 #endif
00426 Value value;
00427
00428 if (numArgs == 0) {
00429 #if HAVE_SYS_TIMEB_H
00430 # if defined(__BORLANDC__)
00431 struct timeb timebuffer;
00432 ftime(&timebuffer);
00433 # else
00434 struct _timeb timebuffer;
00435 _ftime(&timebuffer);
00436 # endif
00437 double utc = floor((double)timebuffer.time * 1000.0 + (double)timebuffer.millitm);
00438 #else
00439 struct timeval tv;
00440 gettimeofday(&tv, 0L);
00441 double utc = floor((double)tv.tv_sec * 1000.0 + (double)tv.tv_usec / 1000.0);
00442 #endif
00443 value = Number(utc);
00444 } else if (numArgs == 1) {
00445 UString s = args[0].toString(exec);
00446 double d = s.toDouble();
00447 if (isNaN(d))
00448 value = parseDate(s);
00449 else
00450 value = Number(d);
00451 } else {
00452 struct tm t;
00453 memset(&t, 0, sizeof(t));
00454 int year = args[0].toInt32(exec);
00455
00456 t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
00457 t.tm_mon = args[1].toInt32(exec);
00458 t.tm_mday = (numArgs >= 3) ? args[2].toInt32(exec) : 1;
00459 t.tm_hour = (numArgs >= 4) ? args[3].toInt32(exec) : 0;
00460 t.tm_min = (numArgs >= 5) ? args[4].toInt32(exec) : 0;
00461 t.tm_sec = (numArgs >= 6) ? args[5].toInt32(exec) : 0;
00462 t.tm_isdst = -1;
00463 int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0;
00464 value = makeTime(&t, ms, false);
00465 }
00466
00467 Object proto = exec->interpreter()->builtinDatePrototype();
00468 Object ret(new DateInstanceImp(proto.imp()));
00469 ret.setInternalValue(timeClip(value));
00470 return ret;
00471 }
00472
00473 bool DateObjectImp::implementsCall() const
00474 {
00475 return true;
00476 }
00477
00478
00479 Value DateObjectImp::call(ExecState* , Object &, const List &)
00480 {
00481 #ifdef KJS_VERBOSE
00482 fprintf(stderr,"DateObjectImp::call - current time\n");
00483 #endif
00484 time_t t = time(0L);
00485 UString s(ctime(&t));
00486
00487
00488 return String(s.substr(0, s.size() - 1));
00489 }
00490
00491
00492
00493 DateObjectFuncImp::DateObjectFuncImp(ExecState* , FunctionPrototypeImp *funcProto,
00494 int i, int len)
00495 : InternalFunctionImp(funcProto), id(i)
00496 {
00497 Value protect(this);
00498 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
00499 }
00500
00501 bool DateObjectFuncImp::implementsCall() const
00502 {
00503 return true;
00504 }
00505
00506
00507 Value DateObjectFuncImp::call(ExecState *exec, Object &, const List &args)
00508 {
00509 if (id == Parse) {
00510 return parseDate(args[0].toString(exec));
00511 } else {
00512 struct tm t;
00513 memset(&t, 0, sizeof(t));
00514 int n = args.size();
00515 int year = args[0].toInt32(exec);
00516
00517 t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
00518 t.tm_mon = args[1].toInt32(exec);
00519 t.tm_mday = (n >= 3) ? args[2].toInt32(exec) : 1;
00520 t.tm_hour = (n >= 4) ? args[3].toInt32(exec) : 0;
00521 t.tm_min = (n >= 5) ? args[4].toInt32(exec) : 0;
00522 t.tm_sec = (n >= 6) ? args[5].toInt32(exec) : 0;
00523 int ms = (n >= 7) ? args[6].toInt32(exec) : 0;
00524 return makeTime(&t, ms, true);
00525 }
00526 }
00527
00528
00529
00530
00531 Value KJS::parseDate(const UString &u)
00532 {
00533 #ifdef KJS_VERBOSE
00534 fprintf(stderr,"KJS::parseDate %s\n",u.ascii());
00535 #endif
00536 double seconds = KRFCDate_parseDate( u );
00537 #ifdef KJS_VERBOSE
00538 fprintf(stderr,"KRFCDate_parseDate returned seconds=%g\n",seconds);
00539 bool withinLimits = true;
00540 if ( sizeof(time_t) == 4 )
00541 {
00542 int limit = ((time_t)-1 < 0) ? 2038 : 2115;
00543 if ( seconds > (limit-1970) * 365.25 * 86400 ) {
00544 fprintf(stderr, "date above time_t limit. Year seems to be %d\n", (int)(seconds/(365.25*86400)+1970));
00545 withinLimits = false;
00546 }
00547 }
00548 if ( withinLimits ) {
00549 time_t lsec = (time_t)seconds;
00550 fprintf(stderr, "this is: %s\n", ctime(&lsec));
00551 }
00552 #endif
00553
00554 return Number(seconds == -1 ? NaN : seconds * 1000.0);
00555 }
00556
00558
00559 static double ymdhms_to_seconds(int year, int mon, int day, int hour, int minute, int second)
00560 {
00561
00562
00563 double ret = (day - 32075)
00564 + 1461L * (year + 4800L + (mon - 14) / 12) / 4
00565 + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12
00566 - 3 * ((year + 4900L + (mon - 14) / 12) / 100) / 4
00567 - 2440588;
00568 ret = 24*ret + hour;
00569 ret = 60*ret + minute;
00570 ret = 60*ret + second;
00571
00572 return ret;
00573 }
00574
00575 static const char haystack[37]="janfebmaraprmayjunjulaugsepoctnovdec";
00576
00577
00578
00579 static const struct {
00580 const char tzName[4];
00581 int tzOffset;
00582 } known_zones[] = {
00583 { "UT", 0 },
00584 { "GMT", 0 },
00585 { "EST", -300 },
00586 { "EDT", -240 },
00587 { "CST", -360 },
00588 { "CDT", -300 },
00589 { "MST", -420 },
00590 { "MDT", -360 },
00591 { "PST", -480 },
00592 { "PDT", -420 },
00593 { { 0, 0, 0, 0 }, 0 }
00594 };
00595
00596 Number KJS::makeTime(struct tm *t, int ms, bool utc)
00597 {
00598 int utcOffset;
00599 if (utc) {
00600 time_t zero = 0;
00601 struct tm t3;
00602 localtime_r(&zero, &t3);
00603 #if defined BSD || defined(__linux__) || defined(__APPLE__)
00604 utcOffset = t3.tm_gmtoff;
00605 t->tm_isdst = t3.tm_isdst;
00606 #else
00607 # if defined(__BORLANDC__)
00608 utcOffset = - _timezone;
00609 # else
00610 utcOffset = - timezone;
00611 # endif
00612 t->tm_isdst = 0;
00613 #endif
00614 } else {
00615 utcOffset = 0;
00616 t->tm_isdst = -1;
00617 }
00618
00619 return Number( ( mktime(t) + utcOffset ) * 1000.0 + ms );
00620 }
00621
00622 double KJS::KRFCDate_parseDate(const UString &_date)
00623 {
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 double result = -1;
00639 int offset = 0;
00640 bool have_tz = false;
00641 char *newPosStr;
00642 const char *dateString = _date.ascii();
00643 int day = 0;
00644 char monthStr[4];
00645 int month = -1;
00646 int year = 0;
00647 int hour = 0;
00648 int minute = 0;
00649 int second = 0;
00650 bool have_time = false;
00651
00652
00653 while(*dateString && isspace(*dateString))
00654 dateString++;
00655
00656 const char *wordStart = dateString;
00657
00658 while(*dateString && !isdigit(*dateString))
00659 {
00660 if ( isspace(*dateString) && dateString - wordStart >= 3 )
00661 {
00662 monthStr[0] = tolower(*wordStart++);
00663 monthStr[1] = tolower(*wordStart++);
00664 monthStr[2] = tolower(*wordStart++);
00665 monthStr[3] = '\0';
00666
00667 const char *str = strstr(haystack, monthStr);
00668 if (str) {
00669 int position = str - haystack;
00670 if (position % 3 == 0) {
00671 month = position / 3;
00672 }
00673 }
00674 while(*dateString && isspace(*dateString))
00675 dateString++;
00676 wordStart = dateString;
00677 }
00678 else
00679 dateString++;
00680 }
00681
00682 while(*dateString && isspace(*dateString))
00683 dateString++;
00684
00685 if (!*dateString)
00686 return invalidDate;
00687
00688
00689 day = strtol(dateString, &newPosStr, 10);
00690 dateString = newPosStr;
00691
00692 if (!*dateString)
00693 return invalidDate;
00694
00695 if (day < 1)
00696 return invalidDate;
00697 if (day > 31) {
00698
00699 if (*dateString == '/' && day >= 1000) {
00700
00701 if (!*++dateString)
00702 return invalidDate;
00703 year = day;
00704 month = strtol(dateString, &newPosStr, 10) - 1;
00705 dateString = newPosStr;
00706 if (*dateString++ != '/' || !*dateString)
00707 return invalidDate;
00708 day = strtol(dateString, &newPosStr, 10);
00709 dateString = newPosStr;
00710 } else {
00711 return invalidDate;
00712 }
00713 } else if (*dateString == '/' && day <= 12 && month == -1)
00714 {
00715 dateString++;
00716
00717 month = day - 1;
00718 day = strtol(dateString, &newPosStr, 10);
00719 dateString = newPosStr;
00720 if (*dateString == '/')
00721 dateString++;
00722 if (!*dateString)
00723 return invalidDate;
00724
00725 }
00726 else
00727 {
00728 if (*dateString == '-')
00729 dateString++;
00730
00731 while(*dateString && isspace(*dateString))
00732 dateString++;
00733
00734 if (*dateString == ',')
00735 dateString++;
00736
00737 if ( month == -1 )
00738 {
00739 for(int i=0; i < 3;i++)
00740 {
00741 if (!*dateString || (*dateString == '-') || isspace(*dateString))
00742 return invalidDate;
00743 monthStr[i] = tolower(*dateString++);
00744 }
00745 monthStr[3] = '\0';
00746
00747 newPosStr = (char*)strstr(haystack, monthStr);
00748
00749 if (!newPosStr || (newPosStr - haystack) % 3 != 0)
00750 return invalidDate;
00751
00752 month = (newPosStr-haystack)/3;
00753
00754 if ((month < 0) || (month > 11))
00755 return invalidDate;
00756
00757 while(*dateString && (*dateString != '-') && !isspace(*dateString))
00758 dateString++;
00759
00760 if (!*dateString)
00761 return invalidDate;
00762
00763
00764 if ((*dateString != '-') && (*dateString != '/') && !isspace(*dateString))
00765 return invalidDate;
00766 dateString++;
00767 }
00768
00769 if ((month < 0) || (month > 11))
00770 return invalidDate;
00771 }
00772
00773
00774 if (year <= 0 && *dateString)
00775 year = strtol(dateString, &newPosStr, 10);
00776
00777
00778 if (*newPosStr)
00779 {
00780
00781 if (!isspace(*newPosStr)) {
00782 if ( *newPosStr == ':' )
00783 year = -1;
00784 else
00785 return invalidDate;
00786 } else
00787 dateString = ++newPosStr;
00788
00789 have_time = true;
00790 hour = strtol(dateString, &newPosStr, 10);
00791 dateString = newPosStr;
00792
00793 if ((hour < 0) || (hour > 23))
00794 return invalidDate;
00795
00796 if (!*dateString)
00797 return invalidDate;
00798
00799
00800 if (*dateString++ != ':')
00801 return invalidDate;
00802
00803 minute = strtol(dateString, &newPosStr, 10);
00804 dateString = newPosStr;
00805
00806 if ((minute < 0) || (minute > 59))
00807 return invalidDate;
00808
00809
00810 if (*dateString && *dateString != ':' && !isspace(*dateString))
00811 return invalidDate;
00812
00813
00814 if (*dateString ==':') {
00815 dateString++;
00816
00817 second = strtol(dateString, &newPosStr, 10);
00818 dateString = newPosStr;
00819
00820 if ((second < 0) || (second > 59))
00821 return invalidDate;
00822 }
00823
00824 while(*dateString && isspace(*dateString))
00825 dateString++;
00826 }
00827 else
00828 dateString = newPosStr;
00829
00830
00831
00832
00833 if (*dateString) {
00834
00835 if ( (dateString[0] == 'G' && dateString[1] == 'M' && dateString[2] == 'T')
00836 || (dateString[0] == 'U' && dateString[1] == 'T' && dateString[2] == 'C') )
00837 {
00838 dateString += 3;
00839 have_tz = true;
00840 }
00841
00842 while (*dateString && isspace(*dateString))
00843 ++dateString;
00844
00845 if (strncasecmp(dateString, "GMT", 3) == 0) {
00846 dateString += 3;
00847 }
00848 if ((*dateString == '+') || (*dateString == '-')) {
00849 offset = strtol(dateString, &newPosStr, 10);
00850 dateString = newPosStr;
00851
00852 if ((offset < -9959) || (offset > 9959))
00853 return invalidDate;
00854
00855 int sgn = (offset < 0)? -1:1;
00856 offset = abs(offset);
00857 if ( *dateString == ':' ) {
00858 int offset2 = strtol(dateString, &newPosStr, 10);
00859 dateString = newPosStr;
00860 offset = (offset*60 + offset2)*sgn;
00861 }
00862 else
00863 offset = ((offset / 100)*60 + (offset % 100))*sgn;
00864 have_tz = true;
00865 } else {
00866 for (int i=0; known_zones[i].tzName != 0; i++) {
00867 if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
00868 offset = known_zones[i].tzOffset;
00869 have_tz = true;
00870 break;
00871 }
00872 }
00873 }
00874 }
00875
00876 while(*dateString && isspace(*dateString))
00877 dateString++;
00878
00879 if ( *dateString && year == -1 ) {
00880 year = strtol(dateString, &newPosStr, 10);
00881 }
00882
00883
00884 if ((year >= 0) && (year < 50))
00885 year += 2000;
00886
00887 if ((year >= 50) && (year < 100))
00888 year += 1900;
00889
00890 if ((year < 1900) || (year > 2500))
00891 return invalidDate;
00892
00893 if (!have_tz) {
00894
00895 struct tm t;
00896 memset(&t, 0, sizeof(tm));
00897 t.tm_mday = day;
00898 t.tm_mon = month;
00899 t.tm_year = year - 1900;
00900 t.tm_isdst = -1;
00901 if (have_time) {
00902 t.tm_sec = second;
00903 t.tm_min = minute;
00904 t.tm_hour = hour;
00905 }
00906
00907 return mktime(&t);
00908 }
00909
00910 offset *= 60;
00911
00912 result = ymdhms_to_seconds(year, month+1, day, hour, minute, second);
00913
00914
00915 if ((offset > 0) && (offset > result))
00916 offset = 0;
00917
00918 result -= offset;
00919
00920
00921
00922
00923 if (result < 1) result = 1;
00924
00925 return result;
00926 }
00927
00928
00929 Value KJS::timeClip(const Value &t)
00930 {
00931
00932 return t;
00933 }
00934