rllib  1
rltime.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  rltime_v1.cpp - description
3  -------------------
4  begin : Tue Jan 02 2001
5  copyright : (C) 2001 by R. Lehrig
6  email : lehrig@t-online.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
13  * published by the Free Software Foundation *
14  * *
15  ***************************************************************************/
16 #include "rltime.h"
17 #include <stdio.h>
18 #include <string.h>
19 #include <time.h>
20 #include <sys/stat.h>
21 
22 #ifdef RLUNIX
23 #include <sys/types.h>
24 #include <sys/time.h>
25 #include <unistd.h>
26 #endif
27 
28 #ifdef __VMS
29 #include <ssdef.h>
30 #include <iodef.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <starlet.h>
34 #include <descrip.h>
35 #include <lib$routines.h>
36 #include <libdef.h>
37 #include <jpidef.h>
38 typedef struct
39 {
40  short year;
41  short month;
42  short day;
43  short hour;
44  short min;
45  short sec;
46  short hth;
47 }
48 TDS;
49 typedef struct
50 {
51  long word_1;
52  long word_2;
53 }
55 #endif
56 
57 #ifdef RLWIN32
58 #include <windows.h>
59 #include <mmsystem.h>
60 #endif
61 
62 rlTime::rlTime(int Year, int Month, int Day, int Hour, int Minute, int Second, int Millisecond)
63 {
64  year = Year;
65  month = Month;
66  day = Day;
67  hour = Hour;
68  minute = Minute;
69  second = Second;
70  millisecond = Millisecond;
71 }
72 
74 {
75 }
76 
77 const char *rlTime::version()
78 {
79  return __FILE__;
80 }
81 
82 void rlTime::setTimeFromString(const char *time_string)
83 {
84  year = 0;
85  month = 0;
86  day = 0;
87  hour = 0;
88  minute = 0;
89  second = 0;
90  millisecond = 0;
91  sscanf(time_string,"%d-%d-%d %d:%d:%d %d",&year,&month,&day, &hour,&minute,&second, &millisecond);
92 }
93 
94 void rlTime::setTimeFromIsoString(const char *iso_time_string)
95 {
96  year = 0;
97  month = 0;
98  day = 0;
99  hour = 0;
100  minute = 0;
101  second = 0;
102  millisecond = 0;
103  sscanf(iso_time_string,"%d-%d-%dT%d:%d:%d.%d",&year,&month,&day, &hour,&minute,&second, &millisecond);
104 }
105 
107 {
108  sprintf(time_string,"%04d-%02d-%02d %02d:%02d:%02d %03d",year, month, day, hour, minute, second, millisecond);
109  return time_string;
110 }
111 
113 {
114  sprintf(iso_time_string,"%04d-%02d-%02dT%02d:%02d:%02d.%03d",year, month, day, hour, minute, second, millisecond);
115  return iso_time_string;
116 }
117 
156 const char *rlTime::toString(const char *format)
157 {
158  // See:
159  // https://doc.qt.io/qt-5/qdatetime.html#toString
160  //
161  char buf[16];
162  char *dest = time_string;
163  while(*format != '\0')
164  {
165  if (strncmp(format,"dd",2) == 0)
166  {
167  sprintf(buf,"%02d",day);
168  strcpy(dest,buf);
169  dest += strlen(buf);
170  format += 2;
171  }
172  else if(strncmp(format,"d",1) == 0)
173  {
174  sprintf(buf,"%d",day);
175  strcpy(dest,buf);
176  dest += strlen(buf);
177  format += 1;
178  }
179  else if(strncmp(format,"MMM",3) == 0)
180  {
181  buf[0] = '\0';
182  if(month == 1) strcpy(buf,"Jan");
183  if(month == 2) strcpy(buf,"Feb");
184  if(month == 3) strcpy(buf,"Mar");
185  if(month == 4) strcpy(buf,"Apr");
186  if(month == 5) strcpy(buf,"May");
187  if(month == 6) strcpy(buf,"Jun");
188  if(month == 7) strcpy(buf,"Jul");
189  if(month == 8) strcpy(buf,"Aug");
190  if(month == 9) strcpy(buf,"Sep");
191  if(month == 10) strcpy(buf,"Oct");
192  if(month == 11) strcpy(buf,"Nov");
193  if(month == 12) strcpy(buf,"Dec");
194  strcpy(dest,buf);
195  dest += strlen(buf);
196  format += 3;
197  }
198  else if(strncmp(format,"MM",2) == 0)
199  {
200  sprintf(buf,"%02d",month);
201  strcpy(dest,buf);
202  dest += strlen(buf);
203  format += 2;
204  }
205  else if(strncmp(format,"M",1) == 0)
206  {
207  sprintf(buf,"%d",month);
208  strcpy(dest,buf);
209  dest += strlen(buf);
210  format += 1;
211  }
212  else if(strncmp(format,"yyyy",4) == 0)
213  {
214  sprintf(buf,"%4d",year);
215  strcpy(dest,buf);
216  dest += strlen(buf);
217  format += 4;
218  }
219  else if(strncmp(format,"yy",2) == 0)
220  {
221  sprintf(buf,"%4d",year);
222  strcpy(dest,&buf[2]);
223  dest += strlen(&buf[2]);
224  format += 2;
225  }
226  else if(strncmp(format,"hh",2) == 0)
227  {
228  if (hour > 12) sprintf(buf,"%02d", hour - 12);
229  else if(hour == 0) sprintf(buf,"%02d", 12);
230  else sprintf(buf,"%02d", hour);
231  strcpy(dest,buf);
232  dest += strlen(buf);
233  format += 2;
234  }
235  else if(strncmp(format,"h",1) == 0)
236  {
237  if (hour > 12) sprintf(buf,"%2d", hour - 12);
238  else if(hour == 0) sprintf(buf,"%2d", 12);
239  else sprintf(buf,"%2d", hour);
240  strcpy(dest,buf);
241  dest += strlen(buf);
242  format += 1;
243  }
244  else if(strncmp(format,"HH",2) == 0)
245  {
246  sprintf(buf,"%02d",hour);
247  strcpy(dest,buf);
248  dest += strlen(buf);
249  format += 2;
250  }
251  else if(strncmp(format,"H",1) == 0)
252  {
253  sprintf(buf,"%d",hour);
254  strcpy(dest,buf);
255  dest += strlen(buf);
256  format += 1;
257  }
258  else if(strncmp(format,"mm",2) == 0)
259  {
260  sprintf(buf,"%02d",minute);
261  strcpy(dest,buf);
262  dest += strlen(buf);
263  format += 2;
264  }
265  else if(strncmp(format,"m",1) == 0)
266  {
267  sprintf(buf,"%d",minute);
268  strcpy(dest,buf);
269  dest += strlen(buf);
270  format += 1;
271  }
272  else if(strncmp(format,"ss",2) == 0)
273  {
274  sprintf(buf,"%02d",second);
275  strcpy(dest,buf);
276  dest += strlen(buf);
277  format += 2;
278  }
279  else if(strncmp(format,"s",1) == 0)
280  {
281  sprintf(buf,"%d",second);
282  strcpy(dest,buf);
283  dest += strlen(buf);
284  format += 1;
285  }
286  else if(strncmp(format,"zzz",3) == 0)
287  {
288  sprintf(buf,"%03d",millisecond);
289  strcpy(dest,buf);
290  dest += strlen(buf);
291  format += 3;
292  }
293  else if(strncmp(format,"z",1) == 0)
294  {
295  sprintf(buf,"%d",millisecond);
296  strcpy(dest,buf);
297  dest += strlen(buf);
298  format += 1;
299  }
300  else if(strncmp(format,"AP",2) == 0)
301  {
302  if (hour == 0) strcpy(dest,"PM");
303  else if(hour < 13) strcpy(dest,"AM");
304  else strcpy(dest,"PM");
305  dest += strlen("AM");
306  format += 2;
307  }
308  else if(strncmp(format,"ap",2) == 0)
309  {
310  if (hour == 0) strcpy(dest,"pm");
311  else if(hour < 13) strcpy(dest,"am");
312  else strcpy(dest,"pm");
313  dest += strlen("am");
314  format += 2;
315  }
316  else if(strncmp(format,"A",1) == 0)
317  {
318  if (hour == 0) strcpy(dest,"PM");
319  else if(hour < 13) strcpy(dest,"AM");
320  else strcpy(dest,"PM");
321  dest += strlen("AM");
322  format += 1;
323  }
324  else if(strncmp(format,"a",1) == 0)
325  {
326  if (hour == 0) strcpy(dest,"pm");
327  else if(hour < 13) strcpy(dest,"am");
328  else strcpy(dest,"pm");
329  dest += strlen("am");
330  format += 1;
331  }
332  else
333  {
334  *dest++ = *format++;
335  }
336  if(dest - time_string + 6 > (int) sizeof(time_string)) break;
337  }
338  *dest = '\0';
339  return time_string;
340 }
341 
343 {
344 #ifdef RLUNIX
345  time_t t;
346  struct tm *tms;
347  struct timeval tv;
348  struct timezone tz;
349 
350  time(&t);
351  tms = localtime(&t);
352  gettimeofday(&tv, &tz);
353 
354  /* adjust year and month */
355  tms->tm_year += 1900;
356  tms->tm_mon += 1;
357 
358  millisecond = (int)tv.tv_usec / 1000;
359  second = (int)tms->tm_sec;
360  minute = (int)tms->tm_min;
361  hour = (int)tms->tm_hour;
362  day = (int)tms->tm_mday;
363  month = (int)tms->tm_mon;
364  year = (int)tms->tm_year;
365 #endif
366 
367 #ifdef __VMS
368  TDS tds;
369  sys$numtim(&tds, 0);
370  millisecond = (int)tds.hth * 10;
371  second = (int)tds.sec;
372  minute = (int)tds.min;
373  hour = (int)tds.hour;
374  day = (int)tds.day;
375  month = (int)tds.month;
376  year = (int)tds.year;
377 #endif
378 
379 #ifdef RLWIN32
380  SYSTEMTIME st;
381  GetLocalTime(&st);
382  millisecond = st.wMilliseconds;
383  second = st.wSecond;
384  minute = st.wMinute;
385  hour = st.wHour;
386  day = st.wDay;
387  month = st.wMonth;
388  year = st.wYear;
389 #endif
390 }
391 
392 int rlTime::getFileModificationTime(const char *filename)
393 {
394  struct stat statbuf;
395  struct tm *tms;
396 
397 #ifdef RLUNIX
398  if(lstat(filename,&statbuf)) return -1;
399 #else
400  if(stat(filename,&statbuf)) return -1;
401 #endif
402  tms = localtime(&statbuf.st_mtime);
403 
404  /* adjust year and month */
405  tms->tm_year += 1900;
406  tms->tm_mon += 1;
407 
408  millisecond = 0;
409  second = (int)tms->tm_sec;
410  minute = (int)tms->tm_min;
411  hour = (int)tms->tm_hour;
412  day = (int)tms->tm_mday;
413  month = (int)tms->tm_mon;
414  year = (int)tms->tm_year;
415 
416  return 0;
417 }
418 
420 {
421 #ifdef RLUNIX
422  struct timeval tv;
423  struct tm t;
424 
425  t.tm_mday = day;
426  t.tm_mon = month - 1;
427  t.tm_year = year - 1900;
428  t.tm_hour = hour;
429  t.tm_min = minute;
430  t.tm_sec = second;
431  tv.tv_sec = mktime(&t);
432  tv.tv_usec = 1000 * millisecond;
433  settimeofday(&tv,NULL);
434 #endif
435 
436 #ifdef __VMS
437  VAX_BIN_TIME vbt;
438  struct dsc$descriptor_s d_time;
439  char smonth[12][4],buf[64];
440 
441  // Initialize month array
442  memset (smonth , 0, sizeof(smonth));
443  memcpy (smonth [0], "JAN", 3);
444  memcpy (smonth [1], "FEB", 3);
445  memcpy (smonth [2], "MAR", 3);
446  memcpy (smonth [3], "APR", 3);
447  memcpy (smonth [4], "MAY", 3);
448  memcpy (smonth [5], "JUN", 3);
449  memcpy (smonth [6], "JUL", 3);
450  memcpy (smonth [7], "AUG", 3);
451  memcpy (smonth [8], "SEP", 3);
452  memcpy (smonth [9], "OCT", 3);
453  memcpy (smonth [10], "NOV", 3);
454  memcpy (smonth [11], "DEC", 3);
455  // Create time buffer
456  sprintf(buf, "%02d-%3.3s-%04d %02d:%02d:%02d.%02d",
457  day,
458  smonth[month-1],
459  year,
460  hour,
461  minute,
462  second,
463  millisecond / 10);
464 
465  // Fill string descriptor
466  d_time.dsc$w_length = strlen(buf);
467  d_time.dsc$b_dtype = DSC$K_DTYPE_T;
468  d_time.dsc$b_class = DSC$K_CLASS_S;
469  d_time.dsc$a_pointer = buf;
470  // Convert time buf to VAX bin time
471  sys$bintim(&d_time, &vbt);
472  // Set the system time
473  sys$setime(&vbt);
474 #endif
475 
476 #ifdef RLWIN32
477  SYSTEMTIME st;
478  st.wDay = day;
479  st.wMonth = month;
480  st.wYear = year;
481  st.wHour = hour;
482  st.wMinute = minute;
483  st.wSecond = second;
484  st.wMilliseconds = millisecond;
485  SetSystemTime(&st);
486 #endif
487 }
488 
490 {
491  rlTime t;
492  t = *this + time;
493  *this = t;
494  return *this;
495 }
496 
498 {
499  rlTime t;
500  t = *this - time;
501  *this = t;
502  return *this;
503 }
504 
506 {
507  int maxmonth,y,m;
508  rlTime t;
509 
510  t.year = year + time.year;
511  t.month = month + time.month;
512  t.day = day + time.day;
513  t.hour = hour + time.hour;
514  t.minute = minute + time.minute;
515  t.second = second + time.second;
517 
518  y = t.year;
519  if(t.month > 12 || (t.month==12 && t.day==31 && t.hour>=24)) y++;
520  m = t.month;
521  if(t.month > 12 || (t.month==12 && t.day==31 && t.hour>=24)) m = 1;
522 
523  switch(m % 12)
524  {
525  case 1: // january
526  maxmonth = 31;
527  break;
528  case 2: // february
529  maxmonth = 28;
530  // Annus bisextilis (calendario Gregoriano)
531  if(y%4==0)
532  {
533  maxmonth = 29;
534  int hth = y % 100;
535  int special = y % 400; // 1900-+-2100-2200-2300-+-2500-2600-2700
536  if(hth == 0 && special != 0) maxmonth = 28;
537  }
538  break;
539  case 3: // march
540  maxmonth = 31;
541  break;
542  case 4: // april
543  maxmonth = 30;
544  break;
545  case 5: // may
546  maxmonth = 31;
547  break;
548  case 6: // june
549  maxmonth = 30;
550  break;
551  case 7: // july
552  maxmonth = 31;
553  break;
554  case 8: // august
555  maxmonth = 31;
556  break;
557  case 9: // september
558  maxmonth = 30;
559  break;
560  case 10: // october
561  maxmonth = 31;
562  break;
563  case 11: // november
564  maxmonth = 30;
565  break;
566  case 12: // december
567  maxmonth = 31;
568  break;
569  default:
570  maxmonth = 31;
571  break;
572  }
573 
574  if(t.millisecond >= 1000) { t.second++; t.millisecond -= 1000; }
575  if(t.second >= 60) { t.minute++; t.second -= 60; }
576  if(t.minute >= 60) { t.hour++, t.minute -= 60; }
577  if(t.hour >= 24) { t.day++; t.hour -= 24; }
578  if(t.day > maxmonth) { t.month++; t.day -= maxmonth; }
579  if(t.month > 12) { t.year++; t.month -= 12; }
580  return t;
581 }
582 
584 {
585  int maxmonth,y,m;
586  rlTime t;
587 
588  y = 0;
589  t.year = year - time.year;
590  t.month = month - time.month;
591  t.day = day - time.day;
592  t.hour = hour - time.hour;
593  t.minute = minute - time.minute;
594  t.second = second - time.second;
596 
597  if(t.millisecond < 0) { t.second--; t.millisecond += 1000; }
598  if(t.second < 0) { t.minute--; t.second += 60; }
599  if(t.minute < 0) { t.hour--, t.minute += 60; }
600  if(t.hour < 0) { t.day--; t.hour += 24; }
601 
602  if(t.day < 0)
603  {
604  t.month--;
605  y = t.year;
606  m = t.month;
607  if(m <= 0) { m += 12; y--; }
608  switch(m % 12)
609  {
610  case 1: // january
611  maxmonth = 31;
612  break;
613  case 2: // february
614  maxmonth = 28;
615  // Annus bisextilis (calendario Gregoriano)
616  if(y%4==0)
617  {
618  maxmonth = 29;
619  int hth = y % 100;
620  int special = y % 400; // 1900-+-2100-2200-2300-+-2500-2600-2700
621  if(hth == 0 && special != 0) maxmonth = 28;
622  }
623  break;
624  case 3: // march
625  maxmonth = 31;
626  break;
627  case 4: // april
628  maxmonth = 30;
629  break;
630  case 5: // may
631  maxmonth = 31;
632  break;
633  case 6: // june
634  maxmonth = 30;
635  break;
636  case 7: // july
637  maxmonth = 31;
638  break;
639  case 8: // august
640  maxmonth = 31;
641  break;
642  case 9: // september
643  maxmonth = 30;
644  break;
645  case 10: // october
646  maxmonth = 31;
647  break;
648  case 11: // november
649  maxmonth = 30;
650  break;
651  case 12: // december
652  maxmonth = 31;
653  break;
654  default:
655  maxmonth = 31;
656  break;
657  }
658  t.day += maxmonth;
659  }
660 
661  if(y >= 0)
662  {
663  //printf("after christ was born. thus everything is ok.\n");
664  }
665  else
666  {
667  //printf("before christ was born. now also ok\n");
668  /*
669  { t.month++; t.day -= 30; }
670  if(t.day < 30) { t.day++; t.hour -= 24; }
671  if(t.hour < 0 ) { t.hour++; t.minute -= 60; }
672  if(t.minute < 0 ) { t.minute++; t.second -= 60; }
673  if(t.second < 0 ) { t.second++; t.millisecond -= 1000; }
674  */
675  }
676 
677  return t;
678 }
679 
681 {
682  if(year != time.year) return 0;
683  if(month != time.month) return 0;
684  if(day != time.day) return 0;
685  if(hour != time.hour) return 0;
686  if(minute != time.minute) return 0;
687  if(second != time.second) return 0;
688  if(millisecond != time.millisecond) return 0;
689 
690  return 1;
691 }
692 
694 {
695  rlTime diff,t1;
696 
697  t1.year = year;
698  t1.month = month;
699  t1.day = day;
700  t1.hour = hour;
701  t1.minute = minute;
702  t1.second = second;
704  //printf("<t1=%s\n",t1.getTimeString());
705  //printf("<time=%s\n",time.getTimeString());
706  diff = t1 - time;
707  //printf("<diff=%s\n",diff.getTimeString());
708  if(diff.year < 0) return 1;
709  if(diff.month < 0) return 1;
710  if(diff.day < 0) return 1;
711  if(diff.hour < 0) return 1;
712  if(diff.minute < 0) return 1;
713  if(diff.second < 0) return 1;
714  if(diff.millisecond < 0) return 1;
715  return 0;
716 }
717 
719 {
720  if((*this) == time) return 1;
721  if((*this) < time) return 1;
722  return 0;
723 }
724 
726 {
727  rlTime diff,t1;
728 
729  t1.year = year;
730  t1.month = month;
731  t1.day = day;
732  t1.hour = hour;
733  t1.minute = minute;
734  t1.second = second;
736  //printf(">t1=%s\n",t1.getTimeString());
737  //printf(">time=%s\n",time.getTimeString());
738  diff = time - t1;
739  //printf(">diff=%s\n",diff.getTimeString());
740  if(diff.year < 0) return 1;
741  if(diff.month < 0) return 1;
742  if(diff.day < 0) return 1;
743  if(diff.hour < 0) return 1;
744  if(diff.minute < 0) return 1;
745  if(diff.second < 0) return 1;
746  if(diff.millisecond < 0) return 1;
747  return 0;
748 }
749 
751 {
752  if((*this) == time) return 1;
753  if((*this) > time) return 1;
754  return 0;
755 }
756 
758 {
759  struct tm begin;
760  struct tm test;
761 
762  memset(&begin,0,sizeof(tm));
763  memset(&test,0,sizeof(tm));
764 
765  // If timeptr references a date before midnight, January 1, 1970,
766  // or if the calendar time cannot be represented ...
767  begin.tm_year = 70;
768  begin.tm_mon = 0;
769  begin.tm_mday = 2; // 1; // fix due to error report by George Zempekis
770  begin.tm_hour = 0;
771  begin.tm_min = 0;
772  begin.tm_sec = 0;
773 
774  test.tm_year = year - 1900;
775  test.tm_mon = month - 1;
776  test.tm_mday = day;
777  test.tm_hour = hour;
778  test.tm_min = minute;
779  test.tm_sec = second;
780 
781  time_t t0 = mktime(&begin);
782  time_t t1 = mktime(&test);
783 
784  return difftime(t1,t0) + (((double) millisecond) / 1000);
785 }
786 
const char * getTimeString()
Definition: rltime.cpp:106
void getLocalTime()
Definition: rltime.cpp:342
int year
Definition: rltime.h:53
virtual ~rlTime()
Definition: rltime.cpp:73
int hour
Definition: rltime.h:56
short min
Definition: rltime.cpp:44
char iso_time_string[32]
Definition: rltime.h:62
int operator>=(rlTime &time)
Definition: rltime.cpp:750
rlTime & operator-=(rlTime &time)
Definition: rltime.cpp:497
#define RLWIN32
Definition: rldefine.h:42
int month
Definition: rltime.h:54
const char * toString(const char *format)
Definition: rltime.cpp:156
void setTimeFromIsoString(const char *iso_time_string)
Definition: rltime.cpp:94
const char * getIsoTimeString()
Definition: rltime.cpp:112
int operator==(rlTime &time)
Definition: rltime.cpp:680
long word_2
Definition: rltime.cpp:52
void setLocalTime()
Definition: rltime.cpp:419
short year
Definition: rltime.cpp:40
int operator<=(rlTime &time)
Definition: rltime.cpp:718
int day
Definition: rltime.h:55
Definition: rltime.cpp:38
short hth
Definition: rltime.cpp:46
rlTime operator-(rlTime &time)
Definition: rltime.cpp:583
long word_1
Definition: rltime.cpp:51
const char * version()
Definition: rltime.cpp:77
int second
Definition: rltime.h:58
short sec
Definition: rltime.cpp:45
short hour
Definition: rltime.cpp:43
rlTime & operator+=(rlTime &time)
Definition: rltime.cpp:489
int millisecond
Definition: rltime.h:59
int minute
Definition: rltime.h:57
rlTime operator+(rlTime &time)
Definition: rltime.cpp:505
int getFileModificationTime(const char *filename)
Definition: rltime.cpp:392
double secondsSinceEpoche()
Definition: rltime.cpp:757
char time_string[32]
Definition: rltime.h:61
rlTime(int Year=0, int Month=0, int Day=0, int Hour=0, int Minute=0, int Second=0, int Millisecond=0)
Definition: rltime.cpp:62
short day
Definition: rltime.cpp:42
Definition: rltime.h:25
short month
Definition: rltime.cpp:41
int operator>(rlTime &time)
Definition: rltime.cpp:725
void setTimeFromString(const char *time_string)
Definition: rltime.cpp:82
int operator<(rlTime &time)
Definition: rltime.cpp:693