1 # From MirOS: www/mk/common,v 1.4 2012/07/15 13:06:14 tg Exp $
4 # Thorsten “mirabilos” Glaser <tg@mirbsd.org>
6 # Provided that these terms and disclaimer and all copyright notices
7 # are retained or reproduced in an accompanying document, permission
8 # is granted to deal in this work without restriction, including un‐
9 # limited rights to use, publicly perform, distribute, sell, modify,
10 # merge, give away, or sublicence.
12 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
13 # the utmost extent permitted by applicable law, neither express nor
14 # implied; without malicious intent or gross negligence. In no event
15 # may a licensor, author or contributor be held liable for indirect,
16 # direct, other damage, loss, or other issues arising in any way out
17 # of dealing in the work, even if advised of the possibility of such
18 # damage or existence of a defect, except proven that it results out
19 # of said person’s immediate fault when using the work as intended.
21 # Time manipulation functions in Pure mksh™ – POSIX, no leap seconds
23 # Example use by the MirOS website: https://www.mirbsd.org/cvs.cgi/www/mk/
25 # magic from MirOS: src/kern/c/mirtime.c,v 1.3 2011/11/20 23:40:10 tg Exp $
27 # struct tm members and (POSIX) time functions
28 typeset -ir tm_sec=0 # seconds [0-59]
29 typeset -ir tm_min=1 # minutes [0-59]
30 typeset -ir tm_hour=2 # hours [0-23]
31 typeset -ir tm_mday=3 # day of month [1-31]
32 typeset -ir tm_mon=4 # month of year - 1 [0-11]
33 typeset -ir tm_year=5 # year - 1900
34 typeset -ir tm_wday=6 # day of week [0 = sunday] input:ignored
35 typeset -ir tm_yday=7 # day of year [0-365] input:ignored
36 typeset -ir tm_isdst=8 # summer time act.? [0/1] (0) input:ignored
37 typeset -ir tm_gmtoff=9 # seconds offset from UTC (0)
38 typeset -ir tm_zone=10 # abbrev. of timezone ("UTC") input:ignored
40 set -A mirtime_months -- Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
41 set -A mirtime_wdays -- Sun Mon Tue Wed Thu Fri Sat
42 readonly mirtime_months[*] mirtime_wdays[*]
44 # $ timet2mjd posix_timet
49 (( sec = mjd % 86400 ))
50 (( mjd = (mjd / 86400) + 40587 ))
51 while (( sec < 0 )); do
62 local -i10 t=$1 sec=$2
64 (( t = (t - 40587) * 86400 + sec ))
68 # $ mjd_explode mjd sec
69 # ⇒ tm_sec tm_min tm_hour tm_mday tm_mon tm_year \
70 # tm_wday tm_yday "0" "0" "UTC"
71 function mjd_explode {
74 local -i10 sec=$2 day yday mon year=$1
76 while (( sec < 0 )); do
80 while (( sec >= 86400 )); do
85 (( day = year % 146097 + 678881 ))
86 (( year = 4 * ((year / 146097) + (day / 146097)) ))
88 (( tm[tm_wday] = (day + 3) % 7 ))
89 if (( day == 146096 )); then
93 (( year += day / 36524 ))
96 (( year = 4 * ((year * 25) + (day / 1461)) ))
98 (( yday = (day < 306) ? 1 : 0 ))
99 if (( day == 1460 )); then
103 (( year += day / 365 ))
108 (( mon = (day + 5) / 306 ))
109 (( day = ((day + 5) % 306) / 10 ))
110 if (( mon >= 10 )); then
118 (( tm[tm_sec] = sec % 60 ))
120 (( tm[tm_min] = sec % 60 ))
121 (( tm[tm_hour] = sec / 60 ))
122 (( tm[tm_mday] = day + 1 ))
123 (( tm[tm_mon] = mon ))
124 (( tm[tm_year] = (year < 1 ? year - 1 : year) - 1900 ))
125 (( tm[tm_yday] = yday ))
126 (( tm[tm_isdst] = 0 ))
127 (( tm[tm_gmtoff] = 0 ))
130 print -r -- "${tm[@]}"
133 # $ mjd_implode tm_sec tm_min tm_hour tm_mday tm_mon tm_year \
134 # ignored ignored ignored tm_gmtoff [ignored]
136 function mjd_implode {
139 local -i10 day x y sec
141 (( sec = tm[tm_sec] + 60 * tm[tm_min] + 3600 * tm[tm_hour] - \
143 (( (day = tm[tm_year] + 1900) < 0 )) && (( ++day ))
145 (( day = (day / 400) * 146097 - 678882 + tm[tm_mday] ))
146 while (( sec < 0 )); do
150 while (( sec >= 86400 )); do
155 while (( x < 0 )); do
167 (( day += (306 * x + 5) / 10 ))
168 while (( y < 0 )); do
172 (( day += 146097 * (y / 400) ))
174 (( day += 365 * (y % 4) ))
176 (( day += 1461 * (y % 25) + 36524 * (y / 25) ))