Arduino-RTC
Real-Time Clock (RTC) library for Arduino
mk_gmtime.cpp
Go to the documentation of this file.
1 /*
2  * (C)2012 Michael Duane Rice All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer. Redistributions in binary
10  * form must reproduce the above copyright notice, this list of conditions
11  * and the following disclaimer in the documentation and/or other materials
12  * provided with the distribution. Neither the name of the copyright holders
13  * nor the names of contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "time.h"
30 
31 time_t
32 mk_gmtime(const struct tm * timeptr)
33 {
34  time_t res;
35  uint32_t tmp;
36  int n, m, d, leaps;
37 
38  /*
39  * Determine elapsed whole days since the epoch to the beginning of
40  * this year. Since our epoch is at a conjunction of the leap
41  * cycles, we can do this rather quickly.
42  */
43  n = timeptr->tm_year - 100;
44  leaps = 0;
45  if (n) {
46  m = n - 1;
47  leaps = m / 4;
48  leaps -= m / 100;
49  leaps++;
50  }
51  tmp = 365UL * n + leaps;
52 
53  /*
54  * Derive the day of year from month and day of month. We use the
55  * pattern of 31 day months followed by 30 day months to our
56  * advantage, but we must 'special case' Jan/Feb, and account for a
57  * 'phase change' between July and August (153 days after March 1).
58  * Note: tm_mday is one based.
59  */
60  d = timeptr->tm_mday - 1;
61 
62  // Handle Jan/Feb as a special case
63  if (timeptr->tm_mon < 2) {
64  if (timeptr->tm_mon)
65  d += 31;
66  }
67  else {
68  n = 59 + is_leap_year(timeptr->tm_year + 1900);
69  d += n;
70  n = timeptr->tm_mon - MARCH;
71 
72  // Account for phase change
73  if (n > (JULY - MARCH))
74  d += 153;
75  n %= 5;
76 
77  // N is now an index into a group of alternating 31 and 30
78  // day months... 61 day pairs
79  m = n / 2;
80  m *= 61;
81  d += m;
82 
83  // If n is odd, we are in the second half of the month pair
84  if (n & 1)
85  d += 31;
86  }
87 
88  // Add day of year to elapsed days, and convert to seconds
89  tmp += d;
90  tmp *= ONE_DAY;
91  res = tmp;
92 
93  // Compute 'fractional' day
94  tmp = timeptr->tm_hour;
95  tmp *= ONE_HOUR;
96  tmp += timeptr->tm_min * 60UL;
97  tmp += timeptr->tm_sec;
98  res += tmp;
99 
100  return res;
101 }
int8_t tm_mday
Day in Month [1-31].
Definition: time.h:40
int8_t tm_min
Minutes [0-59].
Definition: time.h:38
unsigned char is_leap_year(int year)
Definition: time.h:80
#define ONE_HOUR
Definition: time.h:148
#define ONE_DAY
Definition: time.h:154
int16_t tm_year
Years since 1900.
Definition: time.h:43
int8_t tm_sec
Seconds [0-60].
Definition: time.h:37
uint32_t time_t
Definition: time.h:30
time_t mk_gmtime(const struct tm *timeptr)
Definition: mk_gmtime.cpp:32
int8_t tm_hour
Hours [0-23].
Definition: time.h:39
Definition: time.h:84
Definition: time.h:36
int8_t tm_mon
0-11 Months since January [0-11].
Definition: time.h:42