1# mktime.awk --- convert a canonical date representation
2#                into a timestamp
3# Arnold Robbins, arnold@gnu.org, Public Domain
4# May 1993
5
6BEGIN    \
7{
8    # Initialize table of month lengths
9    _tm_months[0,1] = _tm_months[1,1] = 31
10    _tm_months[0,2] = 28; _tm_months[1,2] = 29
11    _tm_months[0,3] = _tm_months[1,3] = 31
12    _tm_months[0,4] = _tm_months[1,4] = 30
13    _tm_months[0,5] = _tm_months[1,5] = 31
14    _tm_months[0,6] = _tm_months[1,6] = 30
15    _tm_months[0,7] = _tm_months[1,7] = 31
16    _tm_months[0,8] = _tm_months[1,8] = 31
17    _tm_months[0,9] = _tm_months[1,9] = 30
18    _tm_months[0,10] = _tm_months[1,10] = 31
19    _tm_months[0,11] = _tm_months[1,11] = 30
20    _tm_months[0,12] = _tm_months[1,12] = 31
21}
22# decide if a year is a leap year
23function _tm_isleap(year,    ret)
24{
25    ret = (year % 4 == 0 && year % 100 != 0) ||
26            (year % 400 == 0)
27
28    return ret
29}
30# convert a date into seconds
31function _tm_addup(a,    total, yearsecs, daysecs,
32                         hoursecs, i, j)
33{
34    hoursecs = 60 * 60
35    daysecs = 24 * hoursecs
36    yearsecs = 365 * daysecs
37
38    total = (a[1] - 1970) * yearsecs
39
40    # extra day for leap years
41    for (i = 1970; i < a[1]; i++)
42        if (_tm_isleap(i))
43            total += daysecs
44
45    j = _tm_isleap(a[1])
46    for (i = 1; i < a[2]; i++)
47        total += _tm_months[j, i] * daysecs
48
49    total += (a[3] - 1) * daysecs
50    total += a[4] * hoursecs
51    total += a[5] * 60
52    total += a[6]
53
54    return total
55}
56# mktime --- convert a date into seconds,
57#            compensate for time zone
58
59function mktime(str,    res1, res2, a, b, i, j, t, diff)
60{
61    i = split(str, a, " ")    # don't rely on FS
62
63    if (i != 6)
64        return -1
65
66    # force numeric
67    for (j in a)
68        a[j] += 0
69
70    # validate
71    if (a[1] < 1970 ||
72        a[2] < 1 || a[2] > 12 ||
73        a[3] < 1 || a[3] > 31 ||
74        a[4] < 0 || a[4] > 23 ||
75        a[5] < 0 || a[5] > 59 ||
76        a[6] < 0 || a[6] > 60 )
77            return -1
78
79    res1 = _tm_addup(a)
80    t = strftime("%Y %m %d %H %M %S", res1)
81
82    if (_tm_debug)
83        printf("(%s) -> (%s)\n", str, t) > "/dev/stderr"
84
85    split(t, b, " ")
86    res2 = _tm_addup(b)
87
88    diff = res1 - res2
89
90    if (_tm_debug)
91        printf("diff = %d seconds\n", diff) > "/dev/stderr"
92
93    res1 += diff
94
95    return res1
96}
97BEGIN  {
98    if (_tm_test) {
99        printf "Enter date as yyyy mm dd hh mm ss: "
100        getline _tm_test_date
101        t = mktime(_tm_test_date)
102        r = strftime("%Y %m %d %H %M %S", t)
103        printf "Got back (%s)\n", r
104    }
105}
106