summaryrefslogtreecommitdiff
path: root/time/strptime_l.c
diff options
context:
space:
mode:
Diffstat (limited to 'time/strptime_l.c')
-rw-r--r--time/strptime_l.c54
1 files changed, 22 insertions, 32 deletions
diff --git a/time/strptime_l.c b/time/strptime_l.c
index 5640ccecce..3a56947127 100644
--- a/time/strptime_l.c
+++ b/time/strptime_l.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -41,9 +41,7 @@
# define localtime_r my_localtime_r
static struct tm *localtime_r (const time_t *, struct tm *);
static struct tm *
-localtime_r (t, tp)
- const time_t *t;
- struct tm *tp;
+localtime_r (const time_t *t, struct tm *tp)
{
struct tm *l = localtime (t);
if (! l)
@@ -183,17 +181,13 @@ static const unsigned short int __mon_yday[2][13] =
# undef _NL_CURRENT_WORD
# define _NL_CURRENT_WORD(category, item) \
(current->values[_NL_ITEM_INDEX (item)].word)
-# define LOCALE_PARAM , locale
+# define LOCALE_PARAM , __locale_t locale
# define LOCALE_ARG , locale
-# define LOCALE_PARAM_PROTO , __locale_t locale
-# define LOCALE_PARAM_DECL __locale_t locale;
# define HELPER_LOCALE_ARG , current
# define ISSPACE(Ch) __isspace_l (Ch, locale)
#else
# define LOCALE_PARAM
# define LOCALE_ARG
-# define LOCALE_PARAM_DECL
-# define LOCALE_PARAM_PROTO
# define HELPER_LOCALE_ARG
# define ISSPACE(Ch) isspace (Ch)
#endif
@@ -241,12 +235,8 @@ internal_function
#else
static char *
#endif
-__strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
- const char *rp;
- const char *fmt;
- struct tm *tmp;
- void *statep;
- LOCALE_PARAM_DECL
+__strptime_internal (const char *rp, const char *fmt, struct tm *tmp,
+ void *statep LOCALE_PARAM)
{
#ifdef _LIBC
struct __locale_data *const current = locale->__locales[LC_TIME];
@@ -749,13 +739,21 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
rp++;
break;
case 'z':
- /* We recognize two formats: if two digits are given, these
- specify hours. If fours digits are used, minutes are
- also specified. */
+ /* We recognize four formats:
+ 1. Two digits specify hours.
+ 2. Four digits specify hours and minutes.
+ 3. Two digits, ':', and two digits specify hours and minutes.
+ 4. 'Z' is equivalent to +0000. */
{
val = 0;
while (ISSPACE (*rp))
++rp;
+ if (*rp == 'Z')
+ {
+ ++rp;
+ tm->tm_gmtoff = 0;
+ break;
+ }
if (*rp != '+' && *rp != '-')
return NULL;
bool neg = *rp++ == '-';
@@ -764,22 +762,18 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
{
val = val * 10 + *rp++ - '0';
++n;
+ if (*rp == ':' && n == 2 && isdigit (*(rp + 1)))
+ ++rp;
}
if (n == 2)
val *= 100;
else if (n != 4)
/* Only two or four digits recognized. */
return NULL;
- else
- {
- /* We have to convert the minutes into decimal. */
- if (val % 100 >= 60)
- return NULL;
- val = (val / 100) * 100 + ((val % 100) * 50) / 30;
- }
- if (val > 1200)
+ else if (val % 100 >= 60)
+ /* Minutes valid range is 0 through 59. */
return NULL;
- tm->tm_gmtoff = (val * 3600) / 100;
+ tm->tm_gmtoff = (val / 100) * 3600 + (val % 100) * 60;
if (neg)
tm->tm_gmtoff = -tm->tm_gmtoff;
}
@@ -1207,11 +1201,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
char *
-strptime (buf, format, tm LOCALE_PARAM)
- const char *buf;
- const char *format;
- struct tm *tm;
- LOCALE_PARAM_DECL
+strptime (const char *buf, const char *format, struct tm *tm LOCALE_PARAM)
{
return __strptime_internal (buf, format, tm, NULL LOCALE_ARG);
}