lib/iec_std_lib.h
changeset 705 f2323f79252e
parent 704 1adc8df05d2b
child 706 31553c22f318
equal deleted inserted replaced
704:1adc8df05d2b 705:f2323f79252e
   232   broken_down_time.tm_min = 0;
   232   broken_down_time.tm_min = 0;
   233   broken_down_time.tm_hour = 0;
   233   broken_down_time.tm_hour = 0;
   234   broken_down_time.tm_mday = day;  /* day of month, from 1 to 31 */
   234   broken_down_time.tm_mday = day;  /* day of month, from 1 to 31 */
   235   broken_down_time.tm_mon = month - 1;   /* month since January, in the range 0 to 11 */
   235   broken_down_time.tm_mon = month - 1;   /* month since January, in the range 0 to 11 */
   236   broken_down_time.tm_year = year - 1900;  /* number of years since 1900 */
   236   broken_down_time.tm_year = year - 1900;  /* number of years since 1900 */
   237 
   237   broken_down_time.tm_isdst = -1; /* disable daylight savings time */
   238   epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */
   238   
       
   239   epoch_seconds = timegm(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */
   239 
   240 
   240   if ((time_t)(-1) == epoch_seconds)
   241   if ((time_t)(-1) == epoch_seconds)
   241     __iec_error();
   242     __iec_error();
   242 
   243 
       
   244   printf("Seconds = %d\n", (int)epoch_seconds);
       
   245 
   243   ts.tv_sec = epoch_seconds;
   246   ts.tv_sec = epoch_seconds;
   244   ts.tv_nsec = 0;
   247   ts.tv_nsec = 0;
   245 
   248 
   246   return ts;
   249   return ts;
   247 }
   250 }
   248 
   251 
   249 static inline IEC_TIMESPEC __dt_to_timespec(double seconds,  double minutes, double hours, int day, int month, int year) {
   252 static inline IEC_TIMESPEC __dt_to_timespec(double seconds, double minutes, double hours, int day, int month, int year) {
   250   IEC_TIMESPEC ts;
   253   IEC_TIMESPEC ts_date = __date_to_timespec(day, month, year);
   251   struct tm broken_down_time;
   254   IEC_TIMESPEC ts = __tod_to_timespec(seconds, minutes, hours);
   252   time_t epoch_seconds;
   255 
   253 
   256   ts.tv_sec += ts_date.tv_sec;
   254   long double total_sec = (hours*60 + minutes)*60 + seconds;
       
   255   ts.tv_sec = (long int)total_sec;
       
   256   ts.tv_nsec = (long int)((total_sec - ts.tv_sec)*1e9);
       
   257 
       
   258   broken_down_time.tm_sec = 0;
       
   259   broken_down_time.tm_min = 0;
       
   260   broken_down_time.tm_hour = 0;
       
   261   broken_down_time.tm_mday = day;  /* day of month, from 1 to 31 */
       
   262   broken_down_time.tm_mon = month - 1;   /* month since January, in the range 0 to 11 */
       
   263   broken_down_time.tm_year = year - 1900;  /* number of years since 1900 */
       
   264   broken_down_time.tm_isdst = 0; /* disable daylight savings time */
       
   265 
       
   266   epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */
       
   267   if ((time_t)(-1) == epoch_seconds)
       
   268     __iec_error();
       
   269 
       
   270   ts.tv_sec += epoch_seconds;
       
   271   if (ts.tv_sec < epoch_seconds)
       
   272     /* since the TOD is always positive, if the above happens then we had an overflow */
       
   273     __iec_error();
       
   274 
   257 
   275   return ts;
   258   return ts;
   276 }
   259 }
   277 
   260 
   278 /*******************/
   261 /*******************/
   368 }
   351 }
   369     /***************/
   352     /***************/
   370     /* FROM_STRING */
   353     /* FROM_STRING */
   371     /***************/
   354     /***************/
   372 static inline BOOL __string_to_bool(STRING IN) {
   355 static inline BOOL __string_to_bool(STRING IN) {
   373     return IN.len == 5 ? !memcmp(&IN.body,"TRUE", IN.len) : 0;
   356     int i;
       
   357     if (IN.len == 1) return !memcmp(&IN.body,"1", IN.len);
       
   358     for (i = 0; i < IN.len; i++) IN.body[i] = toupper(IN.body[i]);
       
   359     return IN.len == 4 ? !memcmp(&IN.body,"TRUE", IN.len) : 0;
   374 }
   360 }
   375 
   361 
   376 static inline LINT __pstring_to_sint(STRING* IN) {
   362 static inline LINT __pstring_to_sint(STRING* IN) {
   377     LINT res = 0;
   363     LINT res = 0;
   378     __strlen_t l;
   364     __strlen_t l;
   528     struct tm* broken_down_time;
   514     struct tm* broken_down_time;
   529     time_t seconds;
   515     time_t seconds;
   530     /* D#1984-06-25 */
   516     /* D#1984-06-25 */
   531     res = __INIT_STRING;
   517     res = __INIT_STRING;
   532     seconds = IN.tv_sec;
   518     seconds = IN.tv_sec;
   533     if (NULL == (broken_down_time = localtime(&seconds))){ /* get the UTC (GMT) broken down time */
   519     if (NULL == (broken_down_time = gmtime(&seconds))){ /* get the UTC (GMT) broken down time */
   534         __iec_error();
   520         __iec_error();
   535         return (STRING){7,"D#ERROR"};
   521         return (STRING){7,"D#ERROR"};
   536     }
   522     }
   537     res.len = snprintf((char*)&res.body, STR_MAX_LEN, "D#%d-%2.2d-%2.2d", broken_down_time->tm_year + 1900, broken_down_time->tm_mon + 1, broken_down_time->tm_mday);
   523     res.len = snprintf((char*)&res.body, STR_MAX_LEN, "D#%d-%2.2d-%2.2d", broken_down_time->tm_year + 1900, broken_down_time->tm_mon + 1, broken_down_time->tm_mday);
   538     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
   524     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
   543     struct tm* broken_down_time;
   529     struct tm* broken_down_time;
   544     time_t seconds;
   530     time_t seconds;
   545     /* TOD#15:36:55.36 */
   531     /* TOD#15:36:55.36 */
   546     res = __INIT_STRING;
   532     res = __INIT_STRING;
   547     seconds = IN.tv_sec;
   533     seconds = IN.tv_sec;
   548     if (NULL == (broken_down_time = localtime(&seconds))){ /* get the UTC (GMT) broken down time */
   534     if (NULL == (broken_down_time = gmtime(&seconds))){ /* get the UTC (GMT) broken down time */
   549         __iec_error();
   535         __iec_error();
   550         return (STRING){9,"TOD#ERROR"};
   536         return (STRING){9,"TOD#ERROR"};
   551     }
   537     }
   552     if(IN.tv_nsec == 0){
   538     if(IN.tv_nsec == 0){
   553         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%d", broken_down_time->tm_hour, broken_down_time->tm_min, broken_down_time->tm_sec);
   539         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%2.2d", broken_down_time->tm_hour, broken_down_time->tm_min, broken_down_time->tm_sec);
   554     }else{
   540     }else{
   555         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%g", broken_down_time->tm_hour, broken_down_time->tm_min, (LREAL)broken_down_time->tm_sec + (LREAL)IN.tv_nsec / 1e9);
   541         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%09.6g", broken_down_time->tm_hour, broken_down_time->tm_min, (LREAL)broken_down_time->tm_sec + (LREAL)IN.tv_nsec / 1e9);
   556     }
   542     }
   557     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
   543     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
   558     return res;
   544     return res;
   559 }
   545 }
   560 static inline STRING __dt_to_string(DT IN){
   546 static inline STRING __dt_to_string(DT IN){
   561     STRING res;
   547     STRING res;
   562     struct tm* broken_down_time;
   548     struct tm* broken_down_time;
   563     time_t seconds;
   549     time_t seconds;
   564     /* DT#1984-06-25-15:36:55.36 */
   550     /* DT#1984-06-25-15:36:55.36 */
   565     seconds = IN.tv_sec;
   551     seconds = IN.tv_sec;
   566     if (NULL == (broken_down_time = localtime(&seconds))){ /* get the UTC (GMT) broken down time */
   552     if (NULL == (broken_down_time = gmtime(&seconds))){ /* get the UTC (GMT) broken down time */
   567         __iec_error();
   553         __iec_error();
   568         return (STRING){8,"DT#ERROR"};
   554         return (STRING){8,"DT#ERROR"};
   569     }
   555     }
   570     if(IN.tv_nsec == 0){
   556     if(IN.tv_nsec == 0){
   571         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%d",
   557         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%2.2d",
   572                  broken_down_time->tm_year + 1900,
   558                  broken_down_time->tm_year + 1900,
   573                  broken_down_time->tm_mon  + 1,
   559                  broken_down_time->tm_mon  + 1,
   574                  broken_down_time->tm_mday,
   560                  broken_down_time->tm_mday,
   575                  broken_down_time->tm_hour,
   561                  broken_down_time->tm_hour,
   576                  broken_down_time->tm_min,
   562                  broken_down_time->tm_min,
   577                  broken_down_time->tm_sec);
   563                  broken_down_time->tm_sec);
   578     }else{
   564     }else{
   579         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%g",
   565         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%09.6g",
   580                  broken_down_time->tm_year + 1900,
   566                  broken_down_time->tm_year + 1900,
   581                  broken_down_time->tm_mon  + 1,
   567                  broken_down_time->tm_mon  + 1,
   582                  broken_down_time->tm_mday,
   568                  broken_down_time->tm_mday,
   583                  broken_down_time->tm_hour,
   569                  broken_down_time->tm_hour,
   584                  broken_down_time->tm_min,
   570                  broken_down_time->tm_min,
   590 
   576 
   591     /**********************************************/
   577     /**********************************************/
   592     /*  [ANY_DATE | TIME] _TO_ [ANY_DATE | TIME]  */
   578     /*  [ANY_DATE | TIME] _TO_ [ANY_DATE | TIME]  */
   593     /**********************************************/
   579     /**********************************************/
   594 
   580 
   595 static inline TOD __date_and_time_to_time_of_day(DT IN) {return (TOD){IN.tv_sec % 86400, IN.tv_nsec};}
   581 static inline TOD __date_and_time_to_time_of_day(DT IN) {return (TOD){IN.tv_sec % (24*60*60), IN.tv_nsec};}
   596 static inline DATE __date_and_time_to_date(DT IN){return (DATE){IN.tv_sec - (IN.tv_sec % (24*60*60)), 0};}
   582 static inline DATE __date_and_time_to_date(DT IN){return (DATE){IN.tv_sec - (IN.tv_sec % (24*60*60)), 0};}
   597 
   583 
   598     /*****************/
   584     /*****************/
   599     /*  FROM/TO BCD  */
   585     /*  FROM/TO BCD  */
   600     /*****************/
   586     /*****************/
   817 
   803 
   818 
   804 
   819 /******** [ANY_DATE]_TO_[ANY_DATE | TIME]   ************/ 
   805 /******** [ANY_DATE]_TO_[ANY_DATE | TIME]   ************/ 
   820 /* Not supported: DT_TO_TIME */
   806 /* Not supported: DT_TO_TIME */
   821 __convert_type(DT, DATE,  __date_and_time_to_date)
   807 __convert_type(DT, DATE,  __date_and_time_to_date)
       
   808 static inline DATE DATE_AND_TIME_TO_DATE(EN_ENO_PARAMS, DT op){
       
   809 	return DT_TO_DATE(EN_ENO, op);
       
   810 }
   822 __convert_type(DT, DT,    __move_DT)
   811 __convert_type(DT, DT,    __move_DT)
   823 __convert_type(DT, TOD,   __date_and_time_to_time_of_day)
   812 __convert_type(DT, TOD,   __date_and_time_to_time_of_day)
       
   813 static inline DATE DATE_AND_TIME_TO_TIME_OF_DAY(EN_ENO_PARAMS, DT op){
       
   814 	return DT_TO_TOD(EN_ENO, op);
       
   815 }
   824 /* Not supported: DATE_TO_TIME */
   816 /* Not supported: DATE_TO_TIME */
   825 __convert_type(DATE, DATE, __move_DATE)
   817 __convert_type(DATE, DATE, __move_DATE)
   826 /* Not supported: DATE_TO_DT */
   818 /* Not supported: DATE_TO_DT */
   827 /* Not supported: DATE_TO_TOD */
   819 /* Not supported: DATE_TO_TOD */
   828 /* Not supported: TOD_TO_TIME */
   820 /* Not supported: TOD_TO_TIME */