View | Details | Raw Unified | Return to bug 137307 | Differences between
and this patch

Collapse All | Expand All

(-)lib/libc/stdtime/strptime.3 (-3 / +1 lines)
Lines 164-172 Link Here
164
.Fa \&%U
164
.Fa \&%U
165
and
165
and
166
.Fa %W
166
.Fa %W
167
format specifiers accept any value within the range 00 to 53
167
format specifiers accept a two-digit decimal within the range 00 to 53.
168
without validating against other values supplied (like month
169
or day of the year, for example).
170
.Pp
168
.Pp
171
The
169
The
172
.Fa %Z
170
.Fa %Z
(-)lib/libc/stdtime/strptime.c (-7 / +80 lines)
Lines 56-65 Link Here
56
#include "libc_private.h"
56
#include "libc_private.h"
57
#include "timelocal.h"
57
#include "timelocal.h"
58
58
59
#include "tzfile.h"
60
59
static char * _strptime(const char *, const char *, struct tm *, int *, locale_t);
61
static char * _strptime(const char *, const char *, struct tm *, int *, locale_t);
60
62
61
#define	asizeof(a)	(sizeof (a) / sizeof ((a)[0]))
63
#define	asizeof(a)	(sizeof(a) / sizeof((a)[0]))
62
64
65
/*
66
 * Calculate the week day of the first day of a year.  Valid for
67
 * the Gregorian calendar, which began Sept 14, 1752 in the UK
68
 * and its colonies.  Ref:
69
 * http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week/
70
 */
71
72
static int
73
first_wday_of(int year)
74
{
75
	return (((2 * (3 - (year / 100) % 4)) + (year % 100) +
76
		((year % 100) / 4) + (isleap(year) ? 6 : 0) + 1) % 7);
77
}
78
79
63
static char *
80
static char *
64
_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
81
_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
65
		locale_t locale)
82
		locale_t locale)
Lines 66-74 Link Here
66
{
83
{
67
	char	c;
84
	char	c;
68
	const char *ptr;
85
	const char *ptr;
86
	int	day_offset = -1;
69
	int	i, len;
87
	int	i, len;
70
	int Ealternative, Oalternative;
88
	int Ealternative, Oalternative;
71
	struct lc_time_T *tptr = __get_current_time_locale(locale);
89
	const struct lc_time_T *tptr = __get_current_time_locale(locale);
90
	static int start_of_month[2][13] = {
91
		{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
92
		{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}};
72
93
73
	ptr = fmt;
94
	ptr = fmt;
74
	while (*ptr != 0) {
95
	while (*ptr != 0) {
Lines 303-308 Link Here
303
				return (NULL);
324
				return (NULL);
304
325
305
			tm->tm_wday = i;
326
			tm->tm_wday = i;
327
			if (day_offset >= 0 && (i - day_offset) != 0) {
328
				tm->tm_yday += i - day_offset;
329
				i = 0;
330
				while (tm->tm_yday >=
331
				    start_of_month[isleap(tm->tm_year + 1900)][i])
332
					i++;
333
				if (i > 12)
334
				{
335
					i = 1;
336
					tm->tm_yday -=
337
					    start_of_month[
338
					    isleap(tm->tm_year + 1900)][12];
339
					tm->tm_year++;
340
				}
341
				tm->tm_mon = i - 1;
342
				tm->tm_mday = tm->tm_yday -
343
				    start_of_month[isleap(tm->tm_year+1900)][i - 1] + 1;
344
			}
306
			buf += len;
345
			buf += len;
307
			break;
346
			break;
308
347
Lines 309-318 Link Here
309
		case 'U':
348
		case 'U':
310
		case 'W':
349
		case 'W':
311
			/*
350
			/*
312
			 * XXX This is bogus, as we can not assume any valid
351
			 * We expect that the year has already been
313
			 * information present in the tm structure at this
352
			 * parsed.
314
			 * point to calculate a real value, so just check the
315
			 * range for now.
316
			 */
353
			 */
317
			if (!isdigit_l((unsigned char)*buf, locale))
354
			if (!isdigit_l((unsigned char)*buf, locale))
318
				return (NULL);
355
				return (NULL);
Lines 327-332 Link Here
327
			if (i > 53)
364
			if (i > 53)
328
				return (NULL);
365
				return (NULL);
329
366
367
			/* Week numbers are 1-origin.  So that we can always
368
			 * return the date of a Sunday (or Monday), treat week
369
			 * 0 as week 1.
370
			 */
371
372
			if (i == 0)
373
				i = 1;
374
375
			if (c == 'U')
376
				day_offset = 0;   /* Sunday */
377
			else day_offset = 1;   /* Monday */
378
379
			/*
380
			 * Set the date to the first Sunday (or Monday)
381
			 * of the specified week of the year.
382
			 */
383
384
			tm->tm_yday = (7 - first_wday_of(tm->tm_year + 1900) +
385
			    day_offset) % 7 + (i-1) * 7;
386
			i = 0;
387
			while (tm->tm_yday >=
388
			    start_of_month[isleap(tm->tm_year + 1900)][i])
389
				i++;
390
			if (i > 12)
391
			{
392
				i = 1;
393
				tm->tm_yday -=
394
				    start_of_month[
395
				    isleap(tm->tm_year + 1900)][12];
396
				tm->tm_year++;
397
			}
398
			tm->tm_mon = i - 1;
399
			tm->tm_mday = tm->tm_yday -
400
			    start_of_month[isleap(tm->tm_year+1900)][i - 1] + 1;
401
			tm->tm_wday = day_offset;
402
330
			break;
403
			break;
331
404
332
		case 'w':
405
		case 'w':
Lines 546-552 Link Here
546
	return ((char *)buf);
619
	return ((char *)buf);
547
}
620
}
548
621
549
550
char *
622
char *
551
strptime_l(const char * __restrict buf, const char * __restrict fmt,
623
strptime_l(const char * __restrict buf, const char * __restrict fmt,
552
    struct tm * __restrict tm, locale_t loc)
624
    struct tm * __restrict tm, locale_t loc)
Lines 564-569 Link Here
564
636
565
	return (ret);
637
	return (ret);
566
}
638
}
639
567
char *
640
char *
568
strptime(const char * __restrict buf, const char * __restrict fmt,
641
strptime(const char * __restrict buf, const char * __restrict fmt,
569
    struct tm * __restrict tm)
642
    struct tm * __restrict tm)

Return to bug 137307