Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Make mktime64() correct the incoming tm struct as ISO C requires. [go…

…oglecode 49]

From bugzilla.rw@gmail.com
  • Loading branch information...
commit 0f1670b73f015b0bfacc426843ee06c7ed4cf28e 1 parent 2c66756
@schwern authored
Showing with 46 additions and 5 deletions.
  1. +34 −0 t/mktime64.t.c
  2. +10 −3 time64.c
  3. +2 −2 time64.h
View
34 t/mktime64.t.c
@@ -12,6 +12,7 @@ int main(void) {
struct TM date;
Time64_T time;
+ /* Some basic round trip mktime64 tests */
mktime64_ok((Time64_T)0);
mktime64_ok((Time64_T)1);
mktime64_ok((Time64_T)-1);
@@ -24,11 +25,44 @@ int main(void) {
mktime64_ok((Time64_T)-2147483647);
mktime64_ok((Time64_T)2147483647);
+
/* Test timelocal64 alias to mktime64 */
time = 12345;
localtime64_r(&time, &date);
is_Int64( mktime64(&date), timelocal64(&date), "timelocal64 alias" );
+
+ /* Test that mktime64 accepts and corrects out of bound dates */
+ /* The original values of the tm_wday and tm_yday components of the
+ * structure are ignored, and the original values of the other components
+ * are not restricted to the ranges described in <time.h>.
+ * http://www.opengroup.org/onlinepubs/009695399/functions/mktime.html
+ */
+ date.tm_mday = 35;
+
+ time = 12344678900LL; /* Thu Mar 9 21:28:20 2361 */
+ localtime64_r(&time, &date);
+
+ /* Feb 37 == Mar 9 */
+ date.tm_mon = 1;
+ date.tm_mday = 37;
+ date.tm_wday = 9; /* deliberately wrong week day */
+ date.tm_yday = 487; /* and wrong year day */
+
+ /* Upon successful completion, the values of the tm_wday and tm_yday
+ * components of the structure shall be set appropriately, and the other
+ * components are set to represent the specified time since the Epoch,
+ * but with their values forced to the ranges indicated in the <time.h>
+ * entry; the final value of tm_mday shall not be set until tm_mon and
+ * tm_year are determined.
+ * http://www.opengroup.org/onlinepubs/009695399/functions/mktime.html
+ */
+ is_Int64( mktime64(&date), time, "mktime64(%lld)", time );
+ is_int( date.tm_mon, 2, "tm_mon corrected" );
+ is_int( date.tm_mday, 9, "tm_mday corrected" );
+ is_int( date.tm_yday, 67,"tm_yday corrected" );
+ is_int( date.tm_wday, 4, "tm_wday corrected" );
+
done_testing();
return 0;
}
View
13 time64.c
@@ -515,7 +515,7 @@ static Time64_T seconds_between_years(Year left_year, Year right_year) {
}
-Time64_T mktime64(const struct TM *input_date) {
+Time64_T mktime64(struct TM *input_date) {
struct tm safe_date;
struct TM date;
Time64_T time;
@@ -524,7 +524,11 @@ Time64_T mktime64(const struct TM *input_date) {
if( date_in_safe_range(input_date, &SYSTEM_MKTIME_MIN, &SYSTEM_MKTIME_MAX) )
{
copy_TM64_to_tm(input_date, &safe_date);
- return (Time64_T)mktime(&safe_date);
+ time = (Time64_T)mktime(&safe_date);
+
+ /* Correct the possibly out of bound input date */
+ copy_tm_to_TM64(&safe_date, input_date);
+ return time;
}
/* Have to make the year safe in date else it won't fit in safe_date */
@@ -534,6 +538,9 @@ Time64_T mktime64(const struct TM *input_date) {
time = (Time64_T)mktime(&safe_date);
+ /* Correct the user's possibly out of bound input date */
+ copy_tm_to_TM64(&safe_date, input_date);
+
time += seconds_between_years(year, (Year)(safe_date.tm_year + 1900));
return time;
@@ -541,7 +548,7 @@ Time64_T mktime64(const struct TM *input_date) {
/* Because I think mktime() is a crappy name */
-Time64_T timelocal64(const struct TM *date) {
+Time64_T timelocal64(struct TM *date) {
return mktime64(date);
}
View
4 time64.h
@@ -53,8 +53,8 @@ char *ctime64 (const Time64_T*);
char *ctime64_r (const Time64_T*, char*);
Time64_T timegm64 (const struct TM *);
-Time64_T mktime64 (const struct TM *);
-Time64_T timelocal64 (const struct TM *);
+Time64_T mktime64 (struct TM *);
+Time64_T timelocal64 (struct TM *);
/* Not everyone has gm/localtime_r(), provide a replacement */
Please sign in to comment.
Something went wrong with that request. Please try again.