TPCCLIB
Loading...
Searching...
No Matches
datetime.c File Reference

Data and time processing functions. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <locale.h>
#include <ctype.h>
#include <unistd.h>
#include <math.h>
#include "tpcextensions.h"

Go to the source code of this file.

Functions

struct tm * gmtime_r (const time_t *t, struct tm *tm)
 Convert time_t to GMT struct tm.
 
struct tm * localtime_r (const time_t *t, struct tm *tm)
 Convert time_t to local time in struct tm.
 
time_t timegm (struct tm *tm)
 Inverse of gmtime, converting struct tm to time_t.
 
char * ctime_r_int (const time_t *t, char *buf)
 Convert calendar time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss, with length of 19 characters and the null.
 
int strDateValid (const char *str)
 
int strDateValid2 (const char *str, char *intdate)
 
int strDateValid3 (const char *str, char *intdate)
 
int strDateValid4 (int dateint, char *intdate, int *year, int *month, int *day)
 
int strTimeValid (const char *str)
 
int strDateTimeValid (const char *str, char *intdate)
 
int strDateTimeRead (const char *str, struct tm *date)
 
int strDateRead (const char *str, struct tm *date)
 
void time_to_tm (time_t totalsecs, int offset, struct tm *result)
 
double tmDifference (struct tm *tm1, struct tm *tm0)
 
void tmAdd (int s, struct tm *d)
 
double strDateTimeDifference (const char *dt1, const char *dt0)
 
int strDateTimeAdd (int s, char *dt)
 

Detailed Description

Data and time processing functions.

Todo
Use strptime function, when available, to convert string to struct tm.

Definition in file datetime.c.

Function Documentation

◆ ctime_r_int()

char * ctime_r_int ( const time_t * t,
char * buf )

Convert calendar time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss, with length of 19 characters and the null.

This is a replacement of the thread-safe ctime_r function which converts to date and time in English format.

Author
Vesa Oikonen
Returns
Returns pointer to the string, or null in case of an error.
See also
time_to_tm, strDateTimeValid, strDateTimeRead
Parameters
tPointer to calendar time ; do not give pointer to int here, like &e7mhdr.scan_start_time
bufPointer to string where the date and time will be written. It must be pre-allocated for at least 20 characters.

Definition at line 119 of file datetime.c.

125 {
126 if(buf==NULL) return(NULL);
127 buf[0]=(char)0;
128 struct tm tm;
129 if(!gmtime_r(t, &tm)) return(NULL);
130 if(!strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &tm)) return(NULL);
131 return(buf);
132}
struct tm * gmtime_r(const time_t *t, struct tm *tm)
Convert time_t to GMT struct tm.
Definition datetime.c:31

Referenced by parWriteRES().

◆ gmtime_r()

struct tm * gmtime_r ( const time_t * t,
struct tm * tm )

Convert time_t to GMT struct tm.

This version of gmtime_r function is here for systems (at least Windows) where it is not defined. Uses gmtime, which is threadsafe in Windows.

See also
localtime_r
Returns
Pointer to struct tm, or null in case of an error.
Parameters
tPointer to time_t; do not give pointer to int here, like &e7mhdr.scan_start_time
tmPointer to struct tm, to be filled here.

Definition at line 31 of file datetime.c.

36 {
37 struct tm *ltm=gmtime(t);
38 if(ltm==NULL || tm==NULL) return(NULL);
39 *tm=*ltm; tm->tm_isdst=-1;
40 return tm;
41}

Referenced by ctime_r_int(), tacReadGEMS(), and timegm().

◆ localtime_r()

struct tm * localtime_r ( const time_t * t,
struct tm * tm )

Convert time_t to local time in struct tm.

This version of localtime_r function is here for systems (at least Windows) where it is not defined. Uses localtime, which is threadsafe in Windows.

See also
gmtime_r
Returns
Pointer to struct tm, or null in case of an error.
Parameters
tPointer to time_t; do not give pointer to int here, like &e7mhdr.scan_start_time
tmPointer to struct tm, to be filled here.

Definition at line 54 of file datetime.c.

59 {
60 struct tm *ltm=localtime(t);
61 if(ltm==NULL || tm==NULL) return(NULL);
62 *tm=*ltm; tm->tm_isdst=-1;
63 return tm;
64}

Referenced by tacReadScanditronics().

◆ strDateRead()

int strDateRead ( const char * str,
struct tm * date )

Reads date from a standard string representation of date.

Returns
0 when successful, <>0 in case of an error.
See also
strDateTimeRead, strDateTimeValid, ctime_r_int
Author
Vesa Oikonen
Parameters
strPointer to string that contains date in one of the formats YYYY-MM-DD, DD/MM/YYYY, DD.MM.YYYY, DD/MM/YY, or DD.MM.YYYY.
datePointer to allocated struct tm where the date is written; undefined if date is not valid.

Definition at line 378 of file datetime.c.

385 {
386 char buf[32];
387 int ret, n, YYYY=0, MM=0, DD=0;
388
389 if(strnlen(str, 10)<8) return 1;
390 if((ret=strDateValid(str))<=0) {
391 strlcpy(buf, str, 11);
392 } else {
393 ret=strDateValid2(str, buf);
394 if(ret>0) ret=strDateValid3(str, buf);
395 }
396 if(ret>0) return 2;
397 n=sscanf(buf, "%d-%d-%d", &YYYY, &MM, &DD);
398 if(n!=3) return(3);
399 date->tm_year=YYYY-1900; date->tm_mday=DD; date->tm_mon=MM-1;
400 date->tm_hour=0; date->tm_min=0; date->tm_sec=0; date->tm_isdst=-1;
401 ret=strftime(buf, 32, "%Y-%m-%d %H:%M:%S", date);
402 if(ret==0) return(4);
403 return(0);
404}
int strDateValid3(const char *str, char *intdate)
Definition datetime.c:214
int strDateValid(const char *str)
Definition datetime.c:155
int strDateValid2(const char *str, char *intdate)
Definition datetime.c:179
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632

Referenced by tacReadGEMS(), and tacReadScanditronics().

◆ strDateTimeAdd()

int strDateTimeAdd ( int s,
char * dt )

Add given time in seconds to the date and time.

Returns
0 if successful.
See also
tmAdd, tmDifference, time_to_tm, strDateTimeDifference
Parameters
sTime to add in seconds; can be negative.
dtPointer to date and time string, edited here. It must be allocated for at least 20 characters.

Definition at line 537 of file datetime.c.

543 {
544 if(dt==NULL) return(1);
545 struct tm tm0;
546 if(strDateTimeRead(dt, &tm0)) return(1);
547 if(s==0) return(0);
548 tmAdd(s, &tm0);
549 if(!strftime(dt, 20, "%Y-%m-%d %H:%M:%S", &tm0)) return(2);
550 return(0);
551}
int strDateTimeRead(const char *str, struct tm *date)
Definition datetime.c:350
void tmAdd(int s, struct tm *d)
Definition datetime.c:500

◆ strDateTimeDifference()

double strDateTimeDifference ( const char * dt1,
const char * dt0 )

Calculate the difference in seconds between two dates and times in international date and time string format (YYYY-MM-DD hh:mm:ss).

See also
tmDifference, strDateTimeAdd, strDateTimeRead, strDateTimeValid, ctime_r_int
Returns
Returns dt1-dt0 time difference in seconds.
Parameters
dt1Pointer to date and time string.
dt0Pointer to date and time string.

Definition at line 519 of file datetime.c.

524 {
525 if(dt1==NULL || dt0==NULL) return(0.0);
526 struct tm tm1, tm0;
527 if(strDateTimeRead(dt1, &tm1) || strDateTimeRead(dt0, &tm0)) return(0.0);
528 return(tmDifference(&tm1, &tm0));
529}
double tmDifference(struct tm *tm1, struct tm *tm0)
Definition datetime.c:486

Referenced by dcmMListRead(), and imgReadDICOM().

◆ strDateTimeRead()

int strDateTimeRead ( const char * str,
struct tm * date )

Reads time and date from a standard string representation of date and time.

Returns
0 when successful, <>0 in case of an error.
See also
strDateRead, strDateTimeValid, ctime_r_int, tmDifference, strClean
Author
Vesa Oikonen
Parameters
strPointer to string that contains date and time in one of the formats YYYY-MM-DD hh:mm:ss, DD.MM.YYYY hh:mm:ss, or DD/MM/YY hh:mm:ss
datePointer to allocated struct tm where date and time is written. undefined if date or time is not valid.

Definition at line 350 of file datetime.c.

357 {
358 char buf[32];
359 int ret, n, YYYY=0, MM=0, DD=0, hh=0, mm=0, ss=0;
360
361 ret=strDateTimeValid(str, buf); if(ret!=0) return(ret);
362 n=sscanf(buf, "%d-%d-%d %d:%d:%d", &YYYY, &MM, &DD, &hh, &mm, &ss);
363 if(n!=6) return(40);
364 date->tm_year=YYYY-1900; date->tm_mday=DD; date->tm_mon=MM-1;
365 date->tm_hour=hh; date->tm_min=mm; date->tm_sec=ss; date->tm_isdst=-1;
366 ret=strftime(buf, 32, "%Y-%m-%d %H:%M:%S", date);
367 if(ret==0) return(50);
368 return(0);
369}
int strDateTimeValid(const char *str, char *intdate)
Definition datetime.c:308

Referenced by abssWrite(), strDateTimeAdd(), strDateTimeDifference(), tacReadAllogg(), tacReadGEMS(), and tacReadScanditronics().

◆ strDateTimeValid()

int strDateTimeValid ( const char * str,
char * intdate )

Verify that specified string contains date and time in correct format (YYYY-MM-DD hh:mm:ss, DD.MM.YYYY hh:mm:ss, D.M.YYYY hh:mm:ss, DD.MM.YY hh:mm:ss, or D.M.YY hh:mm:ss). String must start with date, but any contents after time is ignored.

Returns
0 if date and time are in correct format, <0 if format is correct but date or time is invalid, and otherwise >0.
Author
Vesa Oikonen
See also
strDateTimeRead, strTimeValid, strDateValid, strClean
Parameters
strString to be verified.
intdatePointer to preallocated string where date and time is written in international format (YYYY-MM-DD hh:mm:ss); enter NULL, if not needed. Undefined, if date is not valid.

Definition at line 308 of file datetime.c.

315 {
316 int ret1, ret2, len;
317 char correct_date[20], *time_ptr=NULL, tmp[20];
318
319 if(str==NULL) return 1;
320 // 1/1/70 00:00:00 or 1970-01-01 00:00:00
321 if(strnlen(str, 19)<15) return 1;
322 /* Separate date and time */
323 len=strcspn(str, " \t");
324 if(len<6 || len>10) return 1;
325 strlcpy(tmp, str, len+1); time_ptr=(char*)str+len+1;
326 /* and check the date */
327 correct_date[0]=(char)0;
328 if((ret1=strDateValid(tmp))<=0) {strlcpy(correct_date, tmp, 20);}
329 else if((ret1=strDateValid2(tmp, correct_date))<=0) {}
330 else if((ret1=strDateValid3(tmp, correct_date))<=0) {}
331 else {return 2;}
332
333 /* the check the time */
334 ret2=strTimeValid(time_ptr);
335 if(ret1>0) {if(ret2>=0) return(100*ret1+ret2); else return(100*ret2);}
336 if(ret2>0) return(10*ret2);
337 if(ret1<0) {if(ret2<0) return(-3); else return(-1);}
338 if(ret2<0) return(-2);
339 if(intdate!=NULL) sprintf(intdate, "%10.10s %8.8s", correct_date, time_ptr);
340 return 0;
341}
int strTimeValid(const char *str)
Definition datetime.c:284

Referenced by dcmDT2intl(), strDateTimeRead(), tacReadOldAllogg(), and tacReadSIF().

◆ strDateValid()

int strDateValid ( const char * str)

Verify that specified string contains date in correct international format (YYYY-MM-DD). String must start with date, but any contents after it is ignored.

Returns
0 if date is in correct format, -1 if format is correct but date is invalid, and otherwise >0.
Author
Vesa Oikonen
See also
ctime_r_int, strDateValid2, strDateValid3, strDateValid4, strDateTimeValid, strClean
Parameters
strString to be verified.

Definition at line 155 of file datetime.c.

158 {
159 if(str==NULL || strnlen(str, 10)<10) return 1;
160 if(str[4]!='-' || str[7]!='-') return 2;
161 if(strncasecmp(str, "YYYY-MM-DD", 10)==0) return -1;
162 int Y, M, D, n;
163 n=sscanf(str, "%4d-%2d-%2d", &Y, &M, &D); if(n!=3) return 3;
164 if(M>12 || D>31) return -1;
165 if(Y<0 || M<1 || D<1) return -1;
166 return 0;
167}

Referenced by dcmDA2intl(), strDateRead(), and strDateTimeValid().

◆ strDateValid2()

int strDateValid2 ( const char * str,
char * intdate )

Verify that specified string contains date in correct format (DD.MM.YYYY, D.M.YYYY, DD/MM/YYYY, or D/M/YYYY). String must start with date, but any contents after it is ignored.

Returns
0 if date is in correct format, -1 if format is correct but date is invalid, and otherwise >0.
Author
Vesa Oikonen
See also
ctime_r_int, strDateValid, strDateValid3, strDateValid4, strDateTimeValid
Parameters
strString to be verified.
intdatePointer to preallocated string where date is written in international format; enter NULL, if not needed. Undefined, if date is not valid.

Definition at line 179 of file datetime.c.

185 {
186 if(str==NULL || strnlen(str, 10)<8) return 1;
187 int n; char *cptr;
188 cptr=(char*)str; n=strcspn(cptr, "./"); if(n<1 || n>2) return 2;
189 cptr+=n+1; n=strcspn(cptr, "./"); if(n<1 || n>2) return 2;
190 cptr+=n+1; n=strcspn(cptr, "./- \t\n\r"); if(n!=4) return 2;
191 if(strncasecmp(str, "DD.MM.YYYY", 10)==0 || strncasecmp(str, "DD/MM/YYYY", 10)==0) {
192 return -1;
193 }
194 int Y, M, D;
195 n=sscanf(str, "%d/%d/%4d", &D, &M, &Y);
196 if(n<3) n=sscanf(str, "%d.%d.%4d", &D, &M, &Y);
197 if(n!=3) return 3;
198 if(M>12 || D>31) return -1;
199 if(Y<0 || M<1 || D<1) return -1;
200 if(intdate!=NULL) sprintf(intdate, "%04d-%02d-%02d", Y, M, D);
201 return 0;
202}

Referenced by strDateRead(), and strDateTimeValid().

◆ strDateValid3()

int strDateValid3 ( const char * str,
char * intdate )

Verify that specified string contains date in correct format (DD.MM.YY, D.M.YY, DD/MM/YY, or D/M/YY). String must start with date, but any contents after it is ignored.

Returns
0 if date is in correct format, -1 if format is correct but date is invalid, and otherwise >0.
Author
Vesa Oikonen
See also
ctime_r_int, strDateValid2, strDateValid, strDateValid4, strDateTimeValid
Parameters
strString to be verified.
intdatePointer to allocated string where date is written in international format; enter NULL, if not needed. Undefined, if date is not valid.

Definition at line 214 of file datetime.c.

220 {
221 if(str==NULL || strnlen(str, 8)<6) return 1;
222 int n; char *cptr;
223 cptr=(char*)str; n=strcspn(cptr, "./"); if(n<1 || n>2) return 2;
224 cptr+=n+1; n=strcspn(cptr, "./"); if(n<1 || n>2) return 2;
225 cptr+=n+1; n=strcspn(cptr, "./- \t\n\r"); if(n!=2) return 2;
226 if(strncasecmp(str, "DD.MM.YY", 8)==0 || strncasecmp(str, "DD/MM/YY", 8)==0) {
227 return -1;
228 }
229 int Y, M, D;
230 n=sscanf(str, "%d/%d/%2d", &D, &M, &Y);
231 if(n<3) n=sscanf(str, "%d.%d.%2d", &D, &M, &Y);
232 if(n!=3) return 3;
233 if(Y>99 || M>12 || D>31) return -1;
234 if(Y<0 || M<1 || D<1) return -1;
235 if(intdate!=NULL) {
236 if(Y>=70) Y+=1900; else Y+=2000;
237 sprintf(intdate, "%04d-%02d-%02d", Y, M, D);
238 }
239 return 0;
240}

Referenced by strDateRead(), and strDateTimeValid().

◆ strDateValid4()

int strDateValid4 ( int dateint,
char * intdate,
int * year,
int * month,
int * day )

Verify that specified integer contains date in format YYYYMMDD.

Returns
0 if date is in correct format, -1 if format is correct but date is invalid, and otherwise >0.
Author
Vesa Oikonen
See also
ctime_r_int, strDateValid2, strDateValid3, strDateValid, strDateTimeValid
Parameters
dateintInteger to be checked; not changed in this routine.
intdatePointer to allocated string where date is written in international format; enter NULL, if not needed. Undefined, if date is not valid.
yearYear is written in this pointer; enter NULL if not needed.
monthMonth is written in this pointer; enter NULL if not needed.
dayDay is written in this pointer; enter NULL if not needed.

Definition at line 250 of file datetime.c.

262 {
263 if(dateint<18000101 || dateint>99991231) return 1;
264 int Y, M, D, n;
265 n=dateint/100; D=dateint-100*n; Y=n/100; M=n-100*Y;
266 if(M>12 || D>31) return -1;
267 if(Y<1 || M<1 || D<1) return -1;
268 if(year!=NULL) *year=Y;
269 if(month!=NULL) *month=M;
270 if(day!=NULL) *day=D;
271 if(intdate!=NULL) {sprintf(intdate, "%04d-%02d-%02d", Y, M, D);}
272 return 0;
273}

◆ strTimeValid()

int strTimeValid ( const char * str)

Verify that specified string contains time in correct format (hh:mm:ss). String must start with time, but any contents after it is ignored.

Returns
0 if time is in correct format, -1 if format is correct but time is invalid, and otherwise >0.
Author
Vesa Oikonen
See also
strDateTimeRead, strDateTimeValid, strDateValid
Parameters
strString to be verified.

Definition at line 284 of file datetime.c.

287 {
288 if(str==NULL || strnlen(str, 8)<8) return 1;
289 if(str[2]!=':' || str[5]!=':') return 2;
290 if(strncasecmp(str, "hh:mm:ss", 8)==0) return -1;
291 int h, m, s, n;
292 n=sscanf(str, "%d:%d:%d", &h, &m, &s); if(n!=3) return 3;
293 if(h<0 || h>23 || m<0 || m>59 || s<0 || s>59) return -1;
294 return 0;
295}

Referenced by dcmTM2intl(), iftPutFromString(), and strDateTimeValid().

◆ time_to_tm()

void time_to_tm ( time_t totalsecs,
int offset,
struct tm * result )

Convert calendar time to local broken-down time.

This function is copied from GNU C Library with tiny modifications.

See also
ctime_r_int, tmDifference, tmAdd
Parameters
totalsecsnumber of seconds elapsed since 00:00:00 on January 1, 1970, UTC; can be negative to represent times before 1970.
offsetoffset seconds adding to totalsecs (e.g. -timezone).
resultpointer to struct tm variable to receive broken-down time.

Definition at line 443 of file datetime.c.

451 {
452 long int days, rem, y, yg;
453 const unsigned short *ip;
454
455 days=totalsecs/86400; rem=totalsecs%86400; rem+=offset;
456 while(rem<0) {rem+=86400; --days;}
457 while(rem>=86400) {rem-=86400; ++days;}
458 result->tm_hour=rem/3600;
459 rem%=3600; result->tm_min=rem/60;
460 result->tm_sec=rem%60;
461
462 /* January 1, 1970 was a Thursday. */
463 result->tm_wday=(4+days)%7;
464 if(result->tm_wday<0) result->tm_wday+=7;
465 y=1970;
466 while(days<0 || days>=(isleapyear(y)?366:365)) {
467 /* Guess a corrected year, assuming 365 days per year. */
468 yg=y+math_div(days, 365);
469 /* Adjust days and y to match the guessed year. */
470 days-=(yg-y)*365 + leaps_between(y, yg);
471 y=yg;
472 }
473 result->tm_year=y-1900; result->tm_yday=days;
474 ip=__mon_yday[isleapyear(y)];
475 for(y=11; days<ip[y]; y--) continue;
476 days-=ip[y]; result->tm_mon=y; result->tm_mday=days+1;
477 result->tm_isdst=-1;
478}

◆ timegm()

time_t timegm ( struct tm * tm)

Inverse of gmtime, converting struct tm to time_t.

Otherwise same as mktime, except that mktime uses local time. Uses gmtime_r or gmtime_s, if available, otherwise gmtime, which is thread-safe in Windows.

See also
gmtime_r, localtime_r
Returns
Returns the time_t, or -1 in case of an error.
Parameters
tmPointer to struct tm.

Definition at line 77 of file datetime.c.

80 {
81#ifdef HAVE_GMTIME_R
82 {
83 time_t temp_lt;
84 struct tm temp_gm;
85 if(!tm) temp_lt=0; else temp_lt=mktime(tm);
86 if(gmtime_r(&temp_lt, &temp_gm)==NULL) return((time_t)-1);
87 return(time_t)(temp_lt + (temp_lt - mktime(&temp_gm)));
88 }
89#endif
90
91#ifdef HAVE_GMTIME_S
92 {
93 time_t temp_lt;
94 struct tm temp_gm;
95 if(!tm) temp_lt=0; else temp_lt=mktime(tm);
96 if(gmtime_s(&temp_gm, &temp_lt)!=0) return(time_t)-1);
97 return(time_t)(temp_lt + (temp_lt - mktime(&temp_gm)));
98 }
99#endif
100
101 time_t temp_lt;
102 struct tm *temp_gm;
103 if(!tm) temp_lt=0; else {tm->tm_isdst=-1; temp_lt=mktime(tm);}
104 temp_gm=gmtime(&temp_lt); if(temp_gm) temp_gm->tm_isdst=-1;
105 return(time_t)(temp_lt + (temp_lt - mktime(temp_gm)));
106}

Referenced by tmAdd().

◆ tmAdd()

void tmAdd ( int s,
struct tm * d )

Add given time in seconds to the date and time.

See also
tmDifference, time_to_tm, strDateTimeAdd, strDateTimeDifference
Parameters
sTime to add in seconds; can be negative.
dPointer to tm structure.

Definition at line 500 of file datetime.c.

505 {
506 if(d==NULL) return;
507 d->tm_sec+=s;
508 //mktime(d); // this automatically normalizes sec to hours etc if necessary
509 timegm(d); // this automatically normalizes sec to hours etc if necessary
510}
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
Definition datetime.c:77

Referenced by abssWrite(), and strDateTimeAdd().

◆ tmDifference()

double tmDifference ( struct tm * tm1,
struct tm * tm0 )

Calculate the difference in seconds between two given dates and times.

See also
strDateTimeDifference, tmAdd, time_to_tm
Returns
Returns tm1-tm0 in seconds.
Parameters
tm1Pointer to tm structure.
tm0Pointer to tm structure.

Definition at line 486 of file datetime.c.

491 {
492 return(difftime(mktime(tm1), mktime(tm0)));
493}

Referenced by strDateTimeDifference().