OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib-1.10.0/] [newlib/] [libc/] [time/] [mktime.c] - Diff between revs 1010 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 1010 Rev 1765
/*
/*
 * mktime.c
 * mktime.c
 * Original Author:     G. Haley
 * Original Author:     G. Haley
 *
 *
 * Converts the broken-down time, expressed as local time, in the structure
 * Converts the broken-down time, expressed as local time, in the structure
 * pointed to by tim_p into a calendar time value. The original values of the
 * pointed to by tim_p into a calendar time value. The original values of the
 * tm_wday and tm_yday fields of the structure are ignored, and the original
 * tm_wday and tm_yday fields of the structure are ignored, and the original
 * values of the other fields have no restrictions. On successful completion
 * values of the other fields have no restrictions. On successful completion
 * the fields of the structure are set to represent the specified calendar
 * the fields of the structure are set to represent the specified calendar
 * time. Returns the specified calendar time. If the calendar time can not be
 * time. Returns the specified calendar time. If the calendar time can not be
 * represented, returns the value (time_t) -1.
 * represented, returns the value (time_t) -1.
 */
 */
 
 
/*
/*
FUNCTION
FUNCTION
<<mktime>>---convert time to arithmetic representation
<<mktime>>---convert time to arithmetic representation
 
 
INDEX
INDEX
        mktime
        mktime
 
 
ANSI_SYNOPSIS
ANSI_SYNOPSIS
        #include <time.h>
        #include <time.h>
        time_t mktime(struct tm *<[timp]>);
        time_t mktime(struct tm *<[timp]>);
 
 
TRAD_SYNOPSIS
TRAD_SYNOPSIS
        #include <time.h>
        #include <time.h>
        time_t mktime(<[timp]>)
        time_t mktime(<[timp]>)
        struct tm *<[timp]>;
        struct tm *<[timp]>;
 
 
DESCRIPTION
DESCRIPTION
<<mktime>> assumes the time at <[timp]> is a local time, and converts
<<mktime>> assumes the time at <[timp]> is a local time, and converts
its representation from the traditional representation defined by
its representation from the traditional representation defined by
<<struct tm>> into a representation suitable for arithmetic.
<<struct tm>> into a representation suitable for arithmetic.
 
 
<<localtime>> is the inverse of <<mktime>>.
<<localtime>> is the inverse of <<mktime>>.
 
 
RETURNS
RETURNS
If the contents of the structure at <[timp]> do not form a valid
If the contents of the structure at <[timp]> do not form a valid
calendar time representation, the result is <<-1>>.  Otherwise, the
calendar time representation, the result is <<-1>>.  Otherwise, the
result is the time, converted to a <<time_t>> value.
result is the time, converted to a <<time_t>> value.
 
 
PORTABILITY
PORTABILITY
ANSI C requires <<mktime>>.
ANSI C requires <<mktime>>.
 
 
<<mktime>> requires no supporting OS subroutines.
<<mktime>> requires no supporting OS subroutines.
*/
*/
 
 
#include <stdlib.h>
#include <stdlib.h>
#include <time.h>
#include <time.h>
 
 
#define _SEC_IN_MINUTE 60L
#define _SEC_IN_MINUTE 60L
#define _SEC_IN_HOUR 3600L
#define _SEC_IN_HOUR 3600L
#define _SEC_IN_DAY 86400L
#define _SEC_IN_DAY 86400L
 
 
static _CONST int DAYS_IN_MONTH[12] =
static _CONST int DAYS_IN_MONTH[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
 
#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])
#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])
 
 
static _CONST int _DAYS_BEFORE_MONTH[12] =
static _CONST int _DAYS_BEFORE_MONTH[12] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
 
 
#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0))
#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0))
#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365)
#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365)
 
 
static void
static void
validate_structure (tim_p)
validate_structure (tim_p)
     struct tm *tim_p;
     struct tm *tim_p;
{
{
  div_t res;
  div_t res;
  int days_in_feb = 28;
  int days_in_feb = 28;
 
 
  /* calculate time & date to account for out of range values */
  /* calculate time & date to account for out of range values */
  if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59)
  if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59)
    {
    {
      res = div (tim_p->tm_sec, 60);
      res = div (tim_p->tm_sec, 60);
      tim_p->tm_min += res.quot;
      tim_p->tm_min += res.quot;
      if ((tim_p->tm_sec = res.rem) < 0)
      if ((tim_p->tm_sec = res.rem) < 0)
        {
        {
          tim_p->tm_sec += 60;
          tim_p->tm_sec += 60;
          --tim_p->tm_min;
          --tim_p->tm_min;
        }
        }
    }
    }
 
 
  if (tim_p->tm_min < 0 || tim_p->tm_min > 59)
  if (tim_p->tm_min < 0 || tim_p->tm_min > 59)
    {
    {
      res = div (tim_p->tm_min, 60);
      res = div (tim_p->tm_min, 60);
      tim_p->tm_hour += res.quot;
      tim_p->tm_hour += res.quot;
      if ((tim_p->tm_min = res.rem) < 0)
      if ((tim_p->tm_min = res.rem) < 0)
        {
        {
          tim_p->tm_min += 60;
          tim_p->tm_min += 60;
          --tim_p->tm_hour;
          --tim_p->tm_hour;
        }
        }
    }
    }
 
 
  if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23)
  if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23)
    {
    {
      res = div (tim_p->tm_hour, 24);
      res = div (tim_p->tm_hour, 24);
      tim_p->tm_mday += res.quot;
      tim_p->tm_mday += res.quot;
      if ((tim_p->tm_hour = res.rem) < 0)
      if ((tim_p->tm_hour = res.rem) < 0)
        {
        {
          tim_p->tm_hour += 24;
          tim_p->tm_hour += 24;
          --tim_p->tm_mday;
          --tim_p->tm_mday;
        }
        }
    }
    }
 
 
  if (tim_p->tm_mon > 11)
  if (tim_p->tm_mon > 11)
    {
    {
      res = div (tim_p->tm_mon, 12);
      res = div (tim_p->tm_mon, 12);
      tim_p->tm_year += res.quot;
      tim_p->tm_year += res.quot;
      if ((tim_p->tm_mon = res.rem) < 0)
      if ((tim_p->tm_mon = res.rem) < 0)
        {
        {
          tim_p->tm_mon += 12;
          tim_p->tm_mon += 12;
          --tim_p->tm_year;
          --tim_p->tm_year;
        }
        }
    }
    }
 
 
  if (_DAYS_IN_YEAR (tim_p->tm_year) == 366)
  if (_DAYS_IN_YEAR (tim_p->tm_year) == 366)
    days_in_feb = 29;
    days_in_feb = 29;
 
 
  if (tim_p->tm_mday <= 0)
  if (tim_p->tm_mday <= 0)
    {
    {
      while (tim_p->tm_mday <= 0)
      while (tim_p->tm_mday <= 0)
        {
        {
          if (--tim_p->tm_mon == -1)
          if (--tim_p->tm_mon == -1)
            {
            {
              tim_p->tm_year--;
              tim_p->tm_year--;
              tim_p->tm_mon = 11;
              tim_p->tm_mon = 11;
              days_in_feb =
              days_in_feb =
                ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
                ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
                 29 : 28);
                 29 : 28);
            }
            }
          tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon);
          tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon);
        }
        }
    }
    }
  else
  else
    {
    {
      while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon))
      while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon))
        {
        {
          tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon);
          tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon);
          if (++tim_p->tm_mon == 12)
          if (++tim_p->tm_mon == 12)
            {
            {
              tim_p->tm_year++;
              tim_p->tm_year++;
              tim_p->tm_mon = 0;
              tim_p->tm_mon = 0;
              days_in_feb =
              days_in_feb =
                ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
                ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
                 29 : 28);
                 29 : 28);
            }
            }
        }
        }
    }
    }
}
}
 
 
time_t
time_t
mktime (tim_p)
mktime (tim_p)
     struct tm *tim_p;
     struct tm *tim_p;
{
{
  time_t tim = 0;
  time_t tim = 0;
  long days = 0;
  long days = 0;
  int year;
  int year;
 
 
  /* validate structure */
  /* validate structure */
  validate_structure (tim_p);
  validate_structure (tim_p);
 
 
  /* compute hours, minutes, seconds */
  /* compute hours, minutes, seconds */
  tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) +
  tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) +
    (tim_p->tm_hour * _SEC_IN_HOUR);
    (tim_p->tm_hour * _SEC_IN_HOUR);
 
 
  /* compute days in year */
  /* compute days in year */
  days += tim_p->tm_mday - 1;
  days += tim_p->tm_mday - 1;
  days += _DAYS_BEFORE_MONTH[tim_p->tm_mon];
  days += _DAYS_BEFORE_MONTH[tim_p->tm_mon];
  if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366)
  if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366)
    days++;
    days++;
 
 
  /* compute day of the year */
  /* compute day of the year */
  tim_p->tm_yday = days;
  tim_p->tm_yday = days;
 
 
  if (tim_p->tm_year > 10000
  if (tim_p->tm_year > 10000
      || tim_p->tm_year < -10000)
      || tim_p->tm_year < -10000)
    {
    {
      return (time_t) -1;
      return (time_t) -1;
    }
    }
 
 
  /* compute days in other years */
  /* compute days in other years */
  if (tim_p->tm_year > 70)
  if (tim_p->tm_year > 70)
    {
    {
      for (year = 70; year < tim_p->tm_year; year++)
      for (year = 70; year < tim_p->tm_year; year++)
        days += _DAYS_IN_YEAR (year);
        days += _DAYS_IN_YEAR (year);
    }
    }
  else if (tim_p->tm_year < 70)
  else if (tim_p->tm_year < 70)
    {
    {
      for (year = 69; year > tim_p->tm_year; year--)
      for (year = 69; year > tim_p->tm_year; year--)
        days -= _DAYS_IN_YEAR (year);
        days -= _DAYS_IN_YEAR (year);
      days -= _DAYS_IN_YEAR (year);
      days -= _DAYS_IN_YEAR (year);
    }
    }
 
 
  /* compute day of the week */
  /* compute day of the week */
  if ((tim_p->tm_wday = (days + 4) % 7) < 0)
  if ((tim_p->tm_wday = (days + 4) % 7) < 0)
    tim_p->tm_wday += 7;
    tim_p->tm_wday += 7;
 
 
  /* compute total seconds */
  /* compute total seconds */
  tim += (days * _SEC_IN_DAY);
  tim += (days * _SEC_IN_DAY);
 
 
  return tim;
  return tim;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.