gwentime_all.c

Go to the documentation of this file.
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