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