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 t->tm_isdst = -1;
00383 result = Number(mktime(t) * 1000.0 + ms);
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 = Number(mktime(&t) * 1000.0 + ms);
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 Number(mktime(&t) * 1000.0 + ms);
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
int KJS::local_timeoffset()
00597 {
00598
static int local_offset = -1;
00599
00600
if ( local_offset != -1 )
return local_offset;
00601
00602 time_t local = time(0);
00603
struct tm* tm_local = gmtime(&local);
00604 local_offset = local-mktime(tm_local);
00605
if(tm_local->tm_isdst)
00606 local_offset += 3600;
00607
00608
return local_offset;
00609 }
00610
00611
double KJS::KRFCDate_parseDate(
const UString &_date)
00612 {
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
double result = -1;
00628
int offset = 0;
00629
bool have_tz =
false;
00630
char *newPosStr;
00631
const char *dateString = _date.
ascii();
00632
int day = 0;
00633
char monthStr[4];
00634
int month = -1;
00635
int year = 0;
00636
int hour = 0;
00637
int minute = 0;
00638
int second = 0;
00639
bool have_time =
false;
00640
00641
00642
while(*dateString && isspace(*dateString))
00643 dateString++;
00644
00645
const char *wordStart = dateString;
00646
00647
while(*dateString && !isdigit(*dateString))
00648 {
00649
if ( isspace(*dateString) && dateString - wordStart >= 3 )
00650 {
00651 monthStr[0] = tolower(*wordStart++);
00652 monthStr[1] = tolower(*wordStart++);
00653 monthStr[2] = tolower(*wordStart++);
00654 monthStr[3] =
'\0';
00655
00656
const char *str = strstr(haystack, monthStr);
00657
if (str) {
00658
int position = str - haystack;
00659
if (position % 3 == 0) {
00660 month = position / 3;
00661 }
00662 }
00663
while(*dateString && isspace(*dateString))
00664 dateString++;
00665 wordStart = dateString;
00666 }
00667
else
00668 dateString++;
00669 }
00670
00671
while(*dateString && isspace(*dateString))
00672 dateString++;
00673
00674
if (!*dateString)
00675
return invalidDate;
00676
00677
00678 day = strtol(dateString, &newPosStr, 10);
00679 dateString = newPosStr;
00680
00681
if ((day < 1) || (day > 31))
00682
return invalidDate;
00683
if (!*dateString)
00684
return invalidDate;
00685
00686
if (*dateString ==
'/' && day <= 12 && month == -1)
00687 {
00688 dateString++;
00689
00690 month = day - 1;
00691 day = strtol(dateString, &newPosStr, 10);
00692 dateString = newPosStr;
00693
if (*dateString ==
'/')
00694 dateString++;
00695
if (!*dateString)
00696
return invalidDate;
00697
00698 }
00699
else
00700 {
00701
if (*dateString ==
'-')
00702 dateString++;
00703
00704
while(*dateString && isspace(*dateString))
00705 dateString++;
00706
00707
if (*dateString ==
',')
00708 dateString++;
00709
00710
if ( month == -1 )
00711 {
00712
for(
int i=0; i < 3;i++)
00713 {
00714
if (!*dateString || (*dateString ==
'-') || isspace(*dateString))
00715
return invalidDate;
00716 monthStr[i] = tolower(*dateString++);
00717 }
00718 monthStr[3] =
'\0';
00719
00720 newPosStr = (
char*)strstr(haystack, monthStr);
00721
00722
if (!newPosStr || (newPosStr - haystack) % 3 != 0)
00723
return invalidDate;
00724
00725 month = (newPosStr-haystack)/3;
00726
00727
if ((month < 0) || (month > 11))
00728
return invalidDate;
00729
00730
while(*dateString && (*dateString !=
'-') && !isspace(*dateString))
00731 dateString++;
00732
00733
if (!*dateString)
00734
return invalidDate;
00735
00736
00737
if ((*dateString !=
'-') && (*dateString !=
'/') && !isspace(*dateString))
00738
return invalidDate;
00739 dateString++;
00740 }
00741
00742
if ((month < 0) || (month > 11))
00743
return invalidDate;
00744 }
00745
00746
00747 year = strtol(dateString, &newPosStr, 10);
00748
00749
00750
if (*newPosStr)
00751 {
00752
00753
if (!isspace(*newPosStr)) {
00754
if ( *newPosStr ==
':' )
00755 year = -1;
00756
else
00757
return invalidDate;
00758 }
else
00759 dateString = ++newPosStr;
00760
00761 have_time =
true;
00762 hour = strtol(dateString, &newPosStr, 10);
00763 dateString = newPosStr;
00764
00765
if ((hour < 0) || (hour > 23))
00766
return invalidDate;
00767
00768
if (!*dateString)
00769
return invalidDate;
00770
00771
00772
if (*dateString++ !=
':')
00773
return invalidDate;
00774
00775 minute = strtol(dateString, &newPosStr, 10);
00776 dateString = newPosStr;
00777
00778
if ((minute < 0) || (minute > 59))
00779
return invalidDate;
00780
00781
00782
if (*dateString && *dateString !=
':' && !isspace(*dateString))
00783
return invalidDate;
00784
00785
00786
if (*dateString ==
':') {
00787 dateString++;
00788
00789 second = strtol(dateString, &newPosStr, 10);
00790 dateString = newPosStr;
00791
00792
if ((second < 0) || (second > 59))
00793
return invalidDate;
00794 }
00795
00796
while(*dateString && isspace(*dateString))
00797 dateString++;
00798 }
00799
else
00800 dateString = newPosStr;
00801
00802
00803
00804
00805
if (*dateString) {
00806
00807
if ( (dateString[0] ==
'G' && dateString[1] ==
'M' && dateString[2] ==
'T')
00808 || (dateString[0] ==
'U' && dateString[1] ==
'T' && dateString[2] ==
'C') )
00809 {
00810 dateString += 3;
00811 have_tz =
true;
00812 }
00813
00814
while (*dateString && isspace(*dateString))
00815 ++dateString;
00816
00817
if (strncasecmp(dateString,
"GMT", 3) == 0) {
00818 dateString += 3;
00819 }
00820
if ((*dateString ==
'+') || (*dateString ==
'-')) {
00821 offset = strtol(dateString, &newPosStr, 10);
00822 dateString = newPosStr;
00823
00824
if ((offset < -9959) || (offset > 9959))
00825
return invalidDate;
00826
00827
int sgn = (offset < 0)? -1:1;
00828 offset = abs(offset);
00829
if ( *dateString ==
':' ) {
00830
int offset2 = strtol(dateString, &newPosStr, 10);
00831 dateString = newPosStr;
00832 offset = (offset*60 + offset2)*sgn;
00833 }
00834
else
00835 offset = ((offset / 100)*60 + (offset % 100))*sgn;
00836 have_tz =
true;
00837 }
else {
00838
for (
int i=0; known_zones[i].tzName != 0; i++) {
00839
if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
00840 offset = known_zones[i].tzOffset;
00841 have_tz =
true;
00842
break;
00843 }
00844 }
00845 }
00846 }
00847
00848
while(*dateString && isspace(*dateString))
00849 dateString++;
00850
00851
if ( *dateString && year == -1 ) {
00852 year = strtol(dateString, &newPosStr, 10);
00853 }
00854
00855
00856
if ((year >= 0) && (year < 50))
00857 year += 2000;
00858
00859
if ((year >= 50) && (year < 100))
00860 year += 1900;
00861
00862
if ((year < 1900) || (year > 2500))
00863
return invalidDate;
00864
00865
if (!have_time && !have_tz) {
00866
00867
struct tm t;
00868 memset(&t, 0,
sizeof(tm));
00869 t.tm_mday = day;
00870 t.tm_mon = month;
00871 t.tm_year = year - 1900;
00872 t.tm_isdst = -1;
00873
return mktime(&t);
00874 }
00875
00876
if(!have_tz)
00877 offset = local_timeoffset();
00878
else
00879 offset *= 60;
00880
00881 result = ymdhms_to_seconds(year, month+1, day, hour, minute, second);
00882
00883
00884
if ((offset > 0) && (offset > result))
00885 offset = 0;
00886
00887 result -= offset;
00888
00889
00890
00891
00892
if (result < 1) result = 1;
00893
00894
return result;
00895 }
00896
00897
00898
Value KJS::timeClip(
const Value &t)
00899 {
00900
00901
return t;
00902 }
00903