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