blob: c5e115690a1855c9e2530eb95074c96739aade14 [file] [log] [blame]
Michael Teichgräberf35a0482008-07-09 08:27:22 -04001/*
2 * This routine converts time as follows.
3 * The epoch is 0000 Jan 1 1970 GMT.
4 * The argument time is in seconds since then.
5 * The localtime(t) entry returns a pointer to an array
6 * containing
7 *
8 * seconds (0-59)
9 * minutes (0-59)
10 * hours (0-23)
11 * day of month (1-31)
12 * month (0-11)
13 * year-1970
14 * weekday (0-6, Sun is 0)
15 * day of the year
16 * daylight savings flag
17 *
18 * The routine gets the daylight savings time from the environment.
19 *
20 * asctime(tvec))
21 * where tvec is produced by localtime
22 * returns a ptr to a character string
23 * that has the ascii time in the form
24 *
25 * \\
26 * Thu Jan 01 00:00:00 GMT 1970n0
27 * 012345678901234567890123456789
28 * 0 1 2
29 *
30 * ctime(t) just calls localtime, then asctime.
31 */
32
rscfd04aac2003-11-23 18:12:54 +000033#include <u.h>
34#include <libc.h>
35
Michael Teichgräberf35a0482008-07-09 08:27:22 -040036#include "zoneinfo.h"
rscfd04aac2003-11-23 18:12:54 +000037
Michael Teichgräberf35a0482008-07-09 08:27:22 -040038static char dmsize[12] =
39{
40 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
41};
42
43#define dysize ctimedysize
44static int dysize(int);
45static void ct_numb(char*, int);
46
47char*
48ctime(long t)
49{
50 return asctime(localtime(t));
51}
52
53Tm*
54localtime(long tim)
55{
56 Tinfo ti;
57 Tm *ct;
58
59 if (zonelookuptinfo(&ti, tim)!=-1) {
60 ct = gmtime(tim+ti.tzoff);
61 strncpy(ct->zone, ti.zone, sizeof ct->zone);
62 ct->zone[sizeof ct->zone-1] = 0;
63 ct->tzoff = ti.tzoff;
64 return ct;
65 }
66 return gmtime(tim);
67}
68
69Tm*
70gmtime(long tim)
71{
72 int d0, d1;
73 long hms, day;
74 static Tm xtime;
75
76 /*
77 * break initial number into days
78 */
79 hms = tim % 86400L;
80 day = tim / 86400L;
81 if(hms < 0) {
82 hms += 86400L;
83 day -= 1;
84 }
85
86 /*
87 * generate hours:minutes:seconds
88 */
89 xtime.sec = hms % 60;
90 d1 = hms / 60;
91 xtime.min = d1 % 60;
92 d1 /= 60;
93 xtime.hour = d1;
94
95 /*
96 * day is the day number.
97 * generate day of the week.
98 * The addend is 4 mod 7 (1/1/1970 was Thursday)
99 */
100
101 xtime.wday = (day + 7340036L) % 7;
102
103 /*
104 * year number
105 */
106 if(day >= 0)
107 for(d1 = 1970; day >= dysize(d1); d1++)
108 day -= dysize(d1);
109 else
110 for (d1 = 1970; day < 0; d1--)
111 day += dysize(d1-1);
112 xtime.year = d1-1900;
113 xtime.yday = d0 = day;
114
115 /*
116 * generate month
117 */
118
119 if(dysize(d1) == 366)
120 dmsize[1] = 29;
121 for(d1 = 0; d0 >= dmsize[d1]; d1++)
122 d0 -= dmsize[d1];
123 dmsize[1] = 28;
124 xtime.mday = d0 + 1;
125 xtime.mon = d1;
126 strcpy(xtime.zone, "GMT");
127 return &xtime;
rscfd04aac2003-11-23 18:12:54 +0000128}
129
130char*
131asctime(Tm *t)
132{
133 char *ncp;
134 static char cbuf[30];
135
136 strcpy(cbuf, "Thu Jan 01 00:00:00 GMT 1970\n");
137 ncp = &"SunMonTueWedThuFriSat"[t->wday*3];
138 cbuf[0] = *ncp++;
139 cbuf[1] = *ncp++;
140 cbuf[2] = *ncp;
141 ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[t->mon*3];
142 cbuf[4] = *ncp++;
143 cbuf[5] = *ncp++;
144 cbuf[6] = *ncp;
145 ct_numb(cbuf+8, t->mday);
146 ct_numb(cbuf+11, t->hour+100);
147 ct_numb(cbuf+14, t->min+100);
148 ct_numb(cbuf+17, t->sec+100);
149 ncp = t->zone;
rscfd04aac2003-11-23 18:12:54 +0000150 cbuf[20] = *ncp++;
151 cbuf[21] = *ncp++;
152 cbuf[22] = *ncp;
153 if(t->year >= 100) {
154 cbuf[24] = '2';
155 cbuf[25] = '0';
156 }
157 ct_numb(cbuf+26, t->year+100);
158 return cbuf;
159}
160
Michael Teichgräberf35a0482008-07-09 08:27:22 -0400161static
162int
163dysize(int y)
rscfd04aac2003-11-23 18:12:54 +0000164{
Michael Teichgräberf35a0482008-07-09 08:27:22 -0400165
166 if(y%4 == 0 && (y%100 != 0 || y%400 == 0))
167 return 366;
168 return 365;
169}
170
171static
172void
173ct_numb(char *cp, int n)
174{
175
176 cp[0] = ' ';
177 if(n >= 10)
178 cp[0] = (n/10)%10 + '0';
179 cp[1] = n%10 + '0';
rscfd04aac2003-11-23 18:12:54 +0000180}
181