330b6a7dfc7d1fb83a418912c3a166c90832202b
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / time.c
1 /*
2  * Acess2 C Library
3  * - By John Hodge (thePowersGang)
4  *
5  * time.c
6  * - POSIX/stdc time functions
7  */
8 #include <time.h>
9 #include <acess/sys.h>
10 #include <string.h>
11 #include "timeconv.h"
12 #include <errno.h>
13
14 #define UNIX_TO_2K      ((30*365*3600*24) + (7*3600*24))        //Normal years + leap years
15
16 clock_t clock(void)
17 {
18         return _SysTimestamp();
19 }
20
21 time_t mktime(struct tm *timeptr)
22 {
23         time_t ret = seconds_since_y2k(
24                 timeptr->tm_year - 2000,
25                 timeptr->tm_mon,
26                 timeptr->tm_mday,
27                 timeptr->tm_hour,
28                 timeptr->tm_min,
29                 timeptr->tm_sec
30                 );
31         if( ret == 0 && errno ) {
32                 // Bad date
33         }
34         ret += UNIX_TO_2K;
35         
36         return ret;
37 }
38
39 time_t time(time_t *t)
40 {
41         time_t ret = _SysTimestamp() / 1000;
42         if(t)
43                 *t = ret;
44         return ret;
45 }
46
47 static struct tm        static_tm;
48
49 struct tm *localtime(const time_t *timer)
50 {
51         return localtime_r(timer, &static_tm);
52
53 }
54 struct tm *localtime_r(const time_t *timer, struct tm *ret)
55 {
56         // Hours, Mins, Seconds
57         int64_t days = get_days_since_y2k(*timer, &ret->tm_hour, &ret->tm_min, &ret->tm_sec);
58         
59         // Week day
60         ret->tm_wday = (days + 6) % 7;  // Sun = 0, 1 Jan 2000 was Sat (6)
61         
62         // Year and Day of Year
63         bool    is_ly;
64         ret->tm_year = 2000 + get_years_since_y2k(days, &is_ly, &ret->tm_yday);
65
66         // Month and Day of Month
67         get_month_day(ret->tm_yday, is_ly, &ret->tm_mon, &ret->tm_mday);
68         
69         ret->tm_isdst = 0;      // Fuck DST
70         
71         return ret;
72 }
73
74 static inline size_t MIN(size_t a, size_t b) { return a < b ? a : b; }
75 static size_t _puts(char * restrict s, size_t maxsize, size_t ofs, const char *str, size_t len)
76 {
77         if( s && ofs < maxsize ) {
78                 size_t  addlen = MIN(len, maxsize-1-ofs);
79                 memcpy(s+ofs, str, addlen);
80         }
81         return len;
82 }
83
84 size_t strftime(char*restrict s, size_t maxsize, const char*restrict format, const struct tm*restrict timeptr)
85 {
86         size_t  ofs = 0;
87
88         while( *format )
89         {
90                 const char *restrict start = format;
91                 while( *format && *format != '%' )
92                         format ++;
93                 if( format != start )
94                         ofs += _puts(s, maxsize, ofs, start, format-start);
95                 if( *format == 0 )
96                         break;
97                 format ++;
98                 switch(*format++)
99                 {
100                 case 0: format--;       break;
101                 case '%':       ofs += _puts(s, maxsize, ofs, format-1, 1);     break;
102                 case 'd':       // The day of the month as a decimal number (range 01 to 31).
103                         {
104                         char tmp[2] = {'0','0'};
105                         tmp[0] += (timeptr->tm_mday / 10) % 10;
106                         tmp[1] += timeptr->tm_mday % 10;
107                         ofs += _puts(s, maxsize, ofs, tmp, 2);
108                         }
109                         break;
110                 default:
111                         _SysDebug("TODO: strftime('...%%%c...')", format[-1]);
112                         break;
113                 }
114         }
115         
116         return ofs;
117 }

UCC git Repository :: git.ucc.asn.au