gwenhywfar  5.14.1
timestamp.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Wed Mar 22 2023
3  copyright : (C) 2023 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 #include "./timestamp_p.h"
30 
31 #include <gwenhywfar/misc.h>
32 #include <gwenhywfar/debug.h>
33 
34 
35 
36 /* ------------------------------------------------------------------------------------------------
37  * forward declarations
38  * ------------------------------------------------------------------------------------------------
39  */
40 
41 static int _calcJulian(int y, int m, int d);
42 static void _writeAsString(GWEN_TIMESTAMP *tstamp);
43 static void _setDate(GWEN_TIMESTAMP *tstamp, int year, int month, int day);
44 static void _setTime(GWEN_TIMESTAMP *tstamp, int hour, int minute, int second);
45 static void _setFromInt64(GWEN_TIMESTAMP *tstamp, int64_t i);
46 
47 
48 
49 /* ------------------------------------------------------------------------------------------------
50  * implementations
51  * ------------------------------------------------------------------------------------------------
52  */
53 
54 
55 GWEN_TIMESTAMP *GWEN_Timestamp_new(int year, int month, int day,
56  int hour, int minute, int second)
57 {
58  GWEN_TIMESTAMP *tstamp=NULL;
59 
61  GWEN_Timestamp_SetDateAndTime(tstamp, year, month, day, hour, minute, second);
62  return tstamp;
63 }
64 
65 
66 
68 {
69  if (tstampSrc) {
70  GWEN_TIMESTAMP *tstamp;
71 
73  memmove(tstamp, tstampSrc, sizeof(GWEN_TIMESTAMP));
74  return tstamp;
75  }
76  return NULL;
77 }
78 
79 
80 
82 {
83  if (tstamp) {
84  GWEN_FREE_OBJECT(tstamp);
85  }
86 }
87 
88 
89 
90 const char *GWEN_Timestamp_GetString(const GWEN_TIMESTAMP *tstamp)
91 {
92  return tstamp->asString;
93 }
94 
95 
96 
97 int64_t GWEN_Timestamp_toInt64(const GWEN_TIMESTAMP *tstamp)
98 {
99  int64_t result;
100 
101  result=
102  (tstamp->second)+
103  ((int64_t)(tstamp->minute)*60)+
104  ((int64_t)(tstamp->hour)*60*60)+
105  ((int64_t)(tstamp->julian)*24*60*60);
106 
107  return result;
108 }
109 
110 
111 
113 {
114  GWEN_TIMESTAMP *tstamp=NULL;
115 
117  _setFromInt64(tstamp, i);
118  return tstamp;
119 }
120 
121 
122 
123 void _setFromInt64(GWEN_TIMESTAMP *tstamp, int64_t i)
124 {
125  if (tstamp) {
126  tstamp->second=i%60;
127  i/=60;
128  tstamp->minute=i%60;
129  i/=60;
130  tstamp->hour=i%24;
131  i/=24;
132  GWEN_Timestamp_SetJulianDate(tstamp, i);
133  }
134 }
135 
136 
137 
139 {
140  if (ltm) {
141  GWEN_TIMESTAMP *tstamp;
142 
143  tstamp=GWEN_Timestamp_new(ltm->tm_year+1900, ltm->tm_mon+1, ltm->tm_mday,
144  ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
145  return tstamp;
146  }
147 
148  return NULL;
149 }
150 
151 
152 
154 {
155  return GWEN_Timestamp_fromStructTm(localtime(&ti));
156 }
157 
158 
159 
161 {
162  return GWEN_Timestamp_fromStructTm(gmtime(&ti));
163 }
164 
165 
166 
168 {
169  struct tm ti;
170  struct tm *tp;
171  time_t tt;
172 
173  tt=time(NULL);
174  tp=localtime(&tt);
175  assert(tp);
176  memmove(&ti, tp, sizeof(ti));
177 
178  ti.tm_sec=tstamp->second;
179  ti.tm_min=tstamp->minute;
180  ti.tm_hour=tstamp->hour;
181 
182  ti.tm_year=tstamp->year-1900;
183  ti.tm_mon=tstamp->month-1;
184  ti.tm_mday=tstamp->day;
185  ti.tm_yday=0;
186  ti.tm_wday=0;
187  tt=mktime(&ti);
188  assert(tt!=(time_t)-1);
189  return tt;
190 }
191 
192 
193 
195 {
196  time_t ti;
197 
198  ti=time(NULL);
199  return GWEN_Timestamp_fromStructTm(localtime(&ti));
200 }
201 
202 
203 
205 {
206  time_t ti;
207 
208  ti=time(NULL);
209  return GWEN_Timestamp_fromStructTm(gmtime(&ti));
210 }
211 
212 
213 
215  int year, int month, int day,
216  int hour, int minute, int second)
217 {
218  _setDate(tstamp, year, month, day);
219  _setTime(tstamp, hour, minute, second);
220  _writeAsString(tstamp);
221 }
222 
223 
224 
225 void GWEN_Timestamp_SetDate(GWEN_TIMESTAMP *tstamp, int year, int month, int day)
226 {
227  _setDate(tstamp, year, month, day);
228  _writeAsString(tstamp);
229 }
230 
231 
232 
234 {
235  int l, n, i, j;
236 
237  l=julian+68569;
238  n=(4*l)/146097;
239  l=l-(146097*n+3)/4;
240  i=(4000*(l+1))/1461001;
241  l=l-(1461*i)/4+31;
242  j=(80*l)/2447;
243 
244  tstamp->day=l-(2447*j)/80;
245  l=j/11;
246  tstamp->month=j+2-(12*l);
247  tstamp->year=100*(n-49)+i+l;
248  tstamp->julian=julian;
249 
250  _writeAsString(tstamp);
251 }
252 
253 
254 
255 void GWEN_Timestamp_SetTime(GWEN_TIMESTAMP *tstamp, int hour, int minute, int second)
256 {
257  _setTime(tstamp, hour, minute, second);
258  _writeAsString(tstamp);
259 }
260 
261 
262 
264 {
265  return tstamp->year;
266 }
267 
268 
269 
271 {
272  return tstamp->month;
273 }
274 
275 
276 
278 {
279  return tstamp->day;
280 }
281 
282 
283 
285 {
286  assert(tstamp);
287  return (tstamp->julian+1)%7; /* 0=Sunday */
288 }
289 
290 
291 
293 {
294  return tstamp->hour;
295 }
296 
297 
298 
300 {
301  return tstamp->minute;
302 }
303 
304 
305 
307 {
308  return tstamp->second;
309 }
310 
311 
312 
313 int GWEN_Timestamp_Compare(const GWEN_TIMESTAMP *tstamp1, const GWEN_TIMESTAMP *tstamp0)
314 {
315  if (tstamp0 && tstamp1) {
316  int64_t v1, v0;
317 
318  v1=GWEN_Timestamp_toInt64(tstamp1);
319  v0=GWEN_Timestamp_toInt64(tstamp0);
320  if (v1==v0)
321  return 0;
322  else if (v1>v0)
323  return 1;
324  else
325  return -1;
326 
327  }
328  else if (tstamp0)
329  return 1;
330  else if (tstamp1)
331  return -1;
332  else
333  return 0;
334 }
335 
336 
337 
338 
339 int _calcJulian(int y, int m, int d)
340 {
341  return (1461*(y+4800+(m-14)/12))/4+
342  (367*(m-2-12*((m-14)/12)))/12-
343  (3*((y+4900+(m-14)/12)/100))/4+
344  d-32075;
345 }
346 
347 
348 
349 void _setDate(GWEN_TIMESTAMP *tstamp, int year, int month, int day)
350 {
351  tstamp->year=year;
352  tstamp->month=month;
353  tstamp->day=day;
354  tstamp->julian=_calcJulian(year, month, day);
355 }
356 
357 
358 
359 void _setTime(GWEN_TIMESTAMP *tstamp, int hour, int minute, int second)
360 {
361  tstamp->hour=hour;
362  tstamp->minute=minute;
363  tstamp->second=second;
364 }
365 
366 
367 
369 {
370  char *ptr;
371  int x;
372 
373  ptr=tstamp->asString+14;
374  *(ptr--)=0;
375 
376  x=tstamp->second;
377  *(ptr--)='0'+(x%10);
378  x/=10;
379  *(ptr--)='0'+(x%10);
380 
381  x=tstamp->minute;
382  *(ptr--)='0'+(x%10);
383  x/=10;
384  *(ptr--)='0'+(x%10);
385 
386  x=tstamp->hour;
387  *(ptr--)='0'+(x%10);
388  x/=10;
389  *(ptr--)='0'+(x%10);
390 
391  x=tstamp->day;
392  *(ptr--)='0'+(x%10);
393  x/=10;
394  *(ptr--)='0'+(x%10);
395 
396  x=tstamp->month;
397  *(ptr--)='0'+(x%10);
398  x/=10;
399  *(ptr--)='0'+(x%10);
400 
401  x=tstamp->year;
402  *(ptr--)='0'+(x%10);
403  x/=10;
404  *(ptr--)='0'+(x%10);
405  x/=10;
406  *(ptr--)='0'+(x%10);
407  x/=10;
408  *ptr='0'+(x%10);
409 }
410 
411 
412 
414 {
415  if (s && strlen(s)>=14) {
416  int year, month, day, hour, min, sec;
417  GWEN_TIMESTAMP *result;
418  const char *originalPtr;
419 
420  originalPtr=s;
421  year=*(s++)-'0';
422  year*=10;
423  year+=*(s++)-'0';
424  year*=10;
425  year+=*(s++)-'0';
426  year*=10;
427  year+=*(s++)-'0';
428 
429  month=*(s++)-'0';
430  month*=10;
431  month+=*(s++)-'0';
432 
433  day=*(s++)-'0';
434  day*=10;
435  day+=*(s++)-'0';
436 
437  hour=*(s++)-'0';
438  hour*=10;
439  hour+=*(s++)-'0';
440 
441  min=*(s++)-'0';
442  min*=10;
443  min+=*(s++)-'0';
444 
445  sec=*(s++)-'0';
446  sec*=10;
447  sec+=*(s++)-'0';
448 
449  result=GWEN_Timestamp_new(year, month, day, hour, min, sec);
450  if (!result) {
451  DBG_INFO(GWEN_LOGDOMAIN, "Bad timestamp string [%s]", originalPtr);
452  }
453  return result;
454  }
455  else {
456  DBG_INFO(GWEN_LOGDOMAIN, "Bad timestamp string [%s]", s?s:"<empty>");
457  return NULL;
458  }
459 }
460 
461 
462 
464 {
465  const char *s;
466 
467  s=GWEN_Timestamp_GetString(tstamp);
469  return 0;
470 }
471 
472 
473 
475 {
476  const char *s;
477 
478  s=GWEN_DB_GetCharValue(db, "timestamp", 0, NULL);
479  if (s && *s) {
480  GWEN_TIMESTAMP *tstamp;
481 
482  tstamp=GWEN_Timestamp_fromString(s);
483  if (tstamp==NULL) {
484  DBG_INFO(GWEN_LOGDOMAIN, "Invalid timestamp [%s]", s);
485  return NULL;
486  }
487  return tstamp;
488  }
489  else {
490  DBG_VERBOUS(GWEN_LOGDOMAIN, "no or empty timestamp");
491  return NULL;
492  }
493 
494 }
495 
496 
497 void GWEN_Timestamp_AddSeconds(GWEN_TIMESTAMP *tstamp, int seconds)
498 {
499  if (tstamp && seconds!=0) {
500  int64_t ti;
501 
502  ti=GWEN_Timestamp_toInt64(tstamp)+seconds;
503  _setFromInt64(tstamp, ti);
504  }
505 }
506 
507 
508 
509 
510 
511 /* include test code */
512 #include "timestamp-t.c"
513 
514 
515 
516 
void GWEN_Timestamp_SetDateAndTime(GWEN_TIMESTAMP *tstamp, int year, int month, int day, int hour, int minute, int second)
Definition: timestamp.c:214
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
int GWEN_Timestamp_GetWeekDay(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:284
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
static void _writeAsString(GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:368
int GWEN_Timestamp_GetMinute(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:299
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
void GWEN_Timestamp_free(GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:81
GWEN_TIMESTAMP * GWEN_Timestamp_fromStructTm(const struct tm *ltm)
Definition: timestamp.c:138
time_t GWEN_Timestamp_toTimeT(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:167
#define GWEN_LOGDOMAIN
Definition: logger.h:32
#define DBG_VERBOUS(dbg_logger, format,...)
Definition: debug.h:224
GWEN_TIMESTAMP * GWEN_Timestamp_dup(const GWEN_TIMESTAMP *tstampSrc)
Definition: timestamp.c:67
int GWEN_Timestamp_toDb(const GWEN_TIMESTAMP *tstamp, GWEN_DB_NODE *db)
Definition: timestamp.c:463
GWEN_TIMESTAMP * GWEN_Timestamp_fromLocalTime(time_t ti)
Definition: timestamp.c:153
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
static void _setFromInt64(GWEN_TIMESTAMP *tstamp, int64_t i)
Definition: timestamp.c:123
void GWEN_Timestamp_SetTime(GWEN_TIMESTAMP *tstamp, int hour, int minute, int second)
Definition: timestamp.c:255
GWEN_TIMESTAMP * GWEN_Timestamp_NowInGmTime()
Definition: timestamp.c:204
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
void GWEN_Timestamp_SetJulianDate(GWEN_TIMESTAMP *tstamp, int julian)
Definition: timestamp.c:233
int GWEN_Timestamp_GetMonth(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:270
GWEN_TIMESTAMP * GWEN_Timestamp_fromString(const char *s)
Definition: timestamp.c:413
int64_t GWEN_Timestamp_toInt64(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:97
int GWEN_Timestamp_GetHour(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:292
GWEN_TIMESTAMP * GWEN_Timestamp_fromDb(GWEN_DB_NODE *db)
Definition: timestamp.c:474
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
GWEN_TIMESTAMP * GWEN_Timestamp_fromGmTime(time_t ti)
Definition: timestamp.c:160
int GWEN_Timestamp_GetDay(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:277
int GWEN_Timestamp_Compare(const GWEN_TIMESTAMP *tstamp1, const GWEN_TIMESTAMP *tstamp0)
Definition: timestamp.c:313
GWEN_TIMESTAMP * GWEN_Timestamp_new(int year, int month, int day, int hour, int minute, int second)
Definition: timestamp.c:55
static void _setTime(GWEN_TIMESTAMP *tstamp, int hour, int minute, int second)
Definition: timestamp.c:359
const char * GWEN_Timestamp_GetString(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:90
int GWEN_Timestamp_GetSecond(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:306
#define DBG_INFO(dbg_logger, format,...)
Definition: debug.h:181
void GWEN_Timestamp_SetDate(GWEN_TIMESTAMP *tstamp, int year, int month, int day)
Definition: timestamp.c:225
static int _calcJulian(int y, int m, int d)
Definition: timestamp.c:339
GWEN_TIMESTAMP * GWEN_Timestamp_NowInLocalTime()
Definition: timestamp.c:194
int GWEN_Timestamp_GetYear(const GWEN_TIMESTAMP *tstamp)
Definition: timestamp.c:263
static void _setDate(GWEN_TIMESTAMP *tstamp, int year, int month, int day)
Definition: timestamp.c:349
void GWEN_Timestamp_AddSeconds(GWEN_TIMESTAMP *tstamp, int seconds)
Definition: timestamp.c:497
GWEN_TIMESTAMP * GWEN_Timestamp_fromInt64(int64_t i)
Definition: timestamp.c:112
struct GWEN_TIMESTAMP GWEN_TIMESTAMP
Definition: timestamp.h:36