gwenhywfar 5.14.1
gwendate.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Tue Jul 07 2009
3 copyright : (C) 2022 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 * *
23 ***************************************************************************/
24
25#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
28
29
30#include "gwendate_p.h"
31#include "i18n_l.h"
32
33#include <gwenhywfar/debug.h>
34#include <gwenhywfar/misc.h>
35
36
37#include <time.h>
38#include <ctype.h>
39
40
41
42static const uint8_t daysInMonth[12]= {
43 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
44};
45
46
47static void _writeAsString(GWEN_DATE *gd);
48static GWEN_DATE *_createFromGregorianAndUseGivenString(int y, int m, int d, const char *s);
49static int _daysInMonth(int month, int year);
50
51
52
53
55{
57}
58
59
60
61/* if s is given it must contain a string of minimum 8 bytes length from which the date was derived,
62 * if not given the string representation will be generated. */
63GWEN_DATE *_createFromGregorianAndUseGivenString(int y, int m, int d, const char *s)
64{
65 GWEN_DATE *gd;
66
67 if (m<1 || m>12 || d<1 || d>31 || y<0) {
68 DBG_INFO(GWEN_LOGDOMAIN, "Bad date values (erroneous year=%d, month=%d, day=%d)", y, m, d);
69 return NULL;
70 }
71
72 if (d>_daysInMonth(m, y)) {
73 DBG_INFO(GWEN_LOGDOMAIN, "Bad date values (day value too high, erroneous year=%d, month=%d, day=%d)", y, m, d);
74 return NULL;
75 }
76
77
79 gd->year=y;
80 gd->month=m;
81 gd->day=d;
82 gd->julian=(1461*(y+4800+(m-14)/12))/4+
83 (367*(m-2-12*((m-14)/12)))/12-
84 (3*((y+4900+(m-14)/12)/100))/4+
85 d-32075;
86
87 if (s && *s) {
88 memmove(gd->asString, s, 8);
89 gd->asString[8]=0;
90 }
91 else
93
94 return gd;
95}
96
97
98
99void GWEN_Date_setJulian(GWEN_DATE *gd, int julian)
100{
101 int l, n, i, j /*, len */;
102
103 l=julian+68569;
104 n=(4*l)/146097;
105 l=l-(146097*n+3)/4;
106 i=(4000*(l+1))/1461001;
107 l=l-(1461*i)/4+31;
108 j=(80*l)/2447;
109 gd->day=l-(2447*j)/80;
110 l=j/11;
111 gd->month=j+2-(12*l);
112 gd->year=100*(n-49)+i+l;
113 gd->julian=julian;
114
115#if 1
116 _writeAsString(gd);
117#else
118 len=snprintf(gd->asString, sizeof(gd->asString)-1,
119 "%04d%02d%02d",
120 gd->year, gd->month, gd->day);
121 gd->asString[sizeof(gd->asString)-1]=0;
122 if ((int)(sizeof(gd->asString)-1) < len) {
123 DBG_ERROR(GWEN_LOGDOMAIN, "truncated date string [%s]", gd->asString);
124 }
125#endif
126
127}
128
129
130
132{
133 char *ptr;
134 int x;
135
136 ptr=gd->asString+8;
137 *(ptr--)=0;
138
139 x=gd->day;
140 *(ptr--)='0'+(x%10);
141 x/=10;
142 *(ptr--)='0'+(x%10);
143
144 x=gd->month;
145 *(ptr--)='0'+(x%10);
146 x/=10;
147 *(ptr--)='0'+(x%10);
148
149 x=gd->year;
150 *(ptr--)='0'+(x%10);
151 x/=10;
152 *(ptr--)='0'+(x%10);
153 x/=10;
154 *(ptr--)='0'+(x%10);
155 x/=10;
156 *ptr='0'+(x%10);
157}
158
159
160void GWEN_Date_AddDays(GWEN_DATE *gd, int days)
161{
162 GWEN_Date_setJulian(gd, gd->julian+days);
163}
164
165
166
167void GWEN_Date_SubDays(GWEN_DATE *gd, int days)
168{
169 GWEN_Date_setJulian(gd, gd->julian-days);
170}
171
172
173
175{
176 GWEN_DATE *gd;
177
179 GWEN_Date_setJulian(gd, julian);
180 return gd;
181}
182
183
184
186{
187 struct tm *ltm;
188
189 ltm=localtime(&t);
190 if (ltm) {
191 GWEN_DATE *gd;
192
193 gd=GWEN_Date_fromGregorian(ltm->tm_year+1900, ltm->tm_mon+1, ltm->tm_mday);
194 return gd;
195 }
196
197 return NULL;
198}
199
200
201
203{
204 struct tm ti;
205 struct tm *tp;
206 time_t tt;
207
208 tt=time(0);
209 tp=localtime(&tt);
210 assert(tp);
211 memmove(&ti, tp, sizeof(ti));
212 ti.tm_sec=0;
213 ti.tm_min=0;
214 ti.tm_hour=0;
215 ti.tm_year=gd->year-1900;
216 ti.tm_mon=gd->month-1;
217 ti.tm_mday=gd->day;
218 ti.tm_yday=0;
219 ti.tm_wday=0;
220 tt=mktime(&ti);
221 assert(tt!=(time_t)-1);
222 return tt;
223}
224
225
226
228{
229 struct tm *ltm;
230
231 ltm=gmtime(&t);
232 if (ltm) {
233 GWEN_DATE *gd;
234
235 gd=GWEN_Date_fromGregorian(ltm->tm_year+1900, ltm->tm_mon+1, ltm->tm_mday);
236 return gd;
237 }
238
239 return NULL;
240}
241
242
243
244
246{
247 time_t l;
248
249 time(&l);
250 return GWEN_Date_fromLocalTime(l);
251}
252
253
254
256{
257 GWEN_DATE *gd;
258
259 assert(ogd);
260
262#if 0
263 gd->year=ogd->year;
264 gd->month=ogd->month;
265 gd->day=ogd->day;
266 gd->julian=ogd->julian;
267 memmove(gd->asString, ogd->asString, sizeof(gd->asString));
268#else
269 memmove(gd, ogd, sizeof(GWEN_DATE));
270#endif
271 return gd;
272}
273
274
275
277{
278
279#if 1
280 if (s && strlen(s)>7) {
281 int y, m, d;
282 GWEN_DATE *result;
283 const char *originalPtr;
284
285 originalPtr=s;
286 y=*(s++)-'0';
287 y*=10;
288 y+=*(s++)-'0';
289 y*=10;
290 y+=*(s++)-'0';
291 y*=10;
292 y+=*(s++)-'0';
293
294 m=*(s++)-'0';
295 m*=10;
296 m+=*(s++)-'0';
297
298 d=*(s++)-'0';
299 d*=10;
300 d+=*(s++)-'0';
301
302 result=_createFromGregorianAndUseGivenString(y, m, d, originalPtr);
303 if (!result) {
304 DBG_INFO(GWEN_LOGDOMAIN, "Bad date string [%s]", originalPtr);
305 }
306 return result;
307 }
308 else {
309 DBG_INFO(GWEN_LOGDOMAIN, "Bad date string [%s]", s?s:"<empty>");
310 return NULL;
311 }
312#else
313 int y, m, d;
314
315 if (3==sscanf(s, "%04d%02d%02d", &y, &m, &d)) {
316 GWEN_DATE *result = GWEN_Date_fromGregorian(y, m, d);
317 if (!result)
318 DBG_INFO(GWEN_LOGDOMAIN, "Bad date string [%s]", s);
319 return result;
320 }
321 else {
322 DBG_INFO(GWEN_LOGDOMAIN, "Bad date string [%s]", s);
323 return NULL;
324 }
325#endif
326}
327
328
329
331{
332 if (gd) {
334 }
335}
336
337
338
340{
341 return ((y%4==0) && (y%100!=0)) || (y%400==0);
342}
343
344
345
346
348{
349 return _daysInMonth(gd->month, gd->year);
350}
351
352
353
354int _daysInMonth(int month, int year)
355{
356 if (month>12) {
357 DBG_INFO(GWEN_LOGDOMAIN, "Bad month %d", month);
358 return GWEN_ERROR_GENERIC;
359 }
360 if (month==2 && GWEN_Date_IsLeapYear(year))
361 /* February in a leap year */
362 return 29;
363 else
364 return daysInMonth[month-1];
365}
366
367
368
370{
371 GWEN_DATE *gd11;
372 int result;
373
374 assert(gd);
375
376 gd11=GWEN_Date_fromGregorian(gd->year, 1, 1);
377 result=(gd->julian)-(gd11->julian)+1; /* count current day also (e.g. return 1 for Jan 1) */
378 GWEN_Date_free(gd11);
379
380 return result;
381}
382
383
384
386{
387 assert(gd);
388 return gd->year;
389}
390
391
392
394{
395 assert(gd);
396 return gd->month;
397}
398
399
400
402{
403 assert(gd);
404 return gd->day;
405}
406
407
408
410{
411 assert(gd);
412 return gd->julian;
413}
414
415
416
418{
419 assert(gd);
420 return (gd->julian+1)%7; /* 0=Sunday */
421}
422
423
424
425const char *GWEN_Date_GetString(const GWEN_DATE *gd)
426{
427 assert(gd);
428 return gd->asString;
429}
430
431
432
433int GWEN_Date_Compare(const GWEN_DATE *gd1, const GWEN_DATE *gd0)
434{
435 if (gd0 && gd1) {
436 if (gd1->julian==gd0->julian)
437 return 0;
438 else if (gd1->julian>gd0->julian)
439 return 1;
440 else
441 return -1;
442 }
443 else if (gd0)
444 return 1;
445 else if (gd1)
446 return -1;
447 else
448 return 0;
449}
450
451
452
453int GWEN_Date_Diff(const GWEN_DATE *gd1, const GWEN_DATE *gd0)
454{
455 assert(gd1);
456 assert(gd0);
457
458 return gd1->julian-gd0->julian;
459}
460
461
462
464{
465 GWEN_BUFFER *tbuf;
466 GWEN_DATE *gd;
467
468 tbuf=GWEN_Buffer_new(0, 32, 0, 1);
469 GWEN_Time_toString(ti, "YYYYMMDD", tbuf);
471 GWEN_Buffer_free(tbuf);
472
473 return gd;
474}
475
476
477
478
479GWEN_DATE *GWEN_Date_fromStringWithTemplate(const char *s, const char *tmpl)
480{
481 int year, month, day;
482 const char *p;
483 const char *t;
484 GWEN_DATE *gwt;
485
486 assert(s);
487 assert(tmpl);
488 year=month=day=0;
489
490 p=s;
491 t=tmpl;
492 while (*t && *p) {
493 int i;
494
495 if (*t=='*') {
496 t++;
497 if (!*t) {
498 DBG_ERROR(GWEN_LOGDOMAIN, "Bad pattern: Must not end with \"*\"");
499 return 0;
500 }
501 i=0;
502 while (*p) {
503 if (!isdigit((int)*p))
504 break;
505 if (*p==*t)
506 break;
507 i*=10;
508 i+=(*p)-'0';
509 p++;
510 } /* while */
511 }
512 else {
513 if (isdigit((int)*p))
514 i=(*p)-'0';
515 else
516 i=-1;
517 p++;
518 }
519
520 if (i==-1 && strchr("YMD", *t)!=NULL) {
522 "No more digits at [%s], continuing", t);
523 p--;
524 }
525 else {
526 switch (*t) {
527 case 'Y':
528 if (i==-1) {
529 DBG_INFO(GWEN_LOGDOMAIN, "here");
530 return 0;
531 }
532 year*=10;
533 year+=i;
534 break;
535 case 'M':
536 if (i==-1) {
537 DBG_INFO(GWEN_LOGDOMAIN, "here");
538 return 0;
539 }
540 month*=10;
541 month+=i;
542 break;
543 case 'D':
544 if (i==-1) {
545 DBG_INFO(GWEN_LOGDOMAIN, "here");
546 return 0;
547 }
548 day*=10;
549 day+=i;
550 break;
551 default:
553 "Unknown character in template, will skip in both strings");
554 break;
555 }
556 }
557 t++;
558 } /* while */
559
560 if (year<100)
561 year+=2000;
562
564 "Got this date/time: %04d/%02d/%02d",
565 year, month, day);
566
567 /* get time in local time */
568 gwt=GWEN_Date_fromGregorian(year, month, day);
569 if (!gwt) {
570 DBG_ERROR(GWEN_LOGDOMAIN, "Bad date string [%s]", s);
571 return 0;
572 }
573 return gwt;
574}
575
576
577
578
579
580GWEN_LIST_FUNCTIONS(GWEN_DATE_TMPLCHAR, GWEN_DateTmplChar)
581
582
583GWEN_DATE_TMPLCHAR *GWEN_DateTmplChar_new(char c)
584{
585 GWEN_DATE_TMPLCHAR *e;
586
587 GWEN_NEW_OBJECT(GWEN_DATE_TMPLCHAR, e);
588 GWEN_LIST_INIT(GWEN_DATE_TMPLCHAR, e);
589 e->character=c;
590 switch (c) {
591 case 'Y':
592 e->maxCount=4;
593 break;
594 case 'M':
595 e->maxCount=2;
596 break;
597 case 'D':
598 e->maxCount=2;
599 break;
600 case 'W':
601 e->maxCount=1;
602 break;
603 case 'w':
604 default:
605 e->maxCount=GWEN_DATE_TMPL_MAX_COUNT;
606 break;
607 }
608
609 return e;
610}
611
612
613
614void GWEN_DateTmplChar_free(GWEN_DATE_TMPLCHAR *e)
615{
616 if (e) {
617 free(e->content);
618 GWEN_LIST_FINI(GWEN_DATE_TMPLCHAR, e);
620 }
621}
622
623
624
625GWEN_DATE_TMPLCHAR *GWEN_Date__findTmplChar(GWEN_DATE_TMPLCHAR_LIST *ll, char c)
626{
627 GWEN_DATE_TMPLCHAR *e;
628
629 e=GWEN_DateTmplChar_List_First(ll);
630 while (e) {
631 if (e->character==c)
632 break;
633 e=GWEN_DateTmplChar_List_Next(e);
634 }
635
636 return e;
637}
638
639
640
641
642void GWEN_Date__sampleTmplChars(GWEN_UNUSED const GWEN_DATE *t, const char *tmpl,
644 GWEN_DATE_TMPLCHAR_LIST *ll)
645{
646 const char *s;
647
648 s=tmpl;
649 while (*s) {
650 if (strchr("YMDWw", *s)) {
651 GWEN_DATE_TMPLCHAR *e;
652
653 e=GWEN_Date__findTmplChar(ll, *s);
654 if (!e) {
655 /* new entry, create it */
657 GWEN_DateTmplChar_List_Add(e, ll);
658 }
659 assert(e);
660 e->count++;
661 }
662 else {
663 DBG_DEBUG(GWEN_LOGDOMAIN, "Unknown character in template (%02x)",
664 *s);
665 }
666 s++;
667 }
668}
669
670
671
672void GWEN_Date__fillTmplChars(const GWEN_DATE *t, GWEN_DATE_TMPLCHAR_LIST *ll)
673{
674 GWEN_DATE_TMPLCHAR *e;
675
676
677 e=GWEN_DateTmplChar_List_First(ll);
678 while (e) {
679 int v;
680
681 if (e->character=='w') {
682 const char *s=NULL;
683
684 switch (GWEN_Date_WeekDay(t)) {
685 case 0:
686 s=I18N("Sunday");
687 break;
688 case 1:
689 s=I18N("Monday");
690 break;
691 case 2:
692 s=I18N("Tuesday");
693 break;
694 case 3:
695 s=I18N("Wednesday");
696 break;
697 case 4:
698 s=I18N("Thursday");
699 break;
700 case 5:
701 s=I18N("Friday");
702 break;
703 case 6:
704 s=I18N("Saturday");
705 break;
706 default:
707 DBG_DEBUG(GWEN_LOGDOMAIN, "Invalid week day (%2d)", GWEN_Date_WeekDay(t));
708 s=NULL;
709 break;
710 }
711 assert(s);
712 e->content=strdup(s);
713 e->nextChar=0;
714 }
715 else {
716 char buffer[32];
717 int clen;
718
719 switch (e->character) {
720 case 'Y':
721 v=t->year;
722 break;
723 case 'M':
724 v=t->month;
725 break;
726 case 'D':
727 v=t->day;
728 break;
729 case 'W':
731 break;
732 default:
733 v=-1;
734 break;
735 }
736 if (v==-1) {
737 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown character, should not happen here");
738 abort();
739 }
740 buffer[0]=0;
741 snprintf(buffer, sizeof(buffer)-1, "%0*d", e->maxCount, v);
742 buffer[sizeof(buffer)-1]=0;
743 e->content=strdup(buffer);
744 /* adjust counter if there are more than maxCount template chars */
745 clen=strlen(e->content);
746 if (e->count>clen)
747 e->count=clen;
748 e->nextChar=clen-(e->count);
749 }
750
751 e=GWEN_DateTmplChar_List_Next(e);
752 }
753}
754
755
756
757
758int GWEN_Date_toStringWithTemplate(const GWEN_DATE *t, const char *tmpl, GWEN_BUFFER *buf)
759{
760 GWEN_DATE_TMPLCHAR_LIST *ll;
761 const char *s;
762
763 ll=GWEN_DateTmplChar_List_new();
764 GWEN_Date__sampleTmplChars(t, tmpl, buf, ll);
766
767 s=tmpl;
768 while (*s) {
769 if (strchr("YMDWw", *s)) {
770 GWEN_DATE_TMPLCHAR *e;
771 char c;
772
773 e=GWEN_Date__findTmplChar(ll, *s);
774 assert(e);
775 assert(e->content);
776 if (s[1]=='*') {
777 /* append full string */
778 GWEN_Buffer_AppendString(buf, e->content);
779 /* skip asterisk */
780 s++;
781 }
782 else {
783 c=e->content[e->nextChar];
784 if (c!=0) {
786 e->nextChar++;
787 }
788 }
789 }
790 else
791 GWEN_Buffer_AppendByte(buf, *s);
792 s++;
793 }
794 GWEN_DateTmplChar_List_free(ll);
795 return 0;
796}
797
798
799
801{
802 const char *s;
803
804 assert(dt);
807 return 0;
808}
809
810
811
813{
814 const char *s;
815
816 s=GWEN_DB_GetCharValue(db, "dateString", 0, NULL);
817 if (s && *s) {
818 GWEN_DATE *dt;
819
821 if (dt==NULL) {
822 DBG_INFO(GWEN_LOGDOMAIN, "Invalid date [%s]", s);
823 return NULL;
824 }
825
826 return dt;
827 }
828 else {
829 DBG_VERBOUS(GWEN_LOGDOMAIN, "no or empty date");
830 return NULL;
831 }
832}
833
834
835
837{
838 if (dt) {
839 int weekDay;
840
841 weekDay=GWEN_Date_WeekDay(dt);
842 if (weekDay==0)
843 return GWEN_Date_fromJulian(dt->julian-6);
844 else
845 return GWEN_Date_fromJulian((dt->julian-weekDay)+1);
846 }
847 return NULL;
848}
849
850
851
853{
854 if (dt)
856 return NULL;
857}
858
859
860
865
866
867
869{
870 int day;
871
872 switch (GWEN_Date_GetMonth(dt)) {
873 case 1:
874 case 3:
875 case 5:
876 case 7:
877 case 8:
878 case 10:
879 case 12:
880 day=31;
881 break;
882 case 2:
884 day=29;
885 else
886 day=28;
887 break;
888
889 case 4:
890 case 6:
891 case 9:
892 case 11:
893 day=30;
894 break;
895
896 default:
897 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid month (%d)", GWEN_Date_GetMonth(dt));
898 abort();
899 break;
900 }
902}
903
904
905
907{
908 int m;
909
910 m=GWEN_Date_GetMonth(dt)>>2;
911 switch (m) {
912 case 0:
914 case 1:
916 case 2:
918 case 3:
920 default:
921 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid quarter (%d)", m);
922 break;
923 }
924
925 return NULL;
926}
927
928
929
931{
932 int m;
933
934 m=GWEN_Date_GetMonth(dt)>>2;
935 switch (m) {
936 case 0:
938 case 1:
940 case 2:
942 case 3:
943 return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 12, 31);
944 default:
945 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid quarter (%d)", m);
946 break;
947 }
948
949 return NULL;
950}
951
952
953
955{
956 if (GWEN_Date_GetMonth(dt)<7)
958 else
960}
961
962
963
965{
966 if (GWEN_Date_GetMonth(dt)<7)
968 else
969 return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 12, 31);
970}
971
972
973
978
979
980
985
986
987
989{
990 GWEN_DATE *tmpDate;
991 GWEN_DATE *result;
992 int j;
993
995 j=GWEN_Date_GetJulian(tmpDate)-1;
996 GWEN_Date_free(tmpDate);
997 tmpDate=GWEN_Date_fromJulian(j);
999 GWEN_Date_free(tmpDate);
1000 return result;
1001}
1002
1003
1004
1006{
1007 GWEN_DATE *tmpDate;
1008 int j;
1009
1011 j=GWEN_Date_GetJulian(tmpDate)-1;
1012 GWEN_Date_free(tmpDate);
1013 return GWEN_Date_fromJulian(j);
1014}
1015
1016
1017
1019{
1020 GWEN_DATE *tmpDate;
1021 GWEN_DATE *result;
1022
1024 result=GWEN_Date_GetThisQuarterYearStart(tmpDate);
1025 GWEN_Date_free(tmpDate);
1026 return result;
1027}
1028
1029
1030
1032{
1033 GWEN_DATE *tmpDate;
1034 int j;
1035
1037 j=GWEN_Date_GetJulian(tmpDate)-1;
1038 GWEN_Date_free(tmpDate);
1039 return GWEN_Date_fromJulian(j);
1040}
1041
1042
1043
1045{
1046 GWEN_DATE *tmpDate;
1047 GWEN_DATE *result;
1048
1049 tmpDate=GWEN_Date_GetLastHalfYearEnd(dt);
1050 result=GWEN_Date_GetThisHalfYearStart(tmpDate);
1051 GWEN_Date_free(tmpDate);
1052 return result;
1053}
1054
1055
1056
1058{
1059 GWEN_DATE *tmpDate;
1060 int j;
1061
1063 j=GWEN_Date_GetJulian(tmpDate)-1;
1064 GWEN_Date_free(tmpDate);
1065 return GWEN_Date_fromJulian(j);
1066}
1067
1068
1069
1071{
1072 GWEN_DATE *tmpDate;
1073 GWEN_DATE *result;
1074
1075 tmpDate=GWEN_Date_GetLastYearEnd(dt);
1076 result=GWEN_Date_GetThisYearStart(tmpDate);
1077 GWEN_Date_free(tmpDate);
1078 return result;
1079}
1080
1081
1082
1084{
1085 GWEN_DATE *tmpDate;
1086 int j;
1087
1088 tmpDate=GWEN_Date_GetThisYearStart(dt);
1089 j=GWEN_Date_GetJulian(tmpDate)-1;
1090 GWEN_Date_free(tmpDate);
1091 return GWEN_Date_fromJulian(j);
1092}
1093
1094
1095
1096
1097
1098
1099
1100
#define NULL
Definition binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition buffer.c:42
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition buffer.c:89
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition buffer.c:992
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition buffer.c:393
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition db.c:971
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition db.c:997
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition db.h:121
struct GWEN_DB_NODE GWEN_DB_NODE
Definition db.h:228
#define DBG_VERBOUS(dbg_logger, format,...)
Definition debug.h:224
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_DEBUG(dbg_logger, format,...)
Definition debug.h:214
#define I18N(m)
Definition error.c:42
#define GWEN_ERROR_GENERIC
Definition error.h:62
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
GWEN_DATE * GWEN_Date_GetLastMonthEnd(const GWEN_DATE *dt)
Definition gwendate.c:1005
GWEN_DATE * GWEN_Date_GetThisQuarterYearEnd(const GWEN_DATE *dt)
Definition gwendate.c:930
GWEN_DATE * GWEN_Date_GetThisYearStart(const GWEN_DATE *dt)
Definition gwendate.c:974
void GWEN_Date_SubDays(GWEN_DATE *gd, int days)
Definition gwendate.c:167
int GWEN_Date_Diff(const GWEN_DATE *gd1, const GWEN_DATE *gd0)
Definition gwendate.c:453
GWEN_DATE * GWEN_Date_fromString(const char *s)
Definition gwendate.c:276
GWEN_DATE_TMPLCHAR * GWEN_DateTmplChar_new(char c)
Definition gwendate.c:583
GWEN_DATE * GWEN_Date_GetThisMonthEnd(const GWEN_DATE *dt)
Definition gwendate.c:868
GWEN_DATE * GWEN_Date_fromStringWithTemplate(const char *s, const char *tmpl)
Definition gwendate.c:479
GWEN_DATE * GWEN_Date_GetThisMonthStart(const GWEN_DATE *dt)
Definition gwendate.c:861
GWEN_DATE * GWEN_Date_fromGmTime(time_t t)
Definition gwendate.c:227
GWEN_DATE * GWEN_Date_GetLastHalfYearStart(const GWEN_DATE *dt)
Definition gwendate.c:1044
static void _writeAsString(GWEN_DATE *gd)
Definition gwendate.c:131
GWEN_DATE * GWEN_Date_fromJulian(int julian)
Definition gwendate.c:174
int GWEN_Date_IsLeapYear(int y)
Definition gwendate.c:339
GWEN_DATE_TMPLCHAR * GWEN_Date__findTmplChar(GWEN_DATE_TMPLCHAR_LIST *ll, char c)
Definition gwendate.c:625
GWEN_DATE * GWEN_Date_GetLastYearEnd(const GWEN_DATE *dt)
Definition gwendate.c:1083
void GWEN_Date__fillTmplChars(const GWEN_DATE *t, GWEN_DATE_TMPLCHAR_LIST *ll)
Definition gwendate.c:672
void GWEN_Date_AddDays(GWEN_DATE *gd, int days)
Definition gwendate.c:160
int GWEN_Date_DaysInYear(const GWEN_DATE *gd)
Definition gwendate.c:369
GWEN_DATE * GWEN_Date_GetLastYearStart(const GWEN_DATE *dt)
Definition gwendate.c:1070
GWEN_DATE * GWEN_Date_fromTime(const GWEN_TIME *ti)
Definition gwendate.c:463
int GWEN_Date_GetYear(const GWEN_DATE *gd)
Definition gwendate.c:385
static int _daysInMonth(int month, int year)
Definition gwendate.c:354
void GWEN_Date__sampleTmplChars(GWEN_UNUSED const GWEN_DATE *t, const char *tmpl, GWEN_UNUSED GWEN_BUFFER *buf, GWEN_DATE_TMPLCHAR_LIST *ll)
Definition gwendate.c:642
GWEN_DATE * GWEN_Date_GetThisYearEnd(const GWEN_DATE *dt)
Definition gwendate.c:981
GWEN_DATE * GWEN_Date_dup(const GWEN_DATE *ogd)
Definition gwendate.c:255
GWEN_DATE * GWEN_Date_fromGregorian(int y, int m, int d)
Definition gwendate.c:54
GWEN_DATE * GWEN_Date_GetThisHalfYearEnd(const GWEN_DATE *dt)
Definition gwendate.c:964
static GWEN_DATE * _createFromGregorianAndUseGivenString(int y, int m, int d, const char *s)
Definition gwendate.c:63
const char * GWEN_Date_GetString(const GWEN_DATE *gd)
Definition gwendate.c:425
int GWEN_Date_WeekDay(const GWEN_DATE *gd)
Definition gwendate.c:417
int GWEN_Date_toStringWithTemplate(const GWEN_DATE *t, const char *tmpl, GWEN_BUFFER *buf)
Definition gwendate.c:758
GWEN_DATE * GWEN_Date_GetThisWeekStartFromMonday(const GWEN_DATE *dt)
Definition gwendate.c:836
int GWEN_Date_GetMonth(const GWEN_DATE *gd)
Definition gwendate.c:393
int GWEN_Date_toDb(const GWEN_DATE *dt, GWEN_DB_NODE *db)
Definition gwendate.c:800
void GWEN_DateTmplChar_free(GWEN_DATE_TMPLCHAR *e)
Definition gwendate.c:614
void GWEN_Date_free(GWEN_DATE *gd)
Definition gwendate.c:330
int GWEN_Date_GetJulian(const GWEN_DATE *gd)
Definition gwendate.c:409
int GWEN_Date_Compare(const GWEN_DATE *gd1, const GWEN_DATE *gd0)
Definition gwendate.c:433
GWEN_DATE * GWEN_Date_GetThisHalfYearStart(const GWEN_DATE *dt)
Definition gwendate.c:954
GWEN_DATE * GWEN_Date_GetLastQuarterYearStart(const GWEN_DATE *dt)
Definition gwendate.c:1018
int GWEN_Date_DaysInMonth(const GWEN_DATE *gd)
Definition gwendate.c:347
GWEN_DATE * GWEN_Date_CurrentDate(void)
Definition gwendate.c:245
time_t GWEN_Date_toLocalTime(const GWEN_DATE *gd)
Definition gwendate.c:202
GWEN_DATE * GWEN_Date_GetThisWeekStartFromSunday(const GWEN_DATE *dt)
Definition gwendate.c:852
GWEN_DATE * GWEN_Date_fromLocalTime(time_t t)
Definition gwendate.c:185
void GWEN_Date_setJulian(GWEN_DATE *gd, int julian)
Definition gwendate.c:99
GWEN_DATE * GWEN_Date_fromDb(GWEN_DB_NODE *db)
Definition gwendate.c:812
GWEN_DATE * GWEN_Date_GetThisQuarterYearStart(const GWEN_DATE *dt)
Definition gwendate.c:906
int GWEN_Date_GetDay(const GWEN_DATE *gd)
Definition gwendate.c:401
GWEN_DATE * GWEN_Date_GetLastQuarterYearEnd(const GWEN_DATE *dt)
Definition gwendate.c:1031
GWEN_DATE * GWEN_Date_GetLastMonthStart(const GWEN_DATE *dt)
Definition gwendate.c:988
GWEN_DATE * GWEN_Date_GetLastHalfYearEnd(const GWEN_DATE *dt)
Definition gwendate.c:1057
static const uint8_t daysInMonth[12]
Definition gwendate.c:42
struct GWEN_DATE GWEN_DATE
Definition gwendate.h:34
#define GWEN_UNUSED
struct GWEN_TIME GWEN_TIME
Definition gwentime.h:43
GWENHYWFAR_API int GWEN_Time_toString(const GWEN_TIME *t, const char *tmpl, GWEN_BUFFER *buf)
#define GWEN_LIST_FINI(t, element)
Definition list1.h:475
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition list1.h:367
#define GWEN_LIST_INIT(t, element)
Definition list1.h:466
#define GWEN_LOGDOMAIN
Definition logger.h:32
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55