From a39e85d2ff83b4e5413a41fbb9029dee5ec732dd Mon Sep 17 00:00:00 2001
From: patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>
Date: Sat, 8 Aug 2009 16:54:36 +0000
Subject: [PATCH] Fix various errors in time manipulation routines

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2015 42af7a65-404d-4744-a932-0658087f49c3
---
 lib/lib_daysbeforemonth.c |  2 +-
 lib/lib_gmtimer.c         | 32 ++++++++++++++++++--------------
 lib/lib_strftime.c        |  2 +-
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/lib/lib_daysbeforemonth.c b/lib/lib_daysbeforemonth.c
index e9c4d0026b..718668bd18 100644
--- a/lib/lib_daysbeforemonth.c
+++ b/lib/lib_daysbeforemonth.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * lib/lib_daysbeforemonth.c
  *
- *   Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/lib/lib_gmtimer.c b/lib/lib_gmtimer.c
index 03e1a20588..e7514fd1a8 100644
--- a/lib/lib_gmtimer.c
+++ b/lib/lib_gmtimer.c
@@ -177,9 +177,9 @@ static void clock_utc2calendar(time_t days, int *year, int *month, int *day)
    * following:
    */
 
-  value = days  / (4*365 + 1);  /* Number of 4-years periods */
-  days -= value * (4*365 + 1);  /* Remaining days */
-  value = 70 + (value << 2);    /* 1970 plus the 4 year groups */
+  value   = days  / (4*365 + 1);  /* Number of 4-years periods since the epoch*/
+  days   -= value * (4*365 + 1);  /* Remaining days */
+  value <<= 2;                    /* Years since the epoch */
 
   /* Then we will brute force the next 0-3 years */
 
@@ -212,7 +212,7 @@ static void clock_utc2calendar(time_t days, int *year, int *month, int *day)
 
   /* At this point, value has the year and days has number days into this year */
 
-  *year = value;
+  *year = 1970 + value;
 
   /* Handle the month (zero based) */
 
@@ -225,18 +225,20 @@ static void clock_utc2calendar(time_t days, int *year, int *month, int *day)
 
       value = (min + max) >> 1;
 
-      /* Get the number of days that occurred before the beginning month
+      /* Get the number of days that occurred before the beginning of the month
        * following the midpoint.
       */
 
       tmp = clock_daysbeforemonth(value + 1, leapyear);
 
-      /* Does that equal or exceed the number of days we have remaining? */
+      /* Does the number of days before this month that equal or exceed the
+       * number of days we have remaining?
+       */
 
       if (tmp >= days)
         {
-          /* Yes.. then the month we want is somewhere between 'min' and the.
-           * midpoint, 'value'.  Check if it is the midpoint.
+          /* Yes.. then the month we want is somewhere from 'min' and to the
+           * midpoint, 'value'.  Could it be the midpoint?
            */
 
           tmp = clock_daysbeforemonth(value, leapyear);
@@ -262,15 +264,17 @@ static void clock_utc2calendar(time_t days, int *year, int *month, int *day)
     }
   while (min < max);
 
-  /* Subtract the number of days in the selected month */
+  /* The selected month number is in min (and max). Subtract the number of days in the
+   * selected month
+   */
 
-  days -= clock_daysbeforemonth(value, leapyear);
+  days -= clock_daysbeforemonth(min, leapyear);
 
   /* At this point, value has the month into this year (zero based) and days has
    * number of days into this month (zero based)
    */
 
-  *month = value;    /* Zero based */
+  *month = min + 1;  /* 1-based */
   *day   = days + 1; /* 1-based */
 }
 
@@ -329,9 +333,9 @@ struct tm *gmtime_r(const time_t *clock, struct tm *result)
 
   /* Then return the struct tm contents */
 
-  result->tm_year = (int)year - 1900;
-  result->tm_mon  = (int)month - 1;
-  result->tm_mday = (int)day;
+  result->tm_year = (int)year - 1900; /* Relative to 1900 */
+  result->tm_mon  = (int)month - 1;   /* zero-based */
+  result->tm_mday = (int)day;         /* one-based */
   result->tm_hour = (int)hour;
   result->tm_min  = (int)min;
   result->tm_sec  = (int)sec;
diff --git a/lib/lib_strftime.c b/lib/lib_strftime.c
index 0085869739..7eed7d5a67 100644
--- a/lib/lib_strftime.c
+++ b/lib/lib_strftime.c
@@ -214,7 +214,7 @@ size_t strftime(char *s, size_t max, const char *format, const struct tm *tm)
 
            case 'C':
              {
-               len = snprintf(dest, chleft, "%02d", tm->tm_year);
+               len = snprintf(dest, chleft, "%02d", tm->tm_year % 100);
              }
              break;
 
-- 
GitLab