The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/clock_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: clock_subr.c,v 1.6 2016/08/26 07:09:56 guenther Exp $ */
    2 /*      $NetBSD: clock_subr.c,v 1.3 1997/03/15 18:11:16 is Exp $        */
    3 
    4 /*
    5  * Copyright (c) 1988 University of Utah.
    6  * Copyright (c) 1982, 1990, 1993
    7  *      The Regents of the University of California.  All rights reserved.
    8  *
    9  * This code is derived from software contributed to Berkeley by
   10  * the Systems Programming Group of the University of Utah Computer
   11  * Science Department.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  * from: Utah $Hdr: clock.c 1.18 91/01/21$
   38  *
   39  *      @(#)clock.c     8.2 (Berkeley) 1/12/94
   40  */
   41 
   42 /*
   43  * Generic routines to convert between a POSIX date
   44  * (seconds since 1/1/1970) and yr/mo/day/hr/min/sec
   45  * Derived from arch/hp300/hp300/clock.c
   46  */
   47 
   48 #include <sys/types.h>
   49 #include <sys/time.h>
   50 #include <sys/systm.h>
   51 
   52 static inline int leapyear(int year);
   53 #define FEBRUARY        2
   54 #define days_in_year(a)         (leapyear(a) ? 366 : 365)
   55 #define days_in_month(a)        (month_days[(a) - 1])
   56 
   57 static const int month_days[12] = {
   58         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
   59 };
   60 
   61 /*
   62  * This inline avoids some unnecessary modulo operations
   63  * as compared with the usual macro:
   64  *   ( ((year % 4) == 0 &&
   65  *      (year % 100) != 0) ||
   66  *     ((year % 400) == 0) )
   67  * It is otherwise equivalent.
   68  */
   69 static inline int
   70 leapyear(int year)
   71 {
   72         int rv = 0;
   73 
   74         if ((year & 3) == 0) {
   75                 rv = 1;
   76                 if ((year % 100) == 0) {
   77                         rv = 0;
   78                         if ((year % 400) == 0)
   79                                 rv = 1;
   80                 }
   81         }
   82         return (rv);
   83 }
   84 
   85 time_t
   86 clock_ymdhms_to_secs(struct clock_ymdhms *dt)
   87 {
   88         time_t secs;
   89         int i, year, days;
   90 
   91         year = dt->dt_year;
   92 
   93         /*
   94          * Compute days since start of time.
   95          * First from years, then from months.
   96          */
   97         days = 0;
   98         for (i = POSIX_BASE_YEAR; i < year; i++)
   99                 days += days_in_year(i);
  100         if (leapyear(year) && dt->dt_mon > FEBRUARY)
  101                 days++;
  102 
  103         /* Months */
  104         for (i = 1; i < dt->dt_mon; i++)
  105                 days += days_in_month(i);
  106         days += (dt->dt_day - 1);
  107 
  108         /* Add hours, minutes, seconds. */
  109         secs = (time_t)((days
  110             * 24 + dt->dt_hour)
  111             * 60 + dt->dt_min)
  112             * 60 + dt->dt_sec;
  113 
  114         return (secs);
  115 }
  116 
  117 /* This function uses a copy of month_days[] */
  118 #undef  days_in_month
  119 #define days_in_month(a)        (mthdays[(a) - 1])
  120 
  121 void
  122 clock_secs_to_ymdhms(time_t secs, struct clock_ymdhms *dt)
  123 {
  124         int mthdays[12];
  125         int i, days;
  126         int rsec;       /* remainder seconds */
  127 
  128         memcpy(mthdays, month_days, sizeof(mthdays));
  129 
  130         days = secs / SECDAY;
  131         rsec = secs % SECDAY;
  132 
  133         /* Day of week (Note: 1/1/1970 was a Thursday) */
  134         dt->dt_wday = (days + 4) % 7;
  135 
  136         /* Subtract out whole years, counting them in i. */
  137         for (i = POSIX_BASE_YEAR; days >= days_in_year(i); i++)
  138                 days -= days_in_year(i);
  139         dt->dt_year = i;
  140 
  141         /* Subtract out whole months, counting them in i. */
  142         if (leapyear(i))
  143                 days_in_month(FEBRUARY) = 29;
  144         for (i = 1; days >= days_in_month(i); i++)
  145                 days -= days_in_month(i);
  146         dt->dt_mon = i;
  147 
  148         /* Days are what is left over (+1) from all that. */
  149         dt->dt_day = days + 1;
  150 
  151         /* Hours, minutes, seconds are easy */
  152         dt->dt_hour = rsec / 3600;
  153         rsec = rsec % 3600;
  154         dt->dt_min  = rsec / 60;
  155         rsec = rsec % 60;
  156         dt->dt_sec  = rsec;
  157 }

Cache object: 6d67cc54839f8030f5c6240ab8efd225


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.