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