10 #define sscanf siscanf /* avoid to pull in FP functions. */
12 #define TZNAME_MIN 3 /* POSIX min TZ abbr size local def */
13 #define TZNAME_MAX 10 /* POSIX max TZ abbr size local def */
15 static char __tzname_std
[TZNAME_MAX
+ 2];
16 static char __tzname_dst
[TZNAME_MAX
+ 2];
17 static char *prev_tzenv
= NULL
;
20 _tzset_unlocked_r (struct _reent
*reent_ptr
)
23 unsigned short hh
, mm
, ss
, m
, w
, d
;
26 long offset0
, offset1
;
27 __tzinfo_type
*tz
= __gettzinfo ();
28 struct __tzrule_struct default_tzrule
= {'J', 0, 0, 0, 0, (time_t)0, 0L };
30 if ((tzenv
= _getenv_r (reent_ptr
, "TZ")) == NULL
)
36 tz
->__tzrule
[0] = default_tzrule
;
37 tz
->__tzrule
[1] = default_tzrule
;
43 if (prev_tzenv
!= NULL
&& strcmp(tzenv
, prev_tzenv
) == 0)
47 prev_tzenv
= _malloc_r (reent_ptr
, strlen(tzenv
) + 1);
48 if (prev_tzenv
!= NULL
)
49 strcpy (prev_tzenv
, tzenv
);
51 /* default to unnamed UTC in case of error */
56 tz
->__tzrule
[0] = default_tzrule
;
57 tz
->__tzrule
[1] = default_tzrule
;
59 /* ignore implementation-specific format specifier */
63 /* allow POSIX angle bracket < > quoted signed alphanumeric tz abbr e.g. <MESZ+0330> */
68 /* quit if no items, too few or too many chars, or no close quote '>' */
69 if (sscanf (tzenv
, "%11[-+0-9A-Za-z]%n", __tzname_std
, &n
) <= 0
70 || n
< TZNAME_MIN
|| TZNAME_MAX
< n
|| '>' != tzenv
[n
])
73 ++tzenv
; /* bump for close quote '>' */
77 /* allow POSIX unquoted alphabetic tz abbr e.g. MESZ */
78 if (sscanf (tzenv
, "%11[A-Za-z]%n", __tzname_std
, &n
) <= 0
79 || n
< TZNAME_MIN
|| TZNAME_MAX
< n
)
91 else if (*tzenv
== '+')
97 if (sscanf (tzenv
, "%hu%n:%hu%n:%hu%n", &hh
, &n
, &mm
, &n
, &ss
, &n
) < 1)
100 offset0
= sign
* (ss
+ SECSPERMIN
* mm
+ SECSPERHOUR
* hh
);
103 /* allow POSIX angle bracket < > quoted signed alphanumeric tz abbr e.g. <MESZ+0330> */
108 /* quit if no items, too few or too many chars, or no close quote '>' */
109 if (sscanf (tzenv
, "%11[-+0-9A-Za-z]%n", __tzname_dst
, &n
) <= 0 && tzenv
[0] == '>')
111 _tzname
[0] = __tzname_std
;
112 _tzname
[1] = _tzname
[0];
113 tz
->__tzrule
[0].offset
= offset0
;
117 else if (n
< TZNAME_MIN
|| TZNAME_MAX
< n
|| '>' != tzenv
[n
])
122 ++tzenv
; /* bump for close quote '>' */
126 /* allow POSIX unquoted alphabetic tz abbr e.g. MESZ */
127 if (sscanf (tzenv
, "%11[A-Za-z]%n", __tzname_dst
, &n
) <= 0)
129 _tzname
[0] = __tzname_std
;
130 _tzname
[1] = _tzname
[0];
131 tz
->__tzrule
[0].offset
= offset0
;
135 else if (n
< TZNAME_MIN
|| TZNAME_MAX
< n
)
143 /* otherwise we have a dst name, look for the offset */
150 else if (*tzenv
== '+')
158 if (sscanf (tzenv
, "%hu%n:%hu%n:%hu%n", &hh
, &n
, &mm
, &n
, &ss
, &n
) <= 0)
159 offset1
= offset0
- 3600;
161 offset1
= sign
* (ss
+ SECSPERMIN
* mm
+ SECSPERHOUR
* hh
);
165 for (i
= 0; i
< 2; ++i
)
172 if (sscanf (tzenv
, "M%hu%n.%hu%n.%hu%n", &m
, &n
, &w
, &n
, &d
, &n
) != 3 ||
173 m
< 1 || m
> 12 || w
< 1 || w
> 5 || d
> 6)
176 tz
->__tzrule
[i
].ch
= 'M';
177 tz
->__tzrule
[i
].m
= m
;
178 tz
->__tzrule
[i
].n
= w
;
179 tz
->__tzrule
[i
].d
= d
;
194 d
= strtoul (tzenv
, &end
, 10);
196 /* if unspecified, default to US settings */
197 /* From 1987-2006, US was M4.1.0,M10.5.0, but starting in 2007 is
198 * M3.2.0,M11.1.0 (2nd Sunday March through 1st Sunday November) */
203 tz
->__tzrule
[0].ch
= 'M';
204 tz
->__tzrule
[0].m
= 3;
205 tz
->__tzrule
[0].n
= 2;
206 tz
->__tzrule
[0].d
= 0;
210 tz
->__tzrule
[1].ch
= 'M';
211 tz
->__tzrule
[1].m
= 11;
212 tz
->__tzrule
[1].n
= 1;
213 tz
->__tzrule
[1].d
= 0;
218 tz
->__tzrule
[i
].ch
= ch
;
219 tz
->__tzrule
[i
].d
= d
;
225 /* default time is 02:00:00 am */
232 if (sscanf (tzenv
, "/%hu%n:%hu%n:%hu%n", &hh
, &n
, &mm
, &n
, &ss
, &n
) <= 0)
234 /* error in time format, restore tz rules to default and return */
235 tz
->__tzrule
[0] = default_tzrule
;
236 tz
->__tzrule
[1] = default_tzrule
;
240 tz
->__tzrule
[i
].s
= ss
+ SECSPERMIN
* mm
+ SECSPERHOUR
* hh
;
245 tz
->__tzrule
[0].offset
= offset0
;
246 tz
->__tzrule
[1].offset
= offset1
;
247 _tzname
[0] = __tzname_std
;
248 _tzname
[1] = __tzname_dst
;
249 __tzcalc_limits (tz
->__tzyear
);
250 _timezone
= tz
->__tzrule
[0].offset
;
251 _daylight
= tz
->__tzrule
[0].offset
!= tz
->__tzrule
[1].offset
;
255 _tzset_r (struct _reent
*reent_ptr
)
258 _tzset_unlocked_r (reent_ptr
);