gwenhywfar
4.3.1
|
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(void){ 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 if (day==0) 00308 day=1; 00309 00310 DBG_DEBUG(GWEN_LOGDOMAIN, 00311 "Got this date/time: %04d/%02d/%02d, %02d:%02d:%02d", 00312 year, month-1, day, hour, min, sec); 00313 00314 /* get time in local time */ 00315 gwt=GWEN_Time_new(year, month-1, day, hour, min, sec, inUtc); 00316 if (!gwt) { 00317 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00318 return 0; 00319 } 00320 return gwt; 00321 } 00322 00323 00324 00325 GWEN_TIME *GWEN_Time_fromString(const char *s, const char *tmpl){ 00326 return GWEN_Time__fromString(s, tmpl, 0); 00327 } 00328 00329 00330 00331 GWEN_TIME *GWEN_Time_fromUtcString(const char *s, const char *tmpl){ 00332 return GWEN_Time__fromString(s, tmpl, 1); 00333 } 00334 00335 00336 00337 GWEN_TIME *GWEN_Time_new(int year, 00338 int month, 00339 int day, 00340 int hour, 00341 int min, 00342 int sec, 00343 int inUtc){ 00344 uint32_t s; 00345 00346 if (inUtc) 00347 s=GWEN_Time__mktimeUtc(year, month, day, hour, min, sec); 00348 else { 00349 struct tm ti; 00350 struct tm *tp; 00351 time_t tt; 00352 00353 tt=time(0); 00354 tp=localtime(&tt); 00355 assert(tp); 00356 memmove(&ti, tp, sizeof(ti)); 00357 ti.tm_sec=sec; 00358 ti.tm_min=min; 00359 ti.tm_hour=hour; 00360 if (year<100) { 00361 if (year<72) 00362 year+=2000; 00363 year+=1900; 00364 } 00365 ti.tm_year=year-1900; 00366 ti.tm_mon=month; 00367 ti.tm_mday=day; 00368 ti.tm_yday=0; 00369 ti.tm_wday=0; 00370 tt=mktime(&ti); 00371 assert(tt!=(time_t)-1); 00372 s=(uint32_t)tt; 00373 } 00374 return GWEN_Time_fromSeconds(s); 00375 } 00376 00377 00378 00379 uint32_t GWEN_Time__mktimeUtc(int year, 00380 int month, 00381 int day, 00382 int hour, 00383 int min, 00384 int sec) { 00385 uint32_t result; 00386 int i; 00387 int isLeap; 00388 const uint32_t hoursecs=60*60; 00389 const uint32_t daysecs=24*hoursecs; 00390 const uint32_t yearsecs=365*daysecs; 00391 const uint32_t monthDays[12]= 00392 { 00393 31, 28, 31, 30, 00394 31, 30, 31, 31, 00395 30, 31, 30, 31 00396 }; 00397 00398 result=(year-1970)*yearsecs; 00399 00400 for (i=1970; i<year; i++) 00401 if ((((i % 4)==0) && 00402 ((i % 100)!=0)) || 00403 ((i % 400)==0)) 00404 result+=daysecs; 00405 00406 isLeap=((((year % 4)==0) && 00407 ((year % 100)!=0)) || 00408 ((year % 400)==0)); 00409 00410 for (i=0; i<month; i++) 00411 if (isLeap && i==1) 00412 result+=29*daysecs; 00413 else 00414 result+=monthDays[i]*daysecs; 00415 00416 result+=(day-1)*daysecs; 00417 result+=(hour*hoursecs); 00418 result+=min*60; 00419 result+=sec; 00420 00421 return result; 00422 } 00423 00424 00425 00426 GWEN_TIME *GWEN_Time_dup(const GWEN_TIME *t){ 00427 GWEN_TIME *newT; 00428 00429 assert(t); 00430 GWEN_NEW_OBJECT(GWEN_TIME, newT); 00431 newT->secs=t->secs; 00432 newT->msecs=t->msecs; 00433 return newT; 00434 } 00435 00436 00437 00438 void GWEN_Time_free(GWEN_TIME *t){ 00439 if (t) { 00440 GWEN_FREE_OBJECT(t); 00441 } 00442 } 00443 00444 00445 00446 double GWEN_Time_Diff(const GWEN_TIME *t1, const GWEN_TIME *t0){ 00447 double d; 00448 00449 assert(t1); 00450 assert(t0); 00451 00452 d=1000.0*((double)(t1->secs)-(double)(t0->secs)); 00453 d+=(double)((double)(t1->msecs)-(double)(t0->msecs)); 00454 00455 return d; 00456 } 00457 00458 00459 00460 double GWEN_Time_DiffSeconds(const GWEN_TIME *t1, const GWEN_TIME *t0){ 00461 double d; 00462 00463 assert(t1); 00464 assert(t0); 00465 00466 d=(double)(t1->secs)-(double)(t0->secs); 00467 d+=((double)((double)(t1->msecs)-(double)(t0->msecs)))/1000.0; 00468 00469 return d; 00470 } 00471 00472 00473 00474 int GWEN_Time_Compare(const GWEN_TIME *t1, const GWEN_TIME *t0){ 00475 if (t1 && t0) { 00476 if (t1->secs<t0->secs) 00477 return -1; 00478 else if (t1->secs>t0->secs) 00479 return 1; 00480 else { 00481 if (t1->msecs<t0->msecs) 00482 return -1; 00483 else if (t1->msecs>t0->msecs) 00484 return 1; 00485 else 00486 return 0; 00487 } 00488 } 00489 else if (t1) 00490 return 1; 00491 else if (t0) 00492 return -1; 00493 00494 return 0; 00495 } 00496 00497 00498 00499 double GWEN_Time_Milliseconds(const GWEN_TIME *t){ 00500 assert(t); 00501 return (double)((t->secs*1000)+(t->msecs)); 00502 } 00503 00504 00505 00506 uint32_t GWEN_Time_Seconds(const GWEN_TIME *t){ 00507 assert(t); 00508 return t->secs; 00509 } 00510 00511 00512 00513 int GWEN_Time_GetBrokenDownTime(const GWEN_TIME *t, 00514 int *hours, 00515 int *mins, 00516 int *secs){ 00517 struct tm *tb; 00518 time_t tt; 00519 00520 assert(t); 00521 tt=t->secs; 00522 tb=localtime(&tt); 00523 if (!tb) { 00524 DBG_ERROR(GWEN_LOGDOMAIN, "localtime(): %s", strerror(errno)); 00525 return -1; 00526 } 00527 *hours=tb->tm_hour; 00528 *mins=tb->tm_min; 00529 *secs=tb->tm_sec; 00530 return 0; 00531 } 00532 00533 00534 00535 int GWEN_Time_GetBrokenDownUtcTime(const GWEN_TIME *t, 00536 int *hours, 00537 int *mins, 00538 int *secs){ 00539 struct tm *tb; 00540 time_t tt; 00541 00542 assert(t); 00543 tt=t->secs; 00544 tb=gmtime(&tt); 00545 if (!tb) { 00546 DBG_ERROR(GWEN_LOGDOMAIN, "gmtime(): %s", strerror(errno)); 00547 return -1; 00548 } 00549 *hours=tb->tm_hour; 00550 *mins=tb->tm_min; 00551 *secs=tb->tm_sec; 00552 return 0; 00553 } 00554 00555 00556 00557 int GWEN_Time_GetBrokenDownDate(const GWEN_TIME *t, 00558 int *days, 00559 int *month, 00560 int *year){ 00561 struct tm *tb; 00562 time_t tt; 00563 00564 assert(t); 00565 tt=t->secs; 00566 tb=localtime(&tt); 00567 if (!tb) { 00568 DBG_ERROR(GWEN_LOGDOMAIN, "localtime(): %s", strerror(errno)); 00569 return -1; 00570 } 00571 *days=tb->tm_mday; 00572 *month=tb->tm_mon; 00573 *year=tb->tm_year+1900; 00574 return 0; 00575 } 00576 00577 00578 00579 int GWEN_Time_GetBrokenDownUtcDate(const GWEN_TIME *t, 00580 int *days, 00581 int *month, 00582 int *year){ 00583 struct tm *tb; 00584 time_t tt; 00585 00586 assert(t); 00587 tt=t->secs; 00588 tb=gmtime(&tt); 00589 if (!tb) { 00590 DBG_ERROR(GWEN_LOGDOMAIN, "gmtime(): %s", strerror(errno)); 00591 return -1; 00592 } 00593 *days=tb->tm_mday; 00594 *month=tb->tm_mon; 00595 *year=tb->tm_year+1900; 00596 return 0; 00597 } 00598 00599 00600 00601 /* TODO: compiler says "function returns an aggregate" */ 00602 struct tm GWEN_Time_toTm(const GWEN_TIME *t) { 00603 struct tm *tb; 00604 time_t tt; 00605 00606 assert(t); 00607 tt=t->secs; 00608 tb=localtime(&tt); 00609 return *tb; 00610 } 00611 00612 time_t GWEN_Time_toTime_t(const GWEN_TIME *t) { 00613 assert(t); 00614 return t->secs; 00615 } 00616 00617 00618 00619 00620 GWEN_TIME_TMPLCHAR *GWEN_TimeTmplChar_new(char c) { 00621 GWEN_TIME_TMPLCHAR *e; 00622 00623 GWEN_NEW_OBJECT(GWEN_TIME_TMPLCHAR, e); 00624 GWEN_LIST_INIT(GWEN_TIME_TMPLCHAR, e); 00625 e->character=c; 00626 return e; 00627 } 00628 00629 00630 00631 void GWEN_TimeTmplChar_free(GWEN_TIME_TMPLCHAR *e) { 00632 if (e) { 00633 free(e->content); 00634 GWEN_LIST_FINI(GWEN_TIME_TMPLCHAR, e); 00635 GWEN_FREE_OBJECT(e); 00636 } 00637 } 00638 00639 00640 GWEN_TIME_TMPLCHAR *GWEN_Time__findTmplChar(GWEN_TIME_TMPLCHAR_LIST *ll, 00641 char c) { 00642 GWEN_TIME_TMPLCHAR *e; 00643 00644 e=GWEN_TimeTmplChar_List_First(ll); 00645 while(e) { 00646 if (e->character==c) 00647 break; 00648 e=GWEN_TimeTmplChar_List_Next(e); 00649 } 00650 00651 return e; 00652 } 00653 00654 00655 00656 00657 void GWEN_Time__sampleTmplChars(GWEN_UNUSED const GWEN_TIME *t, const char *tmpl, 00658 GWEN_UNUSED GWEN_BUFFER *buf, 00659 GWEN_TIME_TMPLCHAR_LIST *ll) { 00660 const char *s; 00661 00662 s=tmpl; 00663 while(*s) { 00664 if (strchr("YMDhms", *s)) { 00665 GWEN_TIME_TMPLCHAR *e; 00666 00667 e=GWEN_Time__findTmplChar(ll, *s); 00668 if (!e) { 00669 /* new entry, create it */ 00670 e=GWEN_TimeTmplChar_new(*s); 00671 GWEN_TimeTmplChar_List_Add(e, ll); 00672 } 00673 assert(e); 00674 e->count++; 00675 } 00676 else { 00677 DBG_DEBUG(GWEN_LOGDOMAIN, "Unknown character in template (%02x)", 00678 *s); 00679 } 00680 s++; 00681 } 00682 } 00683 00684 00685 00686 void GWEN_Time__fillTmplChars(const GWEN_TIME *t, 00687 GWEN_TIME_TMPLCHAR_LIST *ll, 00688 int useUtc) { 00689 GWEN_TIME_TMPLCHAR *e; 00690 int year, month, day, hour, minute, second; 00691 00692 if (useUtc) { 00693 GWEN_Time_GetBrokenDownUtcDate(t, &day, &month, &year); 00694 GWEN_Time_GetBrokenDownUtcTime(t, &hour, &minute, &second); 00695 } 00696 else { 00697 GWEN_Time_GetBrokenDownDate(t, &day, &month, &year); 00698 GWEN_Time_GetBrokenDownTime(t, &hour, &minute, &second); 00699 } 00700 00701 e=GWEN_TimeTmplChar_List_First(ll); 00702 while(e) { 00703 int v; 00704 char buffer[32]; 00705 00706 switch(e->character) { 00707 case 'Y': v=year; break; 00708 case 'M': v=month+1; break; 00709 case 'D': v=day; break; 00710 case 'h': v=hour; break; 00711 case 'm': v=minute; break; 00712 case 's': v=second; break; 00713 default: v=-1; break; 00714 } 00715 if (v==-1) { 00716 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown character, should not happen here"); 00717 abort(); 00718 } 00719 buffer[0]=0; 00720 snprintf(buffer, sizeof(buffer)-1, "%0*d", GWEN_TIME_TMPL_MAX_COUNT, v); 00721 buffer[sizeof(buffer)-1]=0; 00722 e->content=strdup(buffer); 00723 e->nextChar=strlen(e->content)-(e->count); 00724 e=GWEN_TimeTmplChar_List_Next(e); 00725 } 00726 } 00727 00728 00729 00730 00731 int GWEN_Time__toString(const GWEN_TIME *t, const char *tmpl, 00732 GWEN_BUFFER *buf, int useUtc) { 00733 GWEN_TIME_TMPLCHAR_LIST *ll; 00734 const char *s; 00735 00736 ll=GWEN_TimeTmplChar_List_new(); 00737 GWEN_Time__sampleTmplChars(t, tmpl, buf, ll); 00738 GWEN_Time__fillTmplChars(t, ll, useUtc); 00739 00740 s=tmpl; 00741 while(*s) { 00742 if (strchr("YMDhms", *s)) { 00743 GWEN_TIME_TMPLCHAR *e; 00744 char c; 00745 00746 e=GWEN_Time__findTmplChar(ll, *s); 00747 assert(e); 00748 assert(e->content); 00749 if (s[1]=='*') { 00750 /* append full string */ 00751 GWEN_Buffer_AppendString(buf, e->content); 00752 /* skip asterisk */ 00753 s++; 00754 } 00755 else { 00756 c=e->content[e->nextChar++]; 00757 assert(c); 00758 GWEN_Buffer_AppendByte(buf, c); 00759 } 00760 } 00761 else 00762 GWEN_Buffer_AppendByte(buf, *s); 00763 s++; 00764 } 00765 GWEN_TimeTmplChar_List_free(ll); 00766 return 0; 00767 } 00768 00769 00770 00771 int GWEN_Time_toString(const GWEN_TIME *t, const char *tmpl, 00772 GWEN_BUFFER *buf) { 00773 return GWEN_Time__toString(t, tmpl, buf, 0); 00774 } 00775 00776 00777 00778 int GWEN_Time_toUtcString(const GWEN_TIME *t, const char *tmpl, 00779 GWEN_BUFFER *buf) { 00780 return GWEN_Time__toString(t, tmpl, buf, 1); 00781 } 00782 00783 00784 00785 00786 00787 00788 00789 00790 00791