gwenhywfar 4.0.3
|
00001 /*************************************************************************** 00002 $RCSfile$ 00003 ------------------- 00004 cvs : $Id$ 00005 begin : Sun Nov 23 2003 00006 copyright : (C) 2003 by Martin Preuss 00007 email : martin@libchipcard.de 00008 00009 *************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU Lesser General Public * 00013 * License as published by the Free Software Foundation; either * 00014 * version 2.1 of the License, or (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00019 * Lesser General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 00024 * MA 02111-1307 USA * 00025 * * 00026 ***************************************************************************/ 00027 00028 00029 #ifdef HAVE_CONFIG_H 00030 # include <config.h> 00031 #endif 00032 00033 #define DISABLE_DEBUGLOG 00034 00035 00036 #include "gwentime_p.h" 00037 #include <gwenhywfar/gwentime.h> 00038 #include <gwenhywfar/debug.h> 00039 00040 #include <time.h> 00041 #include <ctype.h> 00042 #include <errno.h> 00043 #include <string.h> 00044 00045 00046 GWEN_LIST_FUNCTIONS(GWEN_TIME_TMPLCHAR, GWEN_TimeTmplChar) 00047 00048 00049 00050 GWEN_TIME *GWEN_CurrentTime(){ 00051 GWEN_TIME *t; 00052 00053 GWEN_NEW_OBJECT(GWEN_TIME, t); 00054 if (GWEN_Time__GetCurrentTime(t)) { 00055 DBG_ERROR(GWEN_LOGDOMAIN, "Could not get current time"); 00056 GWEN_Time_free(t); 00057 return 0; 00058 } 00059 return t; 00060 } 00061 00062 00063 00064 GWEN_TIME *GWEN_Time_fromSeconds(uint32_t secs) { 00065 GWEN_TIME *t; 00066 00067 GWEN_NEW_OBJECT(GWEN_TIME, t); 00068 t->secs=secs; 00069 return t; 00070 } 00071 00072 00073 00074 int GWEN_Time_AddSeconds(GWEN_TIME *ti, 00075 uint32_t secs) { 00076 uint32_t i; 00077 00078 assert(ti); 00079 i=ti->secs+secs; 00080 if (i<ti->secs) { 00081 DBG_INFO(GWEN_LOGDOMAIN, 00082 "Overflow when adding %u seconds", secs); 00083 return GWEN_ERROR_INVALID; 00084 } 00085 ti->secs=i; 00086 return 0; 00087 } 00088 00089 00090 00091 int GWEN_Time_SubSeconds(GWEN_TIME *ti, 00092 uint32_t secs) { 00093 assert(ti); 00094 00095 if (ti->secs<secs) { 00096 DBG_INFO(GWEN_LOGDOMAIN, 00097 "Underflow when subtracting %u seconds", 00098 secs); 00099 return GWEN_ERROR_INVALID; 00100 } 00101 ti->secs-=secs; 00102 return 0; 00103 } 00104 00105 00106 void GWEN_Time__SetSecsAndMSecs(GWEN_TIME *ti, 00107 uint32_t secs, 00108 uint32_t msecs){ 00109 assert(ti); 00110 ti->secs=secs; 00111 ti->msecs=msecs; 00112 } 00113 00114 00115 00116 int GWEN_Time_toDb(const GWEN_TIME *t, GWEN_DB_NODE *db) { 00117 GWEN_DB_NODE *dbT; 00118 int i1, i2, i3; 00119 00120 assert(t); 00121 assert(db); 00122 dbT=GWEN_DB_GetGroup(db, GWEN_DB_FLAGS_DEFAULT, "date"); 00123 GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, 00124 "inUtc", 1); 00125 00126 assert(dbT); 00127 if (GWEN_Time_GetBrokenDownUtcDate(t, &i1, &i2, &i3)) { 00128 DBG_INFO(GWEN_LOGDOMAIN, "Could not break down date"); 00129 return -1; 00130 } 00131 GWEN_DB_SetIntValue(dbT, GWEN_DB_FLAGS_OVERWRITE_VARS, 00132 "day", i1); 00133 GWEN_DB_SetIntValue(dbT, GWEN_DB_FLAGS_OVERWRITE_VARS, 00134 "month", i2+1); 00135 GWEN_DB_SetIntValue(dbT, GWEN_DB_FLAGS_OVERWRITE_VARS, 00136 "year", i3); 00137 00138 dbT=GWEN_DB_GetGroup(db, GWEN_DB_FLAGS_DEFAULT, "time"); 00139 assert(dbT); 00140 if (GWEN_Time_GetBrokenDownUtcTime(t, &i1, &i2, &i3)) { 00141 DBG_INFO(GWEN_LOGDOMAIN, "Could not break down time"); 00142 return -1; 00143 } 00144 GWEN_DB_SetIntValue(dbT, GWEN_DB_FLAGS_OVERWRITE_VARS, 00145 "hour", i1); 00146 GWEN_DB_SetIntValue(dbT, GWEN_DB_FLAGS_OVERWRITE_VARS, 00147 "min", i2); 00148 GWEN_DB_SetIntValue(dbT, GWEN_DB_FLAGS_OVERWRITE_VARS, 00149 "sec", i3); 00150 00151 return 0; 00152 } 00153 00154 00155 00156 GWEN_TIME *GWEN_Time_fromDb(GWEN_DB_NODE *db) { 00157 GWEN_TIME *t; 00158 GWEN_DB_NODE *dbT; 00159 int day, month, year; 00160 int hour, min, sec; 00161 int inUtc; 00162 00163 day=month=year=0; 00164 hour=min=sec=0; 00165 00166 inUtc=GWEN_DB_GetIntValue(db, "inUtc", 0, 0); 00167 dbT=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "date"); 00168 if (dbT) { 00169 day=GWEN_DB_GetIntValue(dbT, "day", 0, 0); 00170 month=GWEN_DB_GetIntValue(dbT, "month", 0, 1)-1; 00171 year=GWEN_DB_GetIntValue(dbT, "year", 0, 0); 00172 if (!day || !year) { 00173 DBG_INFO(GWEN_LOGDOMAIN, "Bad date in DB"); 00174 return 0; 00175 } 00176 } 00177 00178 dbT=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "time"); 00179 if (dbT) { 00180 hour=GWEN_DB_GetIntValue(dbT, "hour", 0, 0); 00181 min=GWEN_DB_GetIntValue(dbT, "min", 0, 0); 00182 sec=GWEN_DB_GetIntValue(dbT, "sec", 0, 0); 00183 } 00184 00185 DBG_VERBOUS(GWEN_LOGDOMAIN, 00186 "Creating time from this: %04d/%02d/%02d - %02d:%02d:%02d (%d)", 00187 year, month, day, hour, min, sec, inUtc); 00188 t=GWEN_Time_new(year, month, day, hour, min, sec, inUtc); 00189 if (!t) { 00190 DBG_INFO(GWEN_LOGDOMAIN, "Bad date/time"); 00191 return 0; 00192 } 00193 00194 return t; 00195 } 00196 00197 00198 00199 GWEN_TIME *GWEN_Time__fromString(const char *s, const char *tmpl, int inUtc){ 00200 int year, month, day; 00201 int hour, min, sec; 00202 const char *p; 00203 const char *t; 00204 GWEN_TIME *gwt; 00205 00206 assert(s); 00207 assert(tmpl); 00208 year=month=day=0; 00209 hour=min=sec=0; 00210 00211 p=s; 00212 t=tmpl; 00213 while(*t && *p) { 00214 int i; 00215 00216 if (*t=='*') { 00217 t++; 00218 if (!*t) { 00219 DBG_ERROR(GWEN_LOGDOMAIN, "Bad pattern: Must not end with \"*\""); 00220 return 0; 00221 } 00222 i=0; 00223 while(*p) { 00224 if (!isdigit((int)*p)) 00225 break; 00226 if (*p==*t) 00227 break; 00228 i*=10; 00229 i+=(*p)-'0'; 00230 p++; 00231 } /* while */ 00232 } 00233 else { 00234 if (isdigit((int)*p)) 00235 i=(*p)-'0'; 00236 else 00237 i=-1; 00238 p++; 00239 } 00240 00241 if (i==-1 && strchr("YMDhms", *t)!=NULL) { 00242 DBG_INFO(GWEN_LOGDOMAIN, 00243 "No more digits at [%s], continueing", t); 00244 p--; 00245 } 00246 else { 00247 switch(*t) { 00248 case 'Y': 00249 if (i==-1) { 00250 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00251 return 0; 00252 } 00253 year*=10; 00254 year+=i; 00255 break; 00256 case 'M': 00257 if (i==-1) { 00258 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00259 return 0; 00260 } 00261 month*=10; 00262 month+=i; 00263 break; 00264 case 'D': 00265 if (i==-1) { 00266 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00267 return 0; 00268 } 00269 day*=10; 00270 day+=i; 00271 break; 00272 case 'h': 00273 if (i==-1) { 00274 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00275 return 0; 00276 } 00277 hour*=10; 00278 hour+=i; 00279 break; 00280 case 'm': 00281 if (i==-1) { 00282 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00283 return 0; 00284 } 00285 min*=10; 00286 min+=i; 00287 break; 00288 case 's': 00289 if (i==-1) { 00290 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00291 return 0; 00292 } 00293 sec*=10; 00294 sec+=i; 00295 break; 00296 default: 00297 DBG_VERBOUS(GWEN_LOGDOMAIN, 00298 "Unknown character in template, will skip in both strings"); 00299 break; 00300 } 00301 } 00302 t++; 00303 } /* while */ 00304 00305 if (year<100) 00306 year+=2000; 00307 00308 DBG_DEBUG(GWEN_LOGDOMAIN, 00309 "Got this date/time: %04d/%02d/%02d, %02d:%02d:%02d", 00310 year, month-1, day, hour, min, sec); 00311 00312 /* get time in local time */ 00313 gwt=GWEN_Time_new(year, month-1, day, hour, min, sec, inUtc); 00314 if (!gwt) { 00315 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00316 return 0; 00317 } 00318 return gwt; 00319 } 00320 00321 00322 00323 GWEN_TIME *GWEN_Time_fromString(const char *s, const char *tmpl){ 00324 return GWEN_Time__fromString(s, tmpl, 0); 00325 } 00326 00327 00328 00329 GWEN_TIME *GWEN_Time_fromUtcString(const char *s, const char *tmpl){ 00330 return GWEN_Time__fromString(s, tmpl, 1); 00331 } 00332 00333 00334 00335 GWEN_TIME *GWEN_Time_new(int year, 00336 int month, 00337 int day, 00338 int hour, 00339 int min, 00340 int sec, 00341 int inUtc){ 00342 uint32_t s; 00343 00344 if (inUtc) 00345 s=GWEN_Time__mktimeUtc(year, month, day, hour, min, sec); 00346 else { 00347 struct tm ti; 00348 struct tm *tp; 00349 time_t tt; 00350 00351 tt=time(0); 00352 tp=localtime(&tt); 00353 assert(tp); 00354 memmove(&ti, tp, sizeof(ti)); 00355 ti.tm_sec=sec; 00356 ti.tm_min=min; 00357 ti.tm_hour=hour; 00358 if (year<100) { 00359 if (year<72) 00360 year+=2000; 00361 year+=1900; 00362 } 00363 ti.tm_year=year-1900; 00364 ti.tm_mon=month; 00365 ti.tm_mday=day; 00366 ti.tm_yday=0; 00367 ti.tm_wday=0; 00368 tt=mktime(&ti); 00369 assert(tt!=(time_t)-1); 00370 s=(uint32_t)tt; 00371 } 00372 return GWEN_Time_fromSeconds(s); 00373 } 00374 00375 00376 00377 uint32_t GWEN_Time__mktimeUtc(int year, 00378 int month, 00379 int day, 00380 int hour, 00381 int min, 00382 int sec) { 00383 uint32_t result; 00384 int i; 00385 int isLeap; 00386 const uint32_t hoursecs=60*60; 00387 const uint32_t daysecs=24*hoursecs; 00388 const uint32_t yearsecs=365*daysecs; 00389 const uint32_t monthDays[12]= 00390 { 00391 31, 28, 31, 30, 00392 31, 30, 31, 31, 00393 30, 31, 30, 31 00394 }; 00395 00396 result=(year-1970)*yearsecs; 00397 00398 for (i=1970; i<year; i++) 00399 if ((((i % 4)==0) && 00400 ((i % 100)!=0)) || 00401 ((i % 400)==0)) 00402 result+=daysecs; 00403 00404 isLeap=((((year % 4)==0) && 00405 ((year % 100)!=0)) || 00406 ((year % 400)==0)); 00407 00408 for (i=0; i<month; i++) 00409 if (isLeap && i==1) 00410 result+=29*daysecs; 00411 else 00412 result+=monthDays[i]*daysecs; 00413 00414 result+=(day-1)*daysecs; 00415 result+=(hour*hoursecs); 00416 result+=min*60; 00417 result+=sec; 00418 00419 return result; 00420 } 00421 00422 00423 00424 GWEN_TIME *GWEN_Time_dup(const GWEN_TIME *t){ 00425 GWEN_TIME *newT; 00426 00427 assert(t); 00428 GWEN_NEW_OBJECT(GWEN_TIME, newT); 00429 newT->secs=t->secs; 00430 newT->msecs=t->msecs; 00431 return newT; 00432 } 00433 00434 00435 00436 void GWEN_Time_free(GWEN_TIME *t){ 00437 if (t) { 00438 GWEN_FREE_OBJECT(t); 00439 } 00440 } 00441 00442 00443 00444 double GWEN_Time_Diff(const GWEN_TIME *t1, const GWEN_TIME *t0){ 00445 double d; 00446 00447 assert(t1); 00448 assert(t0); 00449 00450 d=1000.0*((double)(t1->secs)-(double)(t0->secs)); 00451 d+=(double)((double)(t1->msecs)-(double)(t0->msecs)); 00452 00453 return d; 00454 } 00455 00456 00457 00458 double GWEN_Time_DiffSeconds(const GWEN_TIME *t1, const GWEN_TIME *t0){ 00459 double d; 00460 00461 assert(t1); 00462 assert(t0); 00463 00464 d=(double)(t1->secs)-(double)(t0->secs); 00465 d+=((double)((double)(t1->msecs)-(double)(t0->msecs)))/1000.0; 00466 00467 return d; 00468 } 00469 00470 00471 00472 int GWEN_Time_Compare(const GWEN_TIME *t1, const GWEN_TIME *t0){ 00473 if (t1 && t0) { 00474 if (t1->secs<t0->secs) 00475 return -1; 00476 else if (t1->secs>t0->secs) 00477 return 1; 00478 else { 00479 if (t1->msecs<t0->msecs) 00480 return -1; 00481 else if (t1->msecs>t0->msecs) 00482 return 1; 00483 else 00484 return 0; 00485 } 00486 } 00487 else if (t1) 00488 return 1; 00489 else if (t0) 00490 return -1; 00491 00492 return 0; 00493 } 00494 00495 00496 00497 double GWEN_Time_Milliseconds(const GWEN_TIME *t){ 00498 assert(t); 00499 return (double)((t->secs*1000)+(t->msecs)); 00500 } 00501 00502 00503 00504 uint32_t GWEN_Time_Seconds(const GWEN_TIME *t){ 00505 assert(t); 00506 return t->secs; 00507 } 00508 00509 00510 00511 int GWEN_Time_GetBrokenDownTime(const GWEN_TIME *t, 00512 int *hours, 00513 int *mins, 00514 int *secs){ 00515 struct tm *tb; 00516 time_t tt; 00517 00518 assert(t); 00519 tt=t->secs; 00520 tb=localtime(&tt); 00521 if (!tb) { 00522 DBG_ERROR(GWEN_LOGDOMAIN, "localtime(): %s", strerror(errno)); 00523 return -1; 00524 } 00525 *hours=tb->tm_hour; 00526 *mins=tb->tm_min; 00527 *secs=tb->tm_sec; 00528 return 0; 00529 } 00530 00531 00532 00533 int GWEN_Time_GetBrokenDownUtcTime(const GWEN_TIME *t, 00534 int *hours, 00535 int *mins, 00536 int *secs){ 00537 struct tm *tb; 00538 time_t tt; 00539 00540 assert(t); 00541 tt=t->secs; 00542 tb=gmtime(&tt); 00543 if (!tb) { 00544 DBG_ERROR(GWEN_LOGDOMAIN, "gmtime(): %s", strerror(errno)); 00545 return -1; 00546 } 00547 *hours=tb->tm_hour; 00548 *mins=tb->tm_min; 00549 *secs=tb->tm_sec; 00550 return 0; 00551 } 00552 00553 00554 00555 int GWEN_Time_GetBrokenDownDate(const GWEN_TIME *t, 00556 int *days, 00557 int *month, 00558 int *year){ 00559 struct tm *tb; 00560 time_t tt; 00561 00562 assert(t); 00563 tt=t->secs; 00564 tb=localtime(&tt); 00565 if (!tb) { 00566 DBG_ERROR(GWEN_LOGDOMAIN, "localtime(): %s", strerror(errno)); 00567 return -1; 00568 } 00569 *days=tb->tm_mday; 00570 *month=tb->tm_mon; 00571 *year=tb->tm_year+1900; 00572 return 0; 00573 } 00574 00575 00576 00577 int GWEN_Time_GetBrokenDownUtcDate(const GWEN_TIME *t, 00578 int *days, 00579 int *month, 00580 int *year){ 00581 struct tm *tb; 00582 time_t tt; 00583 00584 assert(t); 00585 tt=t->secs; 00586 tb=gmtime(&tt); 00587 if (!tb) { 00588 DBG_ERROR(GWEN_LOGDOMAIN, "gmtime(): %s", strerror(errno)); 00589 return -1; 00590 } 00591 *days=tb->tm_mday; 00592 *month=tb->tm_mon; 00593 *year=tb->tm_year+1900; 00594 return 0; 00595 } 00596 00597 00598 00599 /* TODO: compiler says "function returns an aggregate" */ 00600 struct tm GWEN_Time_toTm(const GWEN_TIME *t) { 00601 struct tm *tb; 00602 time_t tt; 00603 00604 assert(t); 00605 tt=t->secs; 00606 tb=localtime(&tt); 00607 return *tb; 00608 } 00609 00610 time_t GWEN_Time_toTime_t(const GWEN_TIME *t) { 00611 assert(t); 00612 return t->secs; 00613 } 00614 00615 00616 00617 00618 GWEN_TIME_TMPLCHAR *GWEN_TimeTmplChar_new(char c) { 00619 GWEN_TIME_TMPLCHAR *e; 00620 00621 GWEN_NEW_OBJECT(GWEN_TIME_TMPLCHAR, e); 00622 GWEN_LIST_INIT(GWEN_TIME_TMPLCHAR, e); 00623 e->character=c; 00624 return e; 00625 } 00626 00627 00628 00629 void GWEN_TimeTmplChar_free(GWEN_TIME_TMPLCHAR *e) { 00630 if (e) { 00631 free(e->content); 00632 GWEN_LIST_FINI(GWEN_TIME_TMPLCHAR, e); 00633 GWEN_FREE_OBJECT(e); 00634 } 00635 } 00636 00637 00638 GWEN_TIME_TMPLCHAR *GWEN_Time__findTmplChar(GWEN_TIME_TMPLCHAR_LIST *ll, 00639 char c) { 00640 GWEN_TIME_TMPLCHAR *e; 00641 00642 e=GWEN_TimeTmplChar_List_First(ll); 00643 while(e) { 00644 if (e->character==c) 00645 break; 00646 e=GWEN_TimeTmplChar_List_Next(e); 00647 } 00648 00649 return e; 00650 } 00651 00652 00653 00654 00655 void GWEN_Time__sampleTmplChars(GWEN_UNUSED const GWEN_TIME *t, const char *tmpl, 00656 GWEN_UNUSED GWEN_BUFFER *buf, 00657 GWEN_TIME_TMPLCHAR_LIST *ll) { 00658 const char *s; 00659 00660 s=tmpl; 00661 while(*s) { 00662 if (strchr("YMDhms", *s)) { 00663 GWEN_TIME_TMPLCHAR *e; 00664 00665 e=GWEN_Time__findTmplChar(ll, *s); 00666 if (!e) { 00667 /* new entry, create it */ 00668 e=GWEN_TimeTmplChar_new(*s); 00669 GWEN_TimeTmplChar_List_Add(e, ll); 00670 } 00671 assert(e); 00672 e->count++; 00673 } 00674 else { 00675 DBG_DEBUG(GWEN_LOGDOMAIN, "Unknown character in template (%02x)", 00676 *s); 00677 } 00678 s++; 00679 } 00680 } 00681 00682 00683 00684 void GWEN_Time__fillTmplChars(const GWEN_TIME *t, 00685 GWEN_TIME_TMPLCHAR_LIST *ll, 00686 int useUtc) { 00687 GWEN_TIME_TMPLCHAR *e; 00688 int year, month, day, hour, minute, second; 00689 00690 if (useUtc) { 00691 GWEN_Time_GetBrokenDownUtcDate(t, &day, &month, &year); 00692 GWEN_Time_GetBrokenDownUtcTime(t, &hour, &minute, &second); 00693 } 00694 else { 00695 GWEN_Time_GetBrokenDownDate(t, &day, &month, &year); 00696 GWEN_Time_GetBrokenDownTime(t, &hour, &minute, &second); 00697 } 00698 00699 e=GWEN_TimeTmplChar_List_First(ll); 00700 while(e) { 00701 int v; 00702 char buffer[32]; 00703 00704 switch(e->character) { 00705 case 'Y': v=year; break; 00706 case 'M': v=month+1; break; 00707 case 'D': v=day; break; 00708 case 'h': v=hour; break; 00709 case 'm': v=minute; break; 00710 case 's': v=second; break; 00711 default: v=-1; break; 00712 } 00713 if (v==-1) { 00714 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown character, should not happen here"); 00715 abort(); 00716 } 00717 buffer[0]=0; 00718 snprintf(buffer, sizeof(buffer)-1, "%0*d", GWEN_TIME_TMPL_MAX_COUNT, v); 00719 buffer[sizeof(buffer)-1]=0; 00720 e->content=strdup(buffer); 00721 e->nextChar=strlen(e->content)-(e->count); 00722 e=GWEN_TimeTmplChar_List_Next(e); 00723 } 00724 } 00725 00726 00727 00728 00729 int GWEN_Time__toString(const GWEN_TIME *t, const char *tmpl, 00730 GWEN_BUFFER *buf, int useUtc) { 00731 GWEN_TIME_TMPLCHAR_LIST *ll; 00732 const char *s; 00733 00734 ll=GWEN_TimeTmplChar_List_new(); 00735 GWEN_Time__sampleTmplChars(t, tmpl, buf, ll); 00736 GWEN_Time__fillTmplChars(t, ll, useUtc); 00737 00738 s=tmpl; 00739 while(*s) { 00740 if (strchr("YMDhms", *s)) { 00741 GWEN_TIME_TMPLCHAR *e; 00742 char c; 00743 00744 e=GWEN_Time__findTmplChar(ll, *s); 00745 assert(e); 00746 assert(e->content); 00747 c=e->content[e->nextChar++]; 00748 assert(c); 00749 GWEN_Buffer_AppendByte(buf, c); 00750 } 00751 else 00752 GWEN_Buffer_AppendByte(buf, *s); 00753 s++; 00754 } 00755 GWEN_TimeTmplChar_List_free(ll); 00756 return 0; 00757 } 00758 00759 00760 00761 int GWEN_Time_toString(const GWEN_TIME *t, const char *tmpl, 00762 GWEN_BUFFER *buf) { 00763 return GWEN_Time__toString(t, tmpl, buf, 0); 00764 } 00765 00766 00767 00768 int GWEN_Time_toUtcString(const GWEN_TIME *t, const char *tmpl, 00769 GWEN_BUFFER *buf) { 00770 return GWEN_Time__toString(t, tmpl, buf, 1); 00771 } 00772 00773 00774 00775 00776 00777 00778 00779 00780 00781