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