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)
double timespecDifference (struct timespec const *ts2, struct timespec const *ts1)

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 108 of file datetime.c.

114 {
115 if(buf==NULL) return(NULL);
116 buf[0]=(char)0;
117 struct tm tm;
118 if(!gmtime_r(t, &tm)) return(NULL);
119 if(!strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &tm)) return(NULL);
120 return(buf);
121}
struct tm * gmtime_r(const time_t *t, struct tm *tm)
Convert time_t to GMT struct tm.
Definition datetime.c:31

Referenced by ctime_r_int(), and 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(), gmtime_r(), 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 in case 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 53 of file datetime.c.

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

Referenced by localtime_r(), and 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 370 of file datetime.c.

377 {
378 char buf[32];
379 int ret, n, YYYY=0, MM=0, DD=0;
380
381 if(strnlen(str, 10)<8) return 1;
382 if((ret=strDateValid(str))<=0) {
383 strlcpy(buf, str, 11);
384 } else {
385 ret=strDateValid2(str, buf);
386 if(ret>0) ret=strDateValid3(str, buf);
387 }
388 if(ret>0) return 2;
389 n=sscanf(buf, "%d-%d-%d", &YYYY, &MM, &DD);
390 if(n!=3) return(3);
391 date->tm_year=YYYY-1900; date->tm_mday=DD; date->tm_mon=MM-1;
392 date->tm_hour=0; date->tm_min=0; date->tm_sec=0; date->tm_isdst=-1;
393 ret=strftime(buf, 32, "%Y-%m-%d %H:%M:%S", date);
394 if(ret==0) return(4);
395 return(0);
396}
int strDateValid3(const char *str, char *intdate)
Definition datetime.c:203
int strDateValid(const char *str)
Definition datetime.c:144
int strDateValid2(const char *str, char *intdate)
Definition datetime.c:168
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:635

Referenced by strDateRead(), 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 529 of file datetime.c.

535 {
536 if(dt==NULL) return(1);
537 struct tm tm0;
538 if(strDateTimeRead(dt, &tm0)) return(1);
539 if(s==0) return(0);
540 tmAdd(s, &tm0);
541 if(!strftime(dt, 20, "%Y-%m-%d %H:%M:%S", &tm0)) return(2);
542 return(0);
543}
int strDateTimeRead(const char *str, struct tm *date)
Definition datetime.c:339
void tmAdd(int s, struct tm *d)
Definition datetime.c:492

Referenced by strDateTimeAdd().

◆ 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 511 of file datetime.c.

516 {
517 if(dt1==NULL || dt0==NULL) return(0.0);
518 struct tm tm1, tm0;
519 if(strDateTimeRead(dt1, &tm1) || strDateTimeRead(dt0, &tm0)) return(0.0);
520 return(tmDifference(&tm1, &tm0));
521}
double tmDifference(struct tm *tm1, struct tm *tm0)
Definition datetime.c:478

Referenced by dcmMListRead(), imgReadDICOM(), and strDateTimeDifference().

◆ 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 339 of file datetime.c.

346 {
347 char buf[32];
348 int ret, n, YYYY=0, MM=0, DD=0, hh=0, mm=0, ss=0;
349
350 ret=strDateTimeValid(str, buf); if(ret!=0) return(ret);
351 n=sscanf(buf, "%d-%d-%d %d:%d:%d", &YYYY, &MM, &DD, &hh, &mm, &ss);
352 if(n!=6) return(40);
353 date->tm_year=YYYY-1900; date->tm_mday=DD; date->tm_mon=MM-1;
354 date->tm_hour=hh; date->tm_min=mm; date->tm_sec=ss; date->tm_isdst=-1;
355#ifdef HAVE_TM_GMTOFF
356 date->tm_gmtoff=0L;
357#endif
358 ret=strftime(buf, 32, "%Y-%m-%d %H:%M:%S", date);
359 if(ret==0) return(50);
360 return(0);
361}
int strDateTimeValid(const char *str, char *intdate)
Definition datetime.c:297

Referenced by abssWrite(), strDateTimeAdd(), strDateTimeDifference(), strDateTimeRead(), 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 297 of file datetime.c.

304 {
305 int ret1, ret2, len;
306 char correct_date[20], *time_ptr=NULL, tmp[20];
307
308 if(str==NULL) return 1;
309 // 1/1/70 00:00:00 or 1970-01-01 00:00:00
310 if(strnlen(str, 19)<15) return 1;
311 /* Separate date and time */
312 len=strcspn(str, " \t");
313 if(len<6 || len>10) return 1;
314 strlcpy(tmp, str, len+1); time_ptr=(char*)str+len+1;
315 /* and check the date */
316 correct_date[0]=(char)0;
317 if((ret1=strDateValid(tmp))<=0) {strlcpy(correct_date, tmp, 20);}
318 else if((ret1=strDateValid2(tmp, correct_date))<=0) {}
319 else if((ret1=strDateValid3(tmp, correct_date))<=0) {}
320 else {return 2;}
321
322 /* the check the time */
323 ret2=strTimeValid(time_ptr);
324 if(ret1>0) {if(ret2>=0) return(100*ret1+ret2); else return(100*ret2);}
325 if(ret2>0) return(10*ret2);
326 if(ret1<0) {if(ret2<0) return(-3); else return(-1);}
327 if(ret2<0) return(-2);
328 if(intdate!=NULL) sprintf(intdate, "%10.10s %8.8s", correct_date, time_ptr);
329 return 0;
330}
int strTimeValid(const char *str)
Definition datetime.c:273

Referenced by dcmDT2intl(), strDateTimeRead(), strDateTimeValid(), 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 144 of file datetime.c.

147 {
148 if(str==NULL || strnlen(str, 10)<10) return 1;
149 if(str[4]!='-' || str[7]!='-') return 2;
150 if(strncasecmp(str, "YYYY-MM-DD", 10)==0) return -1;
151 int Y, M, D, n;
152 n=sscanf(str, "%4d-%2d-%2d", &Y, &M, &D); if(n!=3) return 3;
153 if(M>12 || D>31) return -1;
154 if(Y<0 || M<1 || D<1) return -1;
155 return 0;
156}

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

◆ 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 168 of file datetime.c.

174 {
175 if(str==NULL || strnlen(str, 10)<8) return 1;
176 int n; char *cptr;
177 cptr=(char*)str; n=strcspn(cptr, "./"); if(n<1 || n>2) return 2;
178 cptr+=n+1; n=strcspn(cptr, "./"); if(n<1 || n>2) return 2;
179 cptr+=n+1; n=strcspn(cptr, "./- \t\n\r"); if(n!=4) return 2;
180 if(strncasecmp(str, "DD.MM.YYYY", 10)==0 || strncasecmp(str, "DD/MM/YYYY", 10)==0) {
181 return -1;
182 }
183 int Y, M, D;
184 n=sscanf(str, "%d/%d/%4d", &D, &M, &Y);
185 if(n<3) n=sscanf(str, "%d.%d.%4d", &D, &M, &Y);
186 if(n!=3) return 3;
187 if(M>12 || D>31) return -1;
188 if(Y<0 || M<1 || D<1) return -1;
189 if(intdate!=NULL) sprintf(intdate, "%04d-%02d-%02d", Y, M, D);
190 return 0;
191}

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

◆ 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 203 of file datetime.c.

209 {
210 if(str==NULL || strnlen(str, 8)<6) return 1;
211 int n; char *cptr;
212 cptr=(char*)str; n=strcspn(cptr, "./"); if(n<1 || n>2) return 2;
213 cptr+=n+1; n=strcspn(cptr, "./"); if(n<1 || n>2) return 2;
214 cptr+=n+1; n=strcspn(cptr, "./- \t\n\r"); if(n!=2) return 2;
215 if(strncasecmp(str, "DD.MM.YY", 8)==0 || strncasecmp(str, "DD/MM/YY", 8)==0) {
216 return -1;
217 }
218 int Y, M, D;
219 n=sscanf(str, "%d/%d/%2d", &D, &M, &Y);
220 if(n<3) n=sscanf(str, "%d.%d.%2d", &D, &M, &Y);
221 if(n!=3) return 3;
222 if(Y>99 || M>12 || D>31) return -1;
223 if(Y<0 || M<1 || D<1) return -1;
224 if(intdate!=NULL) {
225 if(Y>=70) Y+=1900; else Y+=2000;
226 sprintf(intdate, "%04d-%02d-%02d", Y, M, D);
227 }
228 return 0;
229}

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

◆ 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 239 of file datetime.c.

251 {
252 if(dateint<18000101 || dateint>99991231) return 1;
253 int Y, M, D, n;
254 n=dateint/100; D=dateint-100*n; Y=n/100; M=n-100*Y;
255 if(M>12 || D>31) return -1;
256 if(Y<1 || M<1 || D<1) return -1;
257 if(year!=NULL) *year=Y;
258 if(month!=NULL) *month=M;
259 if(day!=NULL) *day=D;
260 if(intdate!=NULL) {sprintf(intdate, "%04d-%02d-%02d", Y, M, D);}
261 return 0;
262}

Referenced by strDateValid4().

◆ 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 273 of file datetime.c.

276 {
277 if(str==NULL || strnlen(str, 8)<8) return 1;
278 if(str[2]!=':' || str[5]!=':') return 2;
279 if(strncasecmp(str, "hh:mm:ss", 8)==0) return -1;
280 int h, m, s, n;
281 n=sscanf(str, "%d:%d:%d", &h, &m, &s); if(n!=3) return 3;
282 if(h<0 || h>23 || m<0 || m>59 || s<0 || s>59) return -1;
283 return 0;
284}

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

◆ 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 435 of file datetime.c.

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

Referenced by time_to_tm().

◆ timegm()

time_t timegm ( struct tm * tm)

Inverse of gmtime, converting struct tm to time_t.

timegm() is a non-standard GNU and BSD extension. Otherwise same as mktime, except that mktime uses local time. Uses gmtime_r, 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 76 of file datetime.c.

79 {
80#if defined HAVE_GMTIME_R
81 {
82 time_t temp_lt;
83 struct tm temp_gm;
84 if(!tm) temp_lt=0; else temp_lt=mktime(tm);
85 if(gmtime_r(&temp_lt, &temp_gm)==NULL) return((time_t)-1);
86 return(time_t)(temp_lt + (temp_lt - mktime(&temp_gm)));
87 }
88#else
89 time_t temp_lt;
90 struct tm *temp_gm;
91 if(!tm) temp_lt=0; else {tm->tm_isdst=-1; temp_lt=mktime(tm);}
92 temp_gm=gmtime(&temp_lt); if(temp_gm) temp_gm->tm_isdst=-1;
93 return(time_t)(temp_lt + (temp_lt - mktime(temp_gm)));
94#endif
95}

Referenced by timegm(), and tmAdd().

◆ timespecDifference()

double timespecDifference ( struct timespec const * ts2,
struct timespec const * ts1 )

Calculate the difference between times in two timespec structures.

Returns
The time difference in seconds.
Parameters
ts2Later time.
ts1Earlier time.

Definition at line 550 of file datetime.c.

555 {
556 if(ts1==NULL || ts2==NULL) return(nan(""));
557 if(ts2->tv_sec < ts1->tv_sec)
558 return(-timespecDifference(ts1, ts2));
559 else
560 return((double)(ts2->tv_sec - ts1->tv_sec) + (ts2->tv_nsec - ts1->tv_nsec)*1E-09);
561}
double timespecDifference(struct timespec const *ts2, struct timespec const *ts1)
Definition datetime.c:550

Referenced by timespecDifference().

◆ 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 492 of file datetime.c.

497 {
498 if(d==NULL) return;
499 d->tm_sec+=s;
500 //mktime(d); // this automatically normalizes sec to hours etc if necessary
501 timegm(d); // this automatically normalizes sec to hours etc if necessary
502}
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
Definition datetime.c:76

Referenced by abssWrite(), strDateTimeAdd(), and tmAdd().

◆ 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 478 of file datetime.c.

483 {
484 return(difftime(mktime(tm1), mktime(tm0)));
485}

Referenced by strDateTimeDifference(), and tmDifference().