Ahoy
27-08-21, 07:28
Hier noch eine Lösung die beliebige RPG Timestamps zu ISO8601 konvertieren kann.
**free
ctl-opt dftactgrp(*no);
ctl-opt option(*nodebugio: *srcstmt: *nounref);
ctl-opt main(main);
dcl-s time_t int(20) template;
dcl-pr time like(time_t) extproc(*cwiden: 'time64');
timeval like(time_t) options(*omit);
end-pr;
dcl-ds struct_tm qualified template;
tm_sec int(10); // seconds after the minute (0-61)
tm_min int(10); // minutes after the hour (0-59)
tm_hour int(10); // hours since midnight (0-23)
tm_mday int(10); // day of the month (1-31)
tm_mon int(10); // months since January (0-11)
tm_year int(10); // years since 1900
tm_wday int(10); // days since Sunday (0-6)
tm_yday int(10); // days since January 1 (0-365)
tm_isdst int(10); // Daylight Saving Time flag
end-ds;
dcl-pr gmtime_r pointer extproc(*cwiden: 'gmtime64_r');
timer like(time_t) const;
tm like(struct_tm);
end-pr;
dcl-pr mktime like(time_t) extproc(*cwiden: 'mktime64');
tm like(struct_tm);
end-pr;
dcl-pr localtime_r pointer extproc(*cwiden: 'localtime64_r');
timer like(time_t) const;
tm like(struct_tm);
end-pr;
dcl-proc main;
dsply time(*omit);
dsply timestampToEpoch(%timestamp);
dsply %timestamp(*sys: 0);
dsply epochToTimestamp(timestampToEpoch(%timestamp));
// 1 Stunde UTC-Offset für Winterzeit
dsply timestampToISO8601(z'2021-01-01-14.00.00');
// 2 Stunde UTC-Offset für Sommerzeit
dsply timestampToISO8601(z'2021-08-01-14.00.00');
// Timestamp innerhalb der überlappung von Sommer- und
// Winterzeit wird als Winterzeit interpretiert
dsply timestampToISO8601(z'2021-10-31-02.30.00');
// Timestamp innerhalb der übersprungenen
// Stunde wird als Winterzeit interpretiert
dsply timestampToISO8601(z'2021-03-28-02.30.00');
end-proc;
// Konvertiert Unix Epoch Timestamp zu ISO8601 Timestamp
dcl-proc epochToISO8601 export;
dcl-pi *n char(20);
timeval like(time_t) const;
end-pi;
dcl-ds tm likeds(struct_tm) inz;
// tm struct befüllen
gmtime_r(timeval: tm);
// ISO8601 Timestamp zusammensetzen
return
%subst(%editc(tm.tm_year + 1900: 'X'): 7: 4) + '-' +
%subst(%editc(tm.tm_mon + 1: 'X'): 9: 2) + '-' +
%subst(%editc(tm.tm_mday: 'X'): 9: 2) + 'T' +
%subst(%editc(tm.tm_hour: 'X'): 9: 2) + ':' +
%subst(%editc(tm.tm_min: 'X'): 9: 2) + ':' +
%subst(%editc(tm.tm_sec: 'X'): 9: 2) + 'Z';
end-proc;
// Konvertiert RPG Timestamp zu ISO8601 Timestamp
dcl-proc timestampToISO8601 export;
dcl-pi *n char(20);
timestamp timestamp(0) const;
isdst ind const options(*nopass);
end-pi;
if %parms = 2;
return epochToISO8601(timestampToEpoch(timestamp: isdst));
else;
return epochToISO8601(timestampToEpoch(timestamp));
endif;
end-proc;
// konvertiert UNIX Epoch zu RPG Timestamp
dcl-proc epochToTimestamp export;
dcl-pi *n timestamp(0);
time like(time_t) value;
end-pi;
dcl-ds tm likeds(struct_tm) inz;
localtime_r(time: tm);
return %timestamp(
%subst(%editc(tm.tm_year + 1900: 'X'): 7: 4) +
%subst(%editc(tm.tm_mon + 1: 'X'): 9: 2) +
%subst(%editc(tm.tm_mday: 'X'): 9: 2) +
%subst(%editc(tm.tm_hour: 'X'): 9: 2) +
%subst(%editc(tm.tm_min: 'X'): 9: 2) +
%subst(%editc(tm.tm_sec: 'X'): 9: 2):
*iso0: 0
);
end-proc;
// konvertiert RPG Timestamp zu UNIX Epoch
dcl-proc timestampToEpoch export;
dcl-pi *n like(time_t);
timestamp timestamp(0) const;
isdst ind const options(*nopass);
end-pi;
dcl-ds tm likeds(struct_tm) inz;
tm.tm_year = %subdt(timestamp: *years) - 1900;
tm.tm_mon = %subdt(timestamp: *months) - 1;
tm.tm_mday = %subdt(timestamp: *days);
tm.tm_hour = %subdt(timestamp: *hours);
tm.tm_min = %subdt(timestamp: *minutes);
tm.tm_sec = %subdt(timestamp: *seconds);
if %parms = 2;
if isdst;
tm.tm_isdst = 1;
else;
tm.tm_isdst = 0;
endif;
else;
tm.tm_isdst = -1;
endif;
// convert to unix timestamp
return mktime(tm);
end-proc;
**free
ctl-opt dftactgrp(*no);
ctl-opt option(*nodebugio: *srcstmt: *nounref);
ctl-opt main(main);
dcl-s time_t int(20) template;
dcl-pr time like(time_t) extproc(*cwiden: 'time64');
timeval like(time_t) options(*omit);
end-pr;
dcl-ds struct_tm qualified template;
tm_sec int(10); // seconds after the minute (0-61)
tm_min int(10); // minutes after the hour (0-59)
tm_hour int(10); // hours since midnight (0-23)
tm_mday int(10); // day of the month (1-31)
tm_mon int(10); // months since January (0-11)
tm_year int(10); // years since 1900
tm_wday int(10); // days since Sunday (0-6)
tm_yday int(10); // days since January 1 (0-365)
tm_isdst int(10); // Daylight Saving Time flag
end-ds;
dcl-pr gmtime_r pointer extproc(*cwiden: 'gmtime64_r');
timer like(time_t) const;
tm like(struct_tm);
end-pr;
dcl-pr mktime like(time_t) extproc(*cwiden: 'mktime64');
tm like(struct_tm);
end-pr;
dcl-pr localtime_r pointer extproc(*cwiden: 'localtime64_r');
timer like(time_t) const;
tm like(struct_tm);
end-pr;
dcl-proc main;
dsply time(*omit);
dsply timestampToEpoch(%timestamp);
dsply %timestamp(*sys: 0);
dsply epochToTimestamp(timestampToEpoch(%timestamp));
// 1 Stunde UTC-Offset für Winterzeit
dsply timestampToISO8601(z'2021-01-01-14.00.00');
// 2 Stunde UTC-Offset für Sommerzeit
dsply timestampToISO8601(z'2021-08-01-14.00.00');
// Timestamp innerhalb der überlappung von Sommer- und
// Winterzeit wird als Winterzeit interpretiert
dsply timestampToISO8601(z'2021-10-31-02.30.00');
// Timestamp innerhalb der übersprungenen
// Stunde wird als Winterzeit interpretiert
dsply timestampToISO8601(z'2021-03-28-02.30.00');
end-proc;
// Konvertiert Unix Epoch Timestamp zu ISO8601 Timestamp
dcl-proc epochToISO8601 export;
dcl-pi *n char(20);
timeval like(time_t) const;
end-pi;
dcl-ds tm likeds(struct_tm) inz;
// tm struct befüllen
gmtime_r(timeval: tm);
// ISO8601 Timestamp zusammensetzen
return
%subst(%editc(tm.tm_year + 1900: 'X'): 7: 4) + '-' +
%subst(%editc(tm.tm_mon + 1: 'X'): 9: 2) + '-' +
%subst(%editc(tm.tm_mday: 'X'): 9: 2) + 'T' +
%subst(%editc(tm.tm_hour: 'X'): 9: 2) + ':' +
%subst(%editc(tm.tm_min: 'X'): 9: 2) + ':' +
%subst(%editc(tm.tm_sec: 'X'): 9: 2) + 'Z';
end-proc;
// Konvertiert RPG Timestamp zu ISO8601 Timestamp
dcl-proc timestampToISO8601 export;
dcl-pi *n char(20);
timestamp timestamp(0) const;
isdst ind const options(*nopass);
end-pi;
if %parms = 2;
return epochToISO8601(timestampToEpoch(timestamp: isdst));
else;
return epochToISO8601(timestampToEpoch(timestamp));
endif;
end-proc;
// konvertiert UNIX Epoch zu RPG Timestamp
dcl-proc epochToTimestamp export;
dcl-pi *n timestamp(0);
time like(time_t) value;
end-pi;
dcl-ds tm likeds(struct_tm) inz;
localtime_r(time: tm);
return %timestamp(
%subst(%editc(tm.tm_year + 1900: 'X'): 7: 4) +
%subst(%editc(tm.tm_mon + 1: 'X'): 9: 2) +
%subst(%editc(tm.tm_mday: 'X'): 9: 2) +
%subst(%editc(tm.tm_hour: 'X'): 9: 2) +
%subst(%editc(tm.tm_min: 'X'): 9: 2) +
%subst(%editc(tm.tm_sec: 'X'): 9: 2):
*iso0: 0
);
end-proc;
// konvertiert RPG Timestamp zu UNIX Epoch
dcl-proc timestampToEpoch export;
dcl-pi *n like(time_t);
timestamp timestamp(0) const;
isdst ind const options(*nopass);
end-pi;
dcl-ds tm likeds(struct_tm) inz;
tm.tm_year = %subdt(timestamp: *years) - 1900;
tm.tm_mon = %subdt(timestamp: *months) - 1;
tm.tm_mday = %subdt(timestamp: *days);
tm.tm_hour = %subdt(timestamp: *hours);
tm.tm_min = %subdt(timestamp: *minutes);
tm.tm_sec = %subdt(timestamp: *seconds);
if %parms = 2;
if isdst;
tm.tm_isdst = 1;
else;
tm.tm_isdst = 0;
endif;
else;
tm.tm_isdst = -1;
endif;
// convert to unix timestamp
return mktime(tm);
end-proc;