Mumps has special format of date and time which is $H. When date and time (not separately) is stored in database (or global), any recommended format? Store it as $H format or any other format? Also what I can get the system timezone information from GT.M? thanks,
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Also during day from day light saying back to regular time,will the time piece value be from 0 to 89999 instead of 0-86399 as regular day? How does it work in GT.M?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm sure there are many opinions on your first question. Here are some possibilities:
1) Just use the the $H format, with the comma separating the date and time. Main advantage is that it is simple and "standard". It also will probably be easier to use with various "standard" conversion routines (like $ZDATE, etc.). Main downside is it does not sort properly.
2) You could use a more human readable format such as that returned by $ZDATE($H,"YEAR-MM-DD 24:60:SS") or even $ZDATE($H,"YEARMMDD2460SS"). This uses a bit more storage but does sort well and is "friendly".
3) Use what we refer to as "H10" format, computing the "timestamp" as follows:
set h=$h,h=h*1E5+$p(h,",",2)
This gives you a 10+ digit date/time that is fairly easily converted back to $H format:
set date=h\1E5,time=h#1E5
It also sorts nicely and one can visually see the $H values (so you can at least compare two dates, get an estimate of the time of day, etc.)
4) The option I prefer these days, however, is to store the timestamp in what I call "S10" format which is actually the number of seconds since the M epoch (the first second of Dec. 31, 1840) using:
set ts=$h,ts=ts*3600*24
and
set date=ts\(3600*24),time=ts#(3600*24)
This is more in line with what most modern systems use. If you want to be fancier you could subtract the offset of Jan 1, 1970 to get a more "Unix" friendly value. One downside is that if you have to deal with timestamps in format 3 above AND these timestamps it is not always clear from looking at the values what format you have.
I'm sure there are other common methods but I would recommend using option 4 and no matter which option you use put the code into several utility functions like $$HorologToInternal^TimeUtils($H), $$InternalToHorlog^TimeUtils(ts), $$Format^TimeUtils(ts,"YYYY-MM-DD HH:MM:SS").
Regarding your time zone questions:
Timezone can be determined using something like:
set pipe="mypipe"
open pipe:(command="date +%Z")::"PIPE"
use pipe
read tz
close pipe
u ""
zwrite tz
You could use "+%z" to get the numeric value of the time zone. See time(1) for more details.
Regarding daylight savings time - No, I don't think that GT.M will ever allow the time piece of $H to be greater than 86399. I suspect that even leap seconds are not taken into account. I would hope that on a leap second the time piece of $H just stays at 86399 for an additional second. I believe that that when going back to daylight savings time when $H="ddddd,7199" (01:59:59AM) $H will simply reset to 3600 (1AM) at the next second. Values from 3600 to 7199 will be repeated and then will continue to 7200 and onward.
Potentially problematic if doing data collection or something at that point in time. I believe that one solution might be to run your systems on UTC time such that $H would never need to deal with jumping forward or backward. Then if you are storing your timestamps in a format such as option 4 above you could treat these as UTC times and only need to know what time zone you want to convert them to when they need to be displayed.
Hope that helps, or at least makes sense.
-bob
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
But I think the pipe is an very expensive operation. Is there a light way to get the "date +%s" information in GT.M from Unix or is there an easy way to execute Unix command from GT.M. Does ZSYSTEM work?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You certainly could do something similar with ZSYSTEM. That is the way we did it before PIPEs. However, I doubt it would be any more efficient even if you did not have to send the output to a file, open the file, read the file, close and delete the file.
If you really need it to be efficient you would use something like the POSIX addon that was mentioned earlier or just write your own interface to time(). You could stash the information in an environment variable before starting GT.M and then use $ZTRNLNM() to retrieve it.
In any case, you probably want to just do it once at start-up and stash the value in the process somewhere instead of making multiple calls. But, I suppose it could change on you at an inopportune time… Interesting problem.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
After considering all four options, I think the unix time "date +%s" is better since it does save the correct information. Option S10 has a big flaw during the day light saving change days, especially the day when it is changed back. It loses the information during the time of 2:00-2:59am. For healthcare, this is critical.
Thanks so much for the help.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mumps has special format of date and time which is $H. When date and time (not separately) is stored in database (or global), any recommended format? Store it as $H format or any other format? Also what I can get the system timezone information from GT.M? thanks,
Also during day from day light saying back to regular time,will the time piece value be from 0 to 89999 instead of 0-86399 as regular day? How does it work in GT.M?
I'm sure there are many opinions on your first question. Here are some possibilities:
1) Just use the the $H format, with the comma separating the date and time. Main advantage is that it is simple and "standard". It also will probably be easier to use with various "standard" conversion routines (like $ZDATE, etc.). Main downside is it does not sort properly.
2) You could use a more human readable format such as that returned by $ZDATE($H,"YEAR-MM-DD 24:60:SS") or even $ZDATE($H,"YEARMMDD2460SS"). This uses a bit more storage but does sort well and is "friendly".
3) Use what we refer to as "H10" format, computing the "timestamp" as follows:
This gives you a 10+ digit date/time that is fairly easily converted back to $H format:
It also sorts nicely and one can visually see the $H values (so you can at least compare two dates, get an estimate of the time of day, etc.)
4) The option I prefer these days, however, is to store the timestamp in what I call "S10" format which is actually the number of seconds since the M epoch (the first second of Dec. 31, 1840) using:
and
This is more in line with what most modern systems use. If you want to be fancier you could subtract the offset of Jan 1, 1970 to get a more "Unix" friendly value. One downside is that if you have to deal with timestamps in format 3 above AND these timestamps it is not always clear from looking at the values what format you have.
I'm sure there are other common methods but I would recommend using option 4 and no matter which option you use put the code into several utility functions like $$HorologToInternal^TimeUtils($H), $$InternalToHorlog^TimeUtils(ts), $$Format^TimeUtils(ts,"YYYY-MM-DD HH:MM:SS").
Regarding your time zone questions:
Timezone can be determined using something like:
You could use "+%z" to get the numeric value of the time zone. See time(1) for more details.
Regarding daylight savings time - No, I don't think that GT.M will ever allow the time piece of $H to be greater than 86399. I suspect that even leap seconds are not taken into account. I would hope that on a leap second the time piece of $H just stays at 86399 for an additional second. I believe that that when going back to daylight savings time when $H="ddddd,7199" (01:59:59AM) $H will simply reset to 3600 (1AM) at the next second. Values from 3600 to 7199 will be repeated and then will continue to 7200 and onward.
Potentially problematic if doing data collection or something at that point in time. I believe that one solution might be to run your systems on UTC time such that $H would never need to deal with jumping forward or backward. Then if you are storing your timestamps in a format such as option 4 above you could treat these as UTC times and only need to know what time zone you want to convert them to when they need to be displayed.
Hope that helps, or at least makes sense.
-bob
That is very helpful. Thanks a lot.
But I think the pipe is an very expensive operation. Is there a light way to get the "date +%s" information in GT.M from Unix or is there an easy way to execute Unix command from GT.M. Does ZSYSTEM work?
You certainly could do something similar with ZSYSTEM. That is the way we did it before PIPEs. However, I doubt it would be any more efficient even if you did not have to send the output to a file, open the file, read the file, close and delete the file.
If you really need it to be efficient you would use something like the POSIX addon that was mentioned earlier or just write your own interface to time(). You could stash the information in an environment variable before starting GT.M and then use $ZTRNLNM() to retrieve it.
In any case, you probably want to just do it once at start-up and stash the value in the process somewhere instead of making multiple calls. But, I suppose it could change on you at an inopportune time… Interesting problem.
After considering all four options, I think the unix time "date +%s" is better since it does save the correct information. Option S10 has a big flaw during the day light saving change days, especially the day when it is changed back. It loses the information during the time of 2:00-2:59am. For healthcare, this is critical.
Thanks so much for the help.