gwenhywfar  5.10.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 
42 static const uint8_t daysInMonth[12]= {
43  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
44 };
45 
46 
47 static void _writeAsString(GWEN_DATE *gd);
48 static GWEN_DATE *_createFromGregorianAndUseGivenString(int y, int m, int d, const char *s);
49 static int _daysInMonth(int month, int year);
50 
51 
52 
53 
54 GWEN_DATE *GWEN_Date_fromGregorian(int y, int m, int d)
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. */
63 GWEN_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
92  _writeAsString(gd);
93 
94  return gd;
95 }
96 
97 
98 
99 void 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 
160 void GWEN_Date_AddDays(GWEN_DATE *gd, int days)
161 {
162  GWEN_Date_setJulian(gd, gd->julian+days);
163 }
164 
165 
166 
167 void 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) {
333  GWEN_FREE_OBJECT(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 
354 int _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);
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 
425 const char *GWEN_Date_GetString(const GWEN_DATE *gd)
426 {
427  assert(gd);
428  return gd->asString;
429 }
430 
431 
432 
433 int 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 
453 int 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 
479 GWEN_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 
580 GWEN_LIST_FUNCTIONS(GWEN_DATE_TMPLCHAR, GWEN_DateTmplChar)
581 
582 
583 GWEN_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 
614 void GWEN_DateTmplChar_free(GWEN_DATE_TMPLCHAR *e)
615 {
616  if (e) {
617  free(e->content);
618  GWEN_LIST_FINI(GWEN_DATE_TMPLCHAR, e);
619  GWEN_FREE_OBJECT(e);
620  }
621 }
622 
623 
624 
625 GWEN_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 
642 void 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 */
656  e=GWEN_DateTmplChar_new(*s);
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 
672 void 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':
730  v=GWEN_Date_WeekDay(t);
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 
758 int 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) {
785  GWEN_Buffer_AppendByte(buf, c);
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);
805  s=GWEN_Date_GetString(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 
820  dt=GWEN_Date_fromString(s);
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 {
839 }
840 
841 
842 
844 {
845  int day;
846 
847  switch (GWEN_Date_GetMonth(dt)) {
848  case 1:
849  case 3:
850  case 5:
851  case 7:
852  case 8:
853  case 10:
854  case 12:
855  day=31;
856  break;
857  case 2:
859  day=29;
860  else
861  day=28;
862  break;
863 
864  case 4:
865  case 6:
866  case 9:
867  case 11:
868  day=30;
869  break;
870 
871  default:
872  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid month (%d)", GWEN_Date_GetMonth(dt));
873  abort();
874  break;
875  }
877 }
878 
879 
880 
882 {
883  int m;
884 
885  m=GWEN_Date_GetMonth(dt)>>2;
886  switch (m) {
887  case 0:
888  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 1, 1);
889  case 1:
890  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 4, 1);
891  case 2:
892  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 7, 1);
893  case 3:
894  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 10, 1);
895  default:
896  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid quarter (%d)", m);
897  break;
898  }
899 
900  return NULL;
901 }
902 
903 
904 
906 {
907  int m;
908 
909  m=GWEN_Date_GetMonth(dt)>>2;
910  switch (m) {
911  case 0:
912  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 3, 31);
913  case 1:
914  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 6, 30);
915  case 2:
916  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 9, 30);
917  case 3:
918  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 12, 31);
919  default:
920  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid quarter (%d)", m);
921  break;
922  }
923 
924  return NULL;
925 }
926 
927 
928 
930 {
931  if (GWEN_Date_GetMonth(dt)<7)
932  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 1, 1);
933  else
934  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 7, 1);
935 }
936 
937 
938 
940 {
941  if (GWEN_Date_GetMonth(dt)<7)
942  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 6, 30);
943  else
944  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 12, 31);
945 }
946 
947 
948 
950 {
951  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 1, 1);
952 }
953 
954 
955 
957 {
958  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 12, 31);
959 }
960 
961 
962 
964 {
965  GWEN_DATE *tmpDate;
966  GWEN_DATE *result;
967  int j;
968 
970  j=GWEN_Date_GetJulian(tmpDate)-1;
971  GWEN_Date_free(tmpDate);
972  tmpDate=GWEN_Date_fromJulian(j);
973  result=GWEN_Date_fromGregorian(GWEN_Date_GetYear(tmpDate), GWEN_Date_GetMonth(tmpDate), 1);
974  GWEN_Date_free(tmpDate);
975  return result;
976 }
977 
978 
979 
981 {
982  GWEN_DATE *tmpDate;
983  int j;
984 
986  j=GWEN_Date_GetJulian(tmpDate)-1;
987  GWEN_Date_free(tmpDate);
988  return GWEN_Date_fromJulian(j);
989 }
990 
991 
992 
994 {
995  GWEN_DATE *tmpDate;
996  GWEN_DATE *result;
997 
999  result=GWEN_Date_GetThisQuarterYearStart(tmpDate);
1000  GWEN_Date_free(tmpDate);
1001  return result;
1002 }
1003 
1004 
1005 
1007 {
1008  GWEN_DATE *tmpDate;
1009  int j;
1010 
1012  j=GWEN_Date_GetJulian(tmpDate)-1;
1013  GWEN_Date_free(tmpDate);
1014  return GWEN_Date_fromJulian(j);
1015 }
1016 
1017 
1018 
1020 {
1021  GWEN_DATE *tmpDate;
1022  GWEN_DATE *result;
1023 
1024  tmpDate=GWEN_Date_GetLastHalfYearEnd(dt);
1025  result=GWEN_Date_GetThisHalfYearStart(tmpDate);
1026  GWEN_Date_free(tmpDate);
1027  return result;
1028 }
1029 
1030 
1031 
1033 {
1034  GWEN_DATE *tmpDate;
1035  int j;
1036 
1037  tmpDate=GWEN_Date_GetThisHalfYearStart(dt);
1038  j=GWEN_Date_GetJulian(tmpDate)-1;
1039  GWEN_Date_free(tmpDate);
1040  return GWEN_Date_fromJulian(j);
1041 }
1042 
1043 
1044 
1046 {
1047  GWEN_DATE *tmpDate;
1048  GWEN_DATE *result;
1049 
1050  tmpDate=GWEN_Date_GetLastYearEnd(dt);
1051  result=GWEN_Date_GetThisYearStart(tmpDate);
1052  GWEN_Date_free(tmpDate);
1053  return result;
1054 }
1055 
1056 
1057 
1059 {
1060  GWEN_DATE *tmpDate;
1061  int j;
1062 
1063  tmpDate=GWEN_Date_GetThisYearStart(dt);
1064  j=GWEN_Date_GetJulian(tmpDate)-1;
1065  GWEN_Date_free(tmpDate);
1066  return GWEN_Date_fromJulian(j);
1067 }
1068 
1069 
1070 
1071 
1072 
1073 
1074 
1075 
GWEN_DATE * GWEN_Date_fromDb(GWEN_DB_NODE *db)
Definition: gwendate.c:812
struct GWEN_TIME GWEN_TIME
Definition: gwentime.h:43
void GWEN_Date_SubDays(GWEN_DATE *gd, int days)
Definition: gwendate.c:167
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
#define I18N(m)
Definition: error.c:42
GWEN_DATE * GWEN_Date_fromString(const char *s)
Definition: gwendate.c:276
GWEN_DATE * GWEN_Date_dup(const GWEN_DATE *ogd)
Definition: gwendate.c:255
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
GWEN_DATE * GWEN_Date_GetLastHalfYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:1019
GWEN_DATE * GWEN_Date_fromStringWithTemplate(const char *s, const char *tmpl)
Definition: gwendate.c:479
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
GWEN_DATE_TMPLCHAR * GWEN_DateTmplChar_new(char c)
Definition: gwendate.c:583
GWEN_DATE * GWEN_Date_GetLastMonthStart(const GWEN_DATE *dt)
Definition: gwendate.c:963
static const uint8_t daysInMonth[12]
Definition: gwendate.c:42
int GWEN_Date_WeekDay(const GWEN_DATE *gd)
Definition: gwendate.c:417
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
time_t GWEN_Date_toLocalTime(const GWEN_DATE *gd)
Definition: gwendate.c:202
GWEN_DATE * GWEN_Date_GetThisMonthEnd(const GWEN_DATE *dt)
Definition: gwendate.c:843
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
int GWEN_Date_toStringWithTemplate(const GWEN_DATE *t, const char *tmpl, GWEN_BUFFER *buf)
Definition: gwendate.c:758
void GWEN_DateTmplChar_free(GWEN_DATE_TMPLCHAR *e)
Definition: gwendate.c:614
GWEN_DATE * GWEN_Date_CurrentDate(void)
Definition: gwendate.c:245
int GWEN_Date_toDb(const GWEN_DATE *dt, GWEN_DB_NODE *db)
Definition: gwendate.c:800
GWEN_DATE * GWEN_Date_fromTime(const GWEN_TIME *ti)
Definition: gwendate.c:463
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
void GWEN_Date__fillTmplChars(const GWEN_DATE *t, GWEN_DATE_TMPLCHAR_LIST *ll)
Definition: gwendate.c:672
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
GWENHYWFAR_API int GWEN_Time_toString(const GWEN_TIME *t, const char *tmpl, GWEN_BUFFER *buf)
Definition: gwentime_all.c:830
int GWEN_Date_DaysInYear(const GWEN_DATE *gd)
Definition: gwendate.c:369
static int _daysInMonth(int month, int year)
Definition: gwendate.c:354
GWEN_DATE * GWEN_Date_GetThisYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:956
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
GWEN_DATE * GWEN_Date_GetLastHalfYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:1032
void GWEN_Date_free(GWEN_DATE *gd)
Definition: gwendate.c:330
GWEN_DATE * GWEN_Date_GetThisMonthStart(const GWEN_DATE *dt)
Definition: gwendate.c:836
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_GetLastMonthEnd(const GWEN_DATE *dt)
Definition: gwendate.c:980
#define GWEN_ERROR_GENERIC
Definition: error.h:62
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_Date_DaysInMonth(const GWEN_DATE *gd)
Definition: gwendate.c:347
GWEN_DATE * GWEN_Date_fromGregorian(int y, int m, int d)
Definition: gwendate.c:54
int GWEN_Date_GetMonth(const GWEN_DATE *gd)
Definition: gwendate.c:393
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWEN_DATE * GWEN_Date_GetThisYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:949
void GWEN_Date_AddDays(GWEN_DATE *gd, int days)
Definition: gwendate.c:160
GWEN_DATE * GWEN_Date_GetThisHalfYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:939
const char * GWEN_Date_GetString(const GWEN_DATE *gd)
Definition: gwendate.c:425
GWEN_DATE * GWEN_Date_fromLocalTime(time_t t)
Definition: gwendate.c:185
GWEN_DATE * GWEN_Date_GetThisQuarterYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:881
GWEN_DATE * GWEN_Date_GetLastYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:1058
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
static void _writeAsString(GWEN_DATE *gd)
Definition: gwendate.c:131
GWEN_DATE * GWEN_Date_GetLastYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:1045
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
static GWEN_DATE * _createFromGregorianAndUseGivenString(int y, int m, int d, const char *s)
Definition: gwendate.c:63
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
int GWEN_Date_GetJulian(const GWEN_DATE *gd)
Definition: gwendate.c:409
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
GWEN_DATE * GWEN_Date_fromGmTime(time_t t)
Definition: gwendate.c:227
GWEN_DATE * GWEN_Date_GetLastQuarterYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:1006
int GWEN_Date_IsLeapYear(int y)
Definition: gwendate.c:339
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
GWEN_DATE * GWEN_Date_GetThisQuarterYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:905
GWEN_DATE * GWEN_Date_GetThisHalfYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:929
int GWEN_Date_GetDay(const GWEN_DATE *gd)
Definition: gwendate.c:401
GWEN_DATE * GWEN_Date_fromJulian(int julian)
Definition: gwendate.c:174
int GWEN_Date_GetYear(const GWEN_DATE *gd)
Definition: gwendate.c:385
GWEN_DATE_TMPLCHAR * GWEN_Date__findTmplChar(GWEN_DATE_TMPLCHAR_LIST *ll, char c)
Definition: gwendate.c:625
int GWEN_Date_Diff(const GWEN_DATE *gd1, const GWEN_DATE *gd0)
Definition: gwendate.c:453
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
void GWEN_Date_setJulian(GWEN_DATE *gd, int julian)
Definition: gwendate.c:99
int GWEN_Date_Compare(const GWEN_DATE *gd1, const GWEN_DATE *gd0)
Definition: gwendate.c:433
GWEN_DATE * GWEN_Date_GetLastQuarterYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:993
#define GWEN_UNUSED
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
struct GWEN_DATE GWEN_DATE
Definition: gwendate.h:34