Subversion Repositories Kolibri OS

Rev

Rev 4921 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.  * localtime_r.c
  3.  * Original Author: Adapted from tzcode maintained by Arthur David Olson.
  4.  * Modifications:
  5.  * - Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston
  6.  * - Fixed bug in mday computations - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
  7.  * - Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
  8.  * - Implement localtime_r() with gmtime_r() and the conditional code moved
  9.  *   from _mktm_r() - 05/09/14, Freddie Chopin <freddie_chopin@op.pl>
  10.  *
  11.  * Converts the calendar time pointed to by tim_p into a broken-down time
  12.  * expressed as local time. Returns a pointer to a structure containing the
  13.  * broken-down time.
  14.  */
  15.  
  16. #include "local.h"
  17.  
  18. struct tm *
  19. _DEFUN (localtime_r, (tim_p, res),
  20.         _CONST time_t *__restrict tim_p _AND
  21.         struct tm *__restrict res)
  22. {
  23.   long offset;
  24.   int hours, mins, secs;
  25.   int year;
  26.   __tzinfo_type *_CONST tz = __gettzinfo ();
  27.   _CONST int *ip;
  28.  
  29.   res = gmtime_r (tim_p, res);
  30.  
  31.   year = res->tm_year + YEAR_BASE;
  32.   ip = __month_lengths[isleap(year)];
  33.  
  34.   TZ_LOCK;
  35.   _tzset_unlocked ();
  36.   if (_daylight)
  37.     {
  38.       if (year == tz->__tzyear || __tzcalc_limits (year))
  39.         res->tm_isdst = (tz->__tznorth
  40.           ? (*tim_p >= tz->__tzrule[0].change
  41.           && *tim_p < tz->__tzrule[1].change)
  42.           : (*tim_p >= tz->__tzrule[0].change
  43.           || *tim_p < tz->__tzrule[1].change));
  44.       else
  45.         res->tm_isdst = -1;
  46.     }
  47.   else
  48.     res->tm_isdst = 0;
  49.  
  50.   offset = (res->tm_isdst == 1
  51.     ? tz->__tzrule[1].offset
  52.     : tz->__tzrule[0].offset);
  53.  
  54.   hours = (int) (offset / SECSPERHOUR);
  55.   offset = offset % SECSPERHOUR;
  56.  
  57.   mins = (int) (offset / SECSPERMIN);
  58.   secs = (int) (offset % SECSPERMIN);
  59.  
  60.   res->tm_sec -= secs;
  61.   res->tm_min -= mins;
  62.   res->tm_hour -= hours;
  63.  
  64.   if (res->tm_sec >= SECSPERMIN)
  65.     {
  66.       res->tm_min += 1;
  67.       res->tm_sec -= SECSPERMIN;
  68.     }
  69.   else if (res->tm_sec < 0)
  70.     {
  71.       res->tm_min -= 1;
  72.       res->tm_sec += SECSPERMIN;
  73.     }
  74.   if (res->tm_min >= MINSPERHOUR)
  75.     {
  76.       res->tm_hour += 1;
  77.       res->tm_min -= MINSPERHOUR;
  78.     }
  79.   else if (res->tm_min < 0)
  80.     {
  81.       res->tm_hour -= 1;
  82.       res->tm_min += MINSPERHOUR;
  83.     }
  84.   if (res->tm_hour >= HOURSPERDAY)
  85.     {
  86.       ++res->tm_yday;
  87.       ++res->tm_wday;
  88.       if (res->tm_wday > 6)
  89.         res->tm_wday = 0;
  90.       ++res->tm_mday;
  91.       res->tm_hour -= HOURSPERDAY;
  92.       if (res->tm_mday > ip[res->tm_mon])
  93.         {
  94.           res->tm_mday -= ip[res->tm_mon];
  95.           res->tm_mon += 1;
  96.           if (res->tm_mon == 12)
  97.             {
  98.               res->tm_mon = 0;
  99.               res->tm_year += 1;
  100.               res->tm_yday = 0;
  101.             }
  102.         }
  103.     }
  104.   else if (res->tm_hour < 0)
  105.     {
  106.       res->tm_yday -= 1;
  107.       res->tm_wday -= 1;
  108.       if (res->tm_wday < 0)
  109.         res->tm_wday = 6;
  110.       res->tm_mday -= 1;
  111.       res->tm_hour += 24;
  112.       if (res->tm_mday == 0)
  113.         {
  114.           res->tm_mon -= 1;
  115.           if (res->tm_mon < 0)
  116.             {
  117.               res->tm_mon = 11;
  118.               res->tm_year -= 1;
  119.               res->tm_yday = 364 + isleap(res->tm_year + YEAR_BASE);
  120.             }
  121.           res->tm_mday = ip[res->tm_mon];
  122.         }
  123.     }
  124.   TZ_UNLOCK;
  125.  
  126.   return (res);
  127. }
  128.