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 
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 
50 
51 
52 
53 GWEN_DATE *GWEN_Date_fromGregorian(int y, int m, int d)
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. */
62 GWEN_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
85  _writeAsString(gd);
86 
87  return gd;
88 }
89 
90 
91 
92 void 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 
153 void GWEN_Date_AddDays(GWEN_DATE *gd, int days)
154 {
155  GWEN_Date_setJulian(gd, gd->julian+days);
156 }
157 
158 
159 
160 void 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) {
326  GWEN_FREE_OBJECT(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 
409 const char *GWEN_Date_GetString(const GWEN_DATE *gd)
410 {
411  assert(gd);
412  return gd->asString;
413 }
414 
415 
416 
417 int 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 
437 int 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 
463 GWEN_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 
564 GWEN_LIST_FUNCTIONS(GWEN_DATE_TMPLCHAR, GWEN_DateTmplChar)
565 
566 
567 GWEN_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 
598 void GWEN_DateTmplChar_free(GWEN_DATE_TMPLCHAR *e)
599 {
600  if (e) {
601  free(e->content);
602  GWEN_LIST_FINI(GWEN_DATE_TMPLCHAR, e);
603  GWEN_FREE_OBJECT(e);
604  }
605 }
606 
607 
608 
609 GWEN_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 
626 void 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 */
640  e=GWEN_DateTmplChar_new(*s);
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 
656 void 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':
714  v=GWEN_Date_WeekDay(t);
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 
742 int 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) {
769  GWEN_Buffer_AppendByte(buf, c);
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);
789  s=GWEN_Date_GetString(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 
804  dt=GWEN_Date_fromString(s);
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 
821 {
823 }
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:
872  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 1, 1);
873  case 1:
874  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 4, 1);
875  case 2:
876  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 7, 1);
877  case 3:
878  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 10, 1);
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:
896  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 3, 31);
897  case 1:
898  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 6, 30);
899  case 2:
900  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 9, 30);
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)
916  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 1, 1);
917  else
918  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 7, 1);
919 }
920 
921 
922 
924 {
925  if (GWEN_Date_GetMonth(dt)<7)
926  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 6, 30);
927  else
928  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 12, 31);
929 }
930 
931 
932 
934 {
935  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 1, 1);
936 }
937 
938 
939 
941 {
942  return GWEN_Date_fromGregorian(GWEN_Date_GetYear(dt), 12, 31);
943 }
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);
957  result=GWEN_Date_fromGregorian(GWEN_Date_GetYear(tmpDate), GWEN_Date_GetMonth(tmpDate), 1);
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 
1021  tmpDate=GWEN_Date_GetThisHalfYearStart(dt);
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 
GWEN_DATE * GWEN_Date_fromDb(GWEN_DB_NODE *db)
Definition: gwendate.c:796
struct GWEN_TIME GWEN_TIME
Definition: gwentime.h:43
void GWEN_Date_SubDays(GWEN_DATE *gd, int days)
Definition: gwendate.c:160
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:269
GWEN_DATE * GWEN_Date_dup(const GWEN_DATE *ogd)
Definition: gwendate.c:248
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
GWEN_DATE * GWEN_Date_GetLastHalfYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:1003
GWEN_DATE * GWEN_Date_fromStringWithTemplate(const char *s, const char *tmpl)
Definition: gwendate.c:463
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
GWEN_DATE_TMPLCHAR * GWEN_DateTmplChar_new(char c)
Definition: gwendate.c:567
GWEN_DATE * GWEN_Date_GetLastMonthStart(const GWEN_DATE *dt)
Definition: gwendate.c:947
static const uint8_t daysInMonth[12]
Definition: gwendate.c:42
int GWEN_Date_WeekDay(const GWEN_DATE *gd)
Definition: gwendate.c:401
#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:195
GWEN_DATE * GWEN_Date_GetThisMonthEnd(const GWEN_DATE *dt)
Definition: gwendate.c:827
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:217
int GWEN_Date_toStringWithTemplate(const GWEN_DATE *t, const char *tmpl, GWEN_BUFFER *buf)
Definition: gwendate.c:742
void GWEN_DateTmplChar_free(GWEN_DATE_TMPLCHAR *e)
Definition: gwendate.c:598
GWEN_DATE * GWEN_Date_CurrentDate(void)
Definition: gwendate.c:238
int GWEN_Date_toDb(const GWEN_DATE *dt, GWEN_DB_NODE *db)
Definition: gwendate.c:784
GWEN_DATE * GWEN_Date_fromTime(const GWEN_TIME *ti)
Definition: gwendate.c:447
#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:656
#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:353
GWEN_DATE * GWEN_Date_GetThisYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:940
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:209
GWEN_DATE * GWEN_Date_GetLastHalfYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:1016
void GWEN_Date_free(GWEN_DATE *gd)
Definition: gwendate.c:323
GWEN_DATE * GWEN_Date_GetThisMonthStart(const GWEN_DATE *dt)
Definition: gwendate.c:820
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_GetLastMonthEnd(const GWEN_DATE *dt)
Definition: gwendate.c:964
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:340
GWEN_DATE * GWEN_Date_fromGregorian(int y, int m, int d)
Definition: gwendate.c:53
int GWEN_Date_GetMonth(const GWEN_DATE *gd)
Definition: gwendate.c:377
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:933
void GWEN_Date_AddDays(GWEN_DATE *gd, int days)
Definition: gwendate.c:153
GWEN_DATE * GWEN_Date_GetThisHalfYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:923
const char * GWEN_Date_GetString(const GWEN_DATE *gd)
Definition: gwendate.c:409
GWEN_DATE * GWEN_Date_fromLocalTime(time_t t)
Definition: gwendate.c:178
GWEN_DATE * GWEN_Date_GetThisQuarterYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:865
GWEN_DATE * GWEN_Date_GetLastYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:1042
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
static void _writeAsString(GWEN_DATE *gd)
Definition: gwendate.c:124
GWEN_DATE * GWEN_Date_GetLastYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:1029
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:62
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
int GWEN_Date_GetJulian(const GWEN_DATE *gd)
Definition: gwendate.c:393
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
GWEN_DATE * GWEN_Date_fromGmTime(time_t t)
Definition: gwendate.c:220
GWEN_DATE * GWEN_Date_GetLastQuarterYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:990
int GWEN_Date_IsLeapYear(int y)
Definition: gwendate.c:332
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
GWEN_DATE * GWEN_Date_GetThisQuarterYearEnd(const GWEN_DATE *dt)
Definition: gwendate.c:889
GWEN_DATE * GWEN_Date_GetThisHalfYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:913
int GWEN_Date_GetDay(const GWEN_DATE *gd)
Definition: gwendate.c:385
GWEN_DATE * GWEN_Date_fromJulian(int julian)
Definition: gwendate.c:167
int GWEN_Date_GetYear(const GWEN_DATE *gd)
Definition: gwendate.c:369
GWEN_DATE_TMPLCHAR * GWEN_Date__findTmplChar(GWEN_DATE_TMPLCHAR_LIST *ll, char c)
Definition: gwendate.c:609
int GWEN_Date_Diff(const GWEN_DATE *gd1, const GWEN_DATE *gd0)
Definition: gwendate.c:437
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
void GWEN_Date_setJulian(GWEN_DATE *gd, int julian)
Definition: gwendate.c:92
int GWEN_Date_Compare(const GWEN_DATE *gd1, const GWEN_DATE *gd0)
Definition: gwendate.c:417
GWEN_DATE * GWEN_Date_GetLastQuarterYearStart(const GWEN_DATE *dt)
Definition: gwendate.c:977
#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