00001
00002
00003 #include <time.h>
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include <string.h>
00007
00008 #include "../command.h"
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #define _DAY_SEC (24L * 60L * 60L)
00035 #define _YEAR_SEC (365L * _DAY_SEC)
00036 #define _FOUR_YEAR_SEC (1461L * _DAY_SEC)
00037 #define _BASE_DOW 4
00038 #define _BASE_YEAR 70L
00039 #define _MAX_YEAR 138L
00040 #define _LEAP_YEAR_ADJUST 17L
00041 static int _lpdays[] = { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
00042 static int _days[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 };
00043
00044
00045
00046 #define ChkAdd(dest, src1, src2) ( ((src1 >= 0L) && (src2 >= 0L) \
00047 && (dest < 0L)) || ((src1 < 0L) && (src2 < 0L) && (dest >= 0L)) )
00048
00049
00050
00051
00052 #define ChkMul(dest, src1, src2) ( src1 ? (dest/src1 != src2) : 0 )
00053
00054 static struct tm * mygmtime (time_t *timp, struct tm *ptb);
00055
00056 static long mygmktime(struct tm *tb){
00057 time_t tmptm1, tmptm2, tmptm3;
00058 struct tm *tbtemp,Qtbtemp;
00059
00060
00061
00062
00063 if( ((tmptm1 = tb->tm_year) < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR+ 1) )
00064 goto err_mktime;
00065
00066
00067
00068
00069
00070 if( (tb->tm_mon < 0) || (tb->tm_mon > 11) ) {
00071
00072
00073 tmptm1 += (tb->tm_mon / 12);
00074 if( (tb->tm_mon %= 12) < 0 ) {
00075 tb->tm_mon += 12;
00076 tmptm1--;
00077 }
00078
00079
00080
00081
00082 if( (tmptm1 < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR + 1) )
00083 goto err_mktime;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 tmptm2 = _days[tb->tm_mon];
00093 if( !(tmptm1 & 3) && (tb->tm_mon > 1) )
00094 tmptm2++;
00095
00096
00097
00098
00099
00100
00101
00102
00103 tmptm3 = (tmptm1 - _BASE_YEAR) * 365L + ((tmptm1 - 1L) >> 2)
00104 - _LEAP_YEAR_ADJUST;
00105
00106
00107 tmptm3 += tmptm2;
00108
00109
00110 tmptm1 = tmptm3 + (tmptm2 = (long)(tb->tm_mday));
00111 if( ChkAdd(tmptm1, tmptm3, tmptm2) ) goto err_mktime;
00112
00113
00114
00115
00116 tmptm2 = tmptm1 * 24L;
00117 if( ChkMul(tmptm2, tmptm1, 24L) )goto err_mktime;
00118
00119 tmptm1 = tmptm2 + (tmptm3 = (long)tb->tm_hour);
00120 if( ChkAdd(tmptm1, tmptm2, tmptm3) )goto err_mktime;
00121
00122
00123
00124
00125
00126 tmptm2 = tmptm1 * 60L;
00127 if( ChkMul(tmptm2, tmptm1, 60L) )goto err_mktime;
00128
00129 tmptm1 = tmptm2 + (tmptm3 = (long)tb->tm_min);
00130 if ( ChkAdd(tmptm1, tmptm2, tmptm3) )goto err_mktime;
00131
00132
00133
00134
00135
00136 tmptm2 = tmptm1 * 60L;
00137 if( ChkMul(tmptm2, tmptm1, 60L) )goto err_mktime;
00138
00139 tmptm1 = tmptm2 + (tmptm3 = (long)tb->tm_sec);
00140 if ( ChkAdd(tmptm1, tmptm2, tmptm3) )goto err_mktime;
00141
00142
00143 if( (tbtemp = mygmtime(&tmptm1,&Qtbtemp)) == NULL )goto err_mktime;
00144
00145 *tb = *tbtemp;
00146 return tmptm1;
00147
00148 err_mktime:
00149
00150 return -1L;
00151 }
00152
00153 static struct tm * mygmtime (time_t *timp, struct tm *ptb){
00154 long caltim = *timp;
00155 int islpyr = 0;
00156 int tmptim;
00157 int *mdays;
00158
00159 if( caltim < 0L )return NULL;
00160
00161
00162
00163
00164
00165
00166 tmptim = (int)(caltim / _FOUR_YEAR_SEC);
00167 caltim -= ((long)tmptim * _FOUR_YEAR_SEC);
00168
00169
00170
00171
00172 tmptim = (tmptim * 4) + 70;
00173
00174 if( caltim >= _YEAR_SEC ) {
00175 tmptim++;
00176 caltim -= _YEAR_SEC;
00177
00178 if( caltim >= _YEAR_SEC ) {
00179 tmptim++;
00180 caltim -= _YEAR_SEC;
00181
00182
00183
00184
00185
00186 if( caltim >= (_YEAR_SEC + _DAY_SEC) ){
00187 tmptim++;
00188 caltim -= (_YEAR_SEC + _DAY_SEC);
00189 }else {
00190
00191
00192
00193 islpyr++;
00194 }
00195 }
00196 }
00197
00198
00199
00200
00201
00202 ptb->tm_year = tmptim;
00203
00204
00205
00206
00207
00208 ptb->tm_yday = (int)(caltim / _DAY_SEC);
00209 caltim -= (long)(ptb->tm_yday) * _DAY_SEC;
00210
00211
00212
00213
00214 if( islpyr )mdays = _lpdays; else mdays = _days;
00215
00216 for ( tmptim = 1 ; mdays[tmptim] < ptb->tm_yday ; tmptim++ ) ;
00217
00218 ptb->tm_mon = --tmptim;
00219
00220 ptb->tm_mday = ptb->tm_yday - mdays[tmptim];
00221
00222
00223
00224
00225 ptb->tm_wday = ((int)(*timp / _DAY_SEC) + _BASE_DOW) % 7;
00226
00227
00228
00229
00230
00231 ptb->tm_hour = (int)(caltim / 3600);
00232 caltim -= (long)ptb->tm_hour * 3600L;
00233
00234 ptb->tm_min = (int)(caltim / 60);
00235 ptb->tm_sec = (int)(caltim - (ptb->tm_min) * 60);
00236
00237 ptb->tm_isdst = 0;
00238 return( (struct tm *)ptb );
00239 }
00240
00241 static long TimeDifference(void){
00242 time_t lTime;
00243 struct tm GmTime,*pGmTime;
00244
00245
00246
00247 lTime = (time_t)time(NULL);
00248 pGmTime = mygmtime(&lTime,&GmTime);
00249 pGmTime->tm_isdst = -1;
00250 return (long)(lTime - mktime(pGmTime));
00251 }
00252
00253 #define MONTH_NAME_LEN 9
00254 static char *MonthName[] = {
00255 "January", "February", "March", "April", "May", "June",
00256 "July", "August", "September", "October", "November", "December"
00257 };
00258 #define WEEK_DAY_NAME_LEN 9
00259 static char *WeekDayName[] ={
00260 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
00261 };
00262
00263
00301 COMMAND(FORMATDATE)
00302 #if NOTIMP_FORMATDATE
00303 NOTIMPLEMENTED;
00304 #else
00305
00306 VARIABLE vFormatString,vTimeValue;
00307 time_t lTimeValue;
00308 NODE nItem;
00309 char *pszFormatString;
00310 struct tm *pGmTime,GmTime;
00311 char *s,*r,
00312 szNumberBuffer[5];
00313 int hour,len;
00314
00315
00316 USE_CALLER_MORTALS;
00317
00318 nItem = PARAMETERLIST;
00319
00320 vFormatString = CONVERT2STRING(_EVALUATEEXPRESSION(CAR(nItem)));
00321 ASSERTOKE;
00322 if( vFormatString == NULL )ERROR(COMMAND_ERROR_INVALID_TIME_FORMAT);
00323
00324 CONVERT2ZCHAR(vFormatString,pszFormatString);
00325
00326 nItem = CDR(nItem);
00327 if( nItem ){
00328 vTimeValue = EVALUATEEXPRESSION(CAR(nItem));
00329 ASSERTOKE;
00330 }else vTimeValue = NULL;
00331
00332 if( vTimeValue )
00333 lTimeValue = LONGVALUE(CONVERT2LONG(vTimeValue));
00334 else
00335 lTimeValue = (long)time(NULL)+ TimeDifference();
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 pGmTime = mygmtime(&lTimeValue,&GmTime);
00363
00364 s = pszFormatString;
00365 while( *s ){
00366
00367 if( !memcmp(s,"WDN",3) ){
00368 len = strlen(r = WeekDayName[pGmTime->tm_wday]);
00369 memcpy(s,r,3);
00370 s+=3;
00371 continue;
00372 }
00373
00374 if( !memcmp(s,"WEEKDAY-NAME",12) ){
00375 len = strlen(r = WeekDayName[pGmTime->tm_wday]);
00376 memcpy(s,r,len);
00377 r = s + 12;
00378 s = s + len;
00379 len = s-r;
00380 for( ; r[len] = *r ; r++ );
00381 continue;
00382 }
00383
00384 if( !memcmp(s,"*MONTH-NAME*",12) ){
00385 len = strlen(r = MonthName[pGmTime->tm_mon]);
00386 memcpy(s,r,len);
00387 r = s + 12;
00388 s = s + len;
00389 len = s-r;
00390 for( ; r[len] = *r ; r++ );
00391 continue;
00392 }
00393
00394 if( !memcmp(s,"MON",3) ){
00395 len = strlen(r = MonthName[pGmTime->tm_mon]);
00396 memcpy(s,r,3);
00397 s += 3;
00398 continue;
00399 }
00400
00401 if( !memcmp(s,"YEAR",4) ){
00402 sprintf(szNumberBuffer,"%04d",pGmTime->tm_year+1900);
00403 memcpy(s,szNumberBuffer,4);
00404 s += 4;
00405 continue;
00406 }
00407
00408 if( !memcmp(s,"WD",2) ){
00409 *s = pGmTime->tm_wday + '0';
00410 s ++;
00411 for( r = s+1 ; r[-1] = *r ; r++ );
00412 continue;
00413 }
00414
00415 if( !memcmp(s,"YY",2) ){
00416 sprintf(szNumberBuffer,"%04d",pGmTime->tm_year+1900);
00417 memcpy(s,szNumberBuffer+2,2);
00418 s += 2;
00419 continue;
00420 }
00421
00422 if( !memcmp(s,"MM",2) ){
00423 if( pGmTime->tm_mon+1 < 10 ){
00424 *s = pGmTime->tm_mon+1 + '0';
00425 s ++;
00426 for( r = s+1 ; r[-1] = *r ; r++ );
00427 continue;
00428 }else{
00429 sprintf(szNumberBuffer,"%02d",pGmTime->tm_mon+1);
00430 memcpy(s,szNumberBuffer,2);
00431 s += 2;
00432 continue;
00433 }
00434 }
00435
00436 if( !memcmp(s,"0M",2) ){
00437 sprintf(szNumberBuffer,"%02d",pGmTime->tm_mon+1);
00438 memcpy(s,szNumberBuffer,2);
00439 s += 2;
00440 continue;
00441 }
00442
00443 if( !memcmp(s,"DD",2) ){
00444 if( pGmTime->tm_mday < 10 ){
00445 *s = pGmTime->tm_mday + '0';
00446 s ++;
00447 for( r = s+1 ; r[-1] = *r ; r++ );
00448 continue;
00449 }else{
00450 sprintf(szNumberBuffer,"%02d",pGmTime->tm_mday);
00451 memcpy(s,szNumberBuffer,2);
00452 s += 2;
00453 continue;
00454 }
00455 }
00456
00457 if( !memcmp(s,"0D",2) ){
00458 sprintf(szNumberBuffer,"%02d",pGmTime->tm_mday);
00459 memcpy(s,szNumberBuffer,2);
00460 s += 2;
00461 continue;
00462 }
00463
00464 if( !memcmp(s,"HH",2) ){
00465 if( pGmTime->tm_hour < 10 ){
00466 *s = pGmTime->tm_hour + '0';
00467 s ++;
00468 for( r = s+1 ; r[-1] = *r ; r++ );
00469 continue;
00470 }else{
00471 sprintf(szNumberBuffer,"%02d",pGmTime->tm_hour);
00472 memcpy(s,szNumberBuffer,2);
00473 s += 2;
00474 continue;
00475 }
00476 }
00477
00478 if( !memcmp(s,"0H",2) ){
00479 sprintf(szNumberBuffer,"%02d",pGmTime->tm_hour);
00480 memcpy(s,szNumberBuffer,2);
00481 s += 2;
00482 continue;
00483 }
00484
00485 if( !memcmp(s,"hh",2) ){
00486 hour = pGmTime->tm_hour;
00487 if( hour > 12 )hour -= 12;
00488 if( hour < 10 ){
00489 *s = hour + '0';
00490 s ++;
00491 for( r = s+1 ; r[-1] = *r ; r++ );
00492 continue;
00493 }else{
00494 sprintf(szNumberBuffer,"%02d",hour);
00495 memcpy(s,szNumberBuffer,2);
00496 s += 2;
00497 continue;
00498 }
00499 }
00500
00501 if( !memcmp(s,"0h",2) ){
00502 hour = pGmTime->tm_hour;
00503 if( hour > 12 )hour -= 12;
00504 sprintf(szNumberBuffer,"%02d",hour);
00505 memcpy(s,szNumberBuffer,2);
00506 s += 2;
00507 continue;
00508 }
00509
00510 if( !memcmp(s,"mm",2) ){
00511 if( pGmTime->tm_min < 10 ){
00512 *s = pGmTime->tm_min + '0';
00513 s ++;
00514 for( r = s+1 ; r[-1] = *r ; r++ );
00515 continue;
00516 }else{
00517 sprintf(szNumberBuffer,"%02d",pGmTime->tm_min);
00518 memcpy(s,szNumberBuffer,2);
00519 s += 2;
00520 continue;
00521 }
00522 }
00523
00524 if( !memcmp(s,"0m",2) ){
00525 sprintf(szNumberBuffer,"%02d",pGmTime->tm_min);
00526 memcpy(s,szNumberBuffer,2);
00527 s += 2;
00528 continue;
00529 }
00530
00531 if( !memcmp(s,"ss",2) ){
00532 if( pGmTime->tm_sec < 10 ){
00533 *s = pGmTime->tm_sec + '0';
00534 s ++;
00535 for( r = s+1 ; r[-1] = *r ; r++ );
00536 continue;
00537 }else{
00538 sprintf(szNumberBuffer,"%02d",pGmTime->tm_sec);
00539 memcpy(s,szNumberBuffer,2);
00540 s += 2;
00541 continue;
00542 }
00543 }
00544
00545 if( !memcmp(s,"0s",2) ){
00546 sprintf(szNumberBuffer,"%02d",pGmTime->tm_sec);
00547 memcpy(s,szNumberBuffer,2);
00548 s += 2;
00549 continue;
00550 }
00551
00552 if( (!memcmp(s,"am",2)) || (!memcmp(s,"pm",2)) ){
00553 if( pGmTime->tm_hour >= 12 )r = "pm"; else r = "am";
00554 memcpy(s,r,2);
00555 s += 2;
00556 continue;
00557 }
00558
00559 s++;
00560 }
00561 RESULT = NEWMORTALSTRING(strlen(pszFormatString));
00562 ASSERTNULL(RESULT)
00563 memcpy(STRINGVALUE(RESULT),pszFormatString,strlen(pszFormatString));
00564
00565 #endif
00566 END
00567
00574 COMMAND(NOW)
00575 #if NOTIMP_NOW
00576 NOTIMPLEMENTED;
00577 #else
00578
00579
00580 USE_CALLER_MORTALS;
00581 RESULT = NEWMORTALLONG;
00582 ASSERTNULL(RESULT)
00583 LONGVALUE(RESULT) = (long)time(NULL)+ TimeDifference();
00584 #endif
00585 END
00586
00593 COMMAND(GMTIME)
00594 #if NOTIMP_GMTIME
00595 NOTIMPLEMENTED;
00596 #else
00597
00598
00599 USE_CALLER_MORTALS;
00600 RESULT = NEWMORTALLONG;
00601 ASSERTNULL(RESULT)
00602 LONGVALUE(RESULT) = (long)time(NULL);
00603 #endif
00604 END
00605
00606 #define NOCOMMAND(XXX) \
00607 COMMAND(XXX)\
00608 NOTIMPLEMENTED;\
00609 END
00610
00611 #ifdef __sun
00612 #undef SEC
00613 #endif
00614
00615 #define TIMEFUN(NAME,FIELD) \
00616 COMMAND(NAME)\
00617 \
00618 VARIABLE vTime;\
00619 time_t lTime;\
00620 NODE nItem;\
00621 struct tm *pGmTime,GmTime;\
00622 \
00623 USE_CALLER_MORTALS;\
00624 nItem = PARAMETERLIST;\
00625 if( nItem ){\
00626 vTime = EVALUATEEXPRESSION(CAR(nItem));\
00627 ASSERTOKE;\
00628 }else\
00629 vTime = NULL;\
00630 \
00631 RESULT = NEWMORTALLONG;\
00632 ASSERTNULL(RESULT)\
00633 \
00634 if( memory_IsUndef(vTime) )\
00635 lTime = (long)time(NULL)+ TimeDifference();\
00636 else\
00637 lTime = LONGVALUE(CONVERT2LONG(vTime));\
00638 \
00639 pGmTime = mygmtime(&lTime,&GmTime);\
00640 LONGVALUE(RESULT) = pGmTime->FIELD;\
00641 END
00642
00649 #if NOTIMP_YEAR
00650 NOCOMMAND(YEAR)
00651 #else
00652 TIMEFUN(YEAR,tm_year+1900)
00653 #endif
00654
00661 #if NOTIMP_MONTH
00662 NOCOMMAND(MONTH)
00663 #else
00664 TIMEFUN(MONTH,tm_mon+1)
00665 #endif
00666
00673 #if NOTIMP_DAY
00674 NOCOMMAND(DAY)
00675 #else
00676 TIMEFUN(DAY,tm_mday)
00677 #endif
00678
00685 #if NOTIMP_WDAY
00686 NOCOMMAND(WDAY)
00687 #else
00688 TIMEFUN(WDAY,tm_wday)
00689 #endif
00690
00697 #if NOTIMP_YDAY
00698 NOCOMMAND(YDAY)
00699 #else
00700 TIMEFUN(YDAY,tm_yday)
00701 #endif
00702
00709 #if NOTIMP_HOUR
00710 NOCOMMAND(HOUR)
00711 #else
00712 TIMEFUN(HOUR,tm_hour)
00713 #endif
00714
00721 #if NOTIMP_MINUTE
00722 NOCOMMAND(MINUTE)
00723 #else
00724 TIMEFUN(MINUTE,tm_min)
00725 #endif
00726
00733 #if NOTIMP_SEC
00734 NOCOMMAND(SEC)
00735 #else
00736 TIMEFUN(SEC,tm_sec)
00737 #endif
00738
00739 #undef TIMEFUN
00740
00741
00757 COMMAND(TIMEVALUE)
00758 #if NOTIMP_TIMEVALUE
00759 NOTIMPLEMENTED;
00760 #else
00761
00762 VARIABLE vTime;
00763 long lTime;
00764 NODE nItem;
00765 struct tm GmTime;
00766
00767
00768 GmTime.tm_year = 1970;
00769 GmTime.tm_mon = 1;
00770 GmTime.tm_mday = 1;
00771 GmTime.tm_hour = 0;
00772 GmTime.tm_min = 0;
00773 GmTime.tm_sec = 0;
00774 GmTime.tm_isdst = -1;
00775
00776 USE_CALLER_MORTALS;
00777 nItem = PARAMETERLIST;
00778 if( nItem == 0 )goto NoMoreTime;
00779
00780 #define TAKE_ARGUMENT(x) \
00781 vTime = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));\
00782 ASSERTOKE;\
00783 if( vTime )GmTime.x = LONGVALUE(vTime);\
00784 nItem = CDR(nItem);\
00785 if( nItem == 0 )goto NoMoreTime;\
00786
00787 TAKE_ARGUMENT(tm_year)
00788 TAKE_ARGUMENT(tm_mon)
00789 TAKE_ARGUMENT(tm_mday)
00790 TAKE_ARGUMENT(tm_hour)
00791 TAKE_ARGUMENT(tm_min)
00792 TAKE_ARGUMENT(tm_sec)
00793
00794 NoMoreTime:;
00795 GmTime.tm_year -= 1900;
00796 GmTime.tm_mon --;
00797 lTime = mygmktime(&GmTime);
00798 if( lTime == -1 )ERROR(COMMAND_ERROR_INVALID_TIME);
00799 RESULT = NEWMORTALLONG;
00800 ASSERTNULL(RESULT)
00801 LONGVALUE(RESULT) = lTime;
00802 #endif
00803 END
00804
00811 COMMAND(GM2LOCAL)
00812 #if NOTIMP_GM2LOCAL
00813 NOTIMPLEMENTED;
00814 #else
00815
00816 VARIABLE vTime;
00817 long lTime;
00818 NODE nItem;
00819
00820 USE_CALLER_MORTALS;
00821 nItem = PARAMETERLIST;
00822 if( nItem == 0 ){
00823 RESULT = NULL;
00824 RETURN;
00825 }
00826 vTime = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));
00827 ASSERTOKE;
00828 if( memory_IsUndef(vTime) ){
00829 RESULT = NULL;
00830 RETURN;
00831 }
00832 lTime = LONGVALUE(vTime);
00833 RESULT = NEWMORTALLONG;
00834 ASSERTNULL(RESULT)
00835 LONGVALUE(RESULT) = lTime + TimeDifference();
00836 #endif
00837 END
00838
00845 COMMAND(LOCAL2GM)
00846 #if NOTIMP_LOCAL2GM
00847 NOTIMPLEMENTED;
00848 #else
00849
00850 VARIABLE vTime;
00851 long lTime;
00852 NODE nItem;
00853
00854 USE_CALLER_MORTALS;
00855 nItem = PARAMETERLIST;
00856 if( nItem == 0 ){
00857 RESULT = NULL;
00858 RETURN;
00859 }
00860 vTime = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));
00861 ASSERTOKE;
00862 if( memory_IsUndef(vTime) ){
00863 RESULT = NULL;
00864 RETURN;
00865 }
00866 lTime = LONGVALUE(vTime);
00867 RESULT = NEWMORTALLONG;
00868 ASSERTNULL(RESULT)
00869 LONGVALUE(RESULT) = lTime - TimeDifference();
00870 #endif
00871 END
00872
00892 COMMAND(ADDYEAR)
00893 #if NOTIMP_ADDYEAR
00894 NOTIMPLEMENTED;
00895 #else
00896
00897 VARIABLE vTime,vOffset;
00898 time_t lTime;
00899 NODE nItem;
00900 struct tm *pGmTime,GmTime;
00901
00902 nItem = PARAMETERLIST;
00903 if( nItem == 0 ){
00904 RESULT = NULL;
00905 RETURN;
00906 }
00907 vTime = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));
00908 ASSERTOKE;
00909 nItem = CDR(nItem);
00910 vOffset = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));
00911 ASSERTOKE;
00912 if( memory_IsUndef(vTime) || memory_IsUndef(vOffset) ){
00913 RESULT = NULL;
00914 RETURN;
00915 }
00916 lTime = LONGVALUE(vTime);
00917 pGmTime = mygmtime(&lTime,&GmTime);
00918 pGmTime->tm_year += LONGVALUE(vOffset);
00919
00920
00921
00922 if( pGmTime->tm_mday > 28 && pGmTime->tm_mon == 1 && (pGmTime->tm_year%4) )
00923 pGmTime->tm_mday = 28;
00924 pGmTime->tm_isdst = -1;
00925 RESULT = NEWMORTALLONG;
00926 ASSERTNULL(RESULT)
00927 LONGVALUE(RESULT) = mygmktime(&GmTime);
00928 #endif
00929 END
00930
00949 COMMAND(ADDMONTH)
00950 #if NOTIMP_ADDMONTH
00951 NOTIMPLEMENTED;
00952 #else
00953
00954 VARIABLE vTime,vOffset;
00955 time_t lTime;
00956 NODE nItem;
00957 struct tm *pGmTime,GmTime;
00958
00959 nItem = PARAMETERLIST;
00960 if( nItem == 0 ){
00961 RESULT = NULL;
00962 RETURN;
00963 }
00964 vTime = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));
00965 ASSERTOKE;
00966 nItem = CDR(nItem);
00967 vOffset = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));
00968 ASSERTOKE;
00969 if( memory_IsUndef(vTime) || memory_IsUndef(vOffset) ){
00970 RESULT = NULL;
00971 RETURN;
00972 }
00973 lTime = LONGVALUE(vTime);
00974 pGmTime = mygmtime(&lTime,&GmTime);
00975 pGmTime->tm_mon += LONGVALUE(vOffset);
00976 if( pGmTime->tm_mday == 31 && (pGmTime->tm_mon == 3 ||
00977 pGmTime->tm_mon == 5 ||
00978 pGmTime->tm_mon == 7 ||
00979 pGmTime->tm_mon == 8 ||
00980 pGmTime->tm_mon == 10 ))
00981 pGmTime->tm_mday = 30;
00982 if( pGmTime->tm_mday > 29 && pGmTime->tm_mon == 1 )
00983 pGmTime->tm_mday = 29;
00984
00985
00986
00987 if( pGmTime->tm_mday > 28 && pGmTime->tm_mon == 1 && (pGmTime->tm_year%4) )
00988 pGmTime->tm_mday = 28;
00989
00990 pGmTime->tm_isdst = -1;
00991 RESULT = NEWMORTALLONG;
00992 ASSERTNULL(RESULT)
00993 LONGVALUE(RESULT) = mygmktime(&GmTime);
00994 #endif
00995 END
00996
00997
00998 #undef TIMEFUN
00999 #define TIMEFUN(XXX,YYY) \
01000 COMMAND(XXX)\
01001 VARIABLE vTime,vOffset;\
01002 long lTime;\
01003 NODE nItem;\
01004 \
01005 nItem = PARAMETERLIST;\
01006 if( nItem == 0 ){\
01007 RESULT = NULL;\
01008 RETURN;\
01009 }\
01010 vTime = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));\
01011 ASSERTOKE;\
01012 nItem = CDR(nItem);\
01013 vOffset = CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem)));\
01014 ASSERTOKE;\
01015 if( memory_IsUndef(vTime) || memory_IsUndef(vOffset) ){\
01016 RESULT = NULL;\
01017 RETURN;\
01018 }\
01019 lTime = LONGVALUE(vTime);\
01020 RESULT = NEWMORTALLONG;\
01021 ASSERTNULL(RESULT)\
01022 LONGVALUE(RESULT) = lTime + LONGVALUE(vOffset)*YYY;\
01023 END
01024
01033 #if NOTIMP_ADDWEEK
01034 NOCOMMAND(ADDWEEK)
01035 #else
01036 TIMEFUN(ADDWEEK,604800)
01037 #endif
01038
01047 #if NOTIMP_ADDDAY
01048 NOCOMMAND(ADDDAY)
01049 #else
01050 TIMEFUN(ADDDAY,86400)
01051 #endif
01052
01061 #if NOTIMP_ADDHOUR
01062 NOCOMMAND(ADDHOUR)
01063 #else
01064 TIMEFUN(ADDHOUR,3600)
01065 #endif
01066
01075 #if NOTIMP_ADDMINUTE
01076 NOCOMMAND(ADDMINUTE)
01077 #else
01078 TIMEFUN(ADDMINUTE,60)
01079 #endif
01080
01089 #if NOTIMP_ADDSECOND
01090 NOCOMMAND(ADDSECOND)
01091 #else
01092 TIMEFUN(ADDSECOND,1);
01093 #endif
01094
01095 #undef TIMEFUN