1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
45:
46: 47: 48: 49: 50: 51:
52:
53: #include <basic.h>
54: #include <errno.h>
55: #include <tk/tkernel.h>
56: #include <t2ex/datetime.h>
57: #include "internal.h"
58:
59: LOCAL BOOL chkDST( const struct tm* tm, union dsttimespec tspec, BOOL start )
60: {
61: int i;
62: long v, w;
63:
64: switch (tspec.j.type) {
65: case DSTTIMESPEC_JULIAN_NL:
66: if (isleap(tm->tm_year + 1900)
67: && tm->tm_yday > (_dt_mdays[0] + _dt_mdays[1])) {
68: v = (tm->tm_yday - 1) * 24 * 60 * 60 + tm->tm_hour * 60 * 60
69: + tm->tm_min * 60 + tm->tm_sec;
70: return start ? (v >= tspec.j.offset) : (v <= tspec.j.offset);
71: }
72:
73:
74: case DSTTIMESPEC_JULIAN:
75: v = tm->tm_yday * 24 * 60 * 60 + tm->tm_hour * 60 * 60
76: + tm->tm_min * 60 + tm->tm_sec;
77: return start ? (v >= tspec.j.offset) : (v <= tspec.j.offset);
78:
79: case DSTTIMESPEC_MWD:
80: if (tm->tm_mon + 1 != tspec.m.m) {
81: return start ? (tm->tm_mon + 1 > tspec.m.m) : (tm->tm_mon + 1 < tspec.m.m);
82: }
83:
84: w = (tm->tm_wday - (tm->tm_mday - 1) % 7 + 7) % 7;
85: v = (tspec.m.d - w + 7) % 7;
86:
87:
88: w = (v + 7 * (tspec.m.n - 1));
89: for (i = 0; i < tm->tm_mon; i++) {
90: w += _dt_mdays[i];
91: }
92:
93: w = w * 24 * 60 * 60 + tspec.m.offset;
94: v = tm->tm_yday * 24 * 60 * 60 + tm->tm_hour * 60 * 60
95: + tm->tm_min * 60 + tm->tm_sec;
96: return start ? (v >= w) : (v <= w);
97:
98: default:
99: return FALSE;
100: }
101: }
102:
103: Inline BOOL isDST( struct tm* tm, const struct tzinfo* tz )
104: {
105: if (tz->daylight) {
106: return FALSE;
107: }
108:
109: return chkDST(tm, tz->dst_start, TRUE) && chkDST(tm, tz->dst_end, FALSE);
110: }
111:
112: EXPORT ER dt_localtime_us( SYSTIM_U tim_u, const struct tzinfo* tz, struct tm* result )
113: {
114: struct tzinfo systz;
115: ER er;
116:
117: if (tz == NULL) {
118:
119: er = dt_getsystz(&systz);
120: if (er < E_OK) {
121: return er;
122: }
123: tz = &systz;
124: }
125:
126:
127: er = dt_gmtime_us(tim_u - ((SYSTIM_U)tz->offset) * 1000000, result);
128: if (er < E_OK) {
129: return er;
130: }
131:
132:
133: if (!isDST(result, tz)) {
134: result->tm_isdst = 0;
135: return E_OK;
136: }
137:
138:
139: er = dt_gmtime_us(tim_u - ((SYSTIM_U)tz->dst_offset) * 1000000, result);
140: if (er < E_OK) {
141: return er;
142: }
143:
144: result->tm_isdst = 1;
145: return E_OK;
146: }
147:
148: EXPORT ER dt_localtime( time_t tims, const struct tzinfo* tz, struct tm* result )
149: {
150: return dt_localtime_us(s_to_us(tims), tz, result);
151: }
152:
153: EXPORT ER dt_localtime_ms( const SYSTIM* tim, const struct tzinfo* tz, struct tm* result )
154: {
155: return dt_localtime_us(ms_to_us(tim), tz, result);
156: }