]>
Commit | Line | Data |
---|---|---|
e63b2f75 L |
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 | /* $Id: mk_gmtime.c 2369 2013-04-28 14:19:35Z swfltek $ */ | |
30 | ||
31 | /* | |
32 | 'Break down' a y2k time stamp into the elements of struct tm. | |
33 | Unlike mktime(), this function does not 'normalize' the elements of timeptr. | |
34 | ||
35 | */ | |
36 | ||
37 | #include <time.h> | |
38 | ||
39 | time_t | |
40 | mk_gmtime(const struct tm * timeptr) | |
41 | { | |
42 | ||
43 | time_t ret; | |
44 | uint32_t tmp; | |
45 | int n, m, d, leaps; | |
46 | ||
47 | /* | |
48 | Determine elapsed whole days since the epoch to the beginning of this year. Since our epoch is | |
49 | at a conjunction of the leap cycles, we can do this rather quickly. | |
50 | */ | |
51 | n = timeptr->tm_year - 100; | |
52 | leaps = 0; | |
53 | if (n) { | |
54 | m = n - 1; | |
55 | leaps = m / 4; | |
56 | leaps -= m / 100; | |
57 | leaps++; | |
58 | } | |
59 | tmp = 365UL * n + leaps; | |
60 | ||
61 | /* | |
62 | Derive the day of year from month and day of month. We use the pattern of 31 day months | |
63 | followed by 30 day months to our advantage, but we must 'special case' Jan/Feb, and | |
64 | account for a 'phase change' between July and August (153 days after March 1). | |
65 | */ | |
66 | d = timeptr->tm_mday - 1; /* tm_mday is one based */ | |
67 | ||
68 | /* handle Jan/Feb as a special case */ | |
69 | if (timeptr->tm_mon < 2) { | |
70 | if (timeptr->tm_mon) | |
71 | d += 31; | |
72 | ||
73 | } else { | |
74 | n = 59 + is_leap_year(timeptr->tm_year + 1900); | |
75 | d += n; | |
76 | n = timeptr->tm_mon - MARCH; | |
77 | ||
78 | /* account for phase change */ | |
79 | if (n > (JULY - MARCH)) | |
80 | d += 153; | |
81 | n %= 5; | |
82 | ||
83 | /* | |
84 | * n is now an index into a group of alternating 31 and 30 | |
85 | * day months... 61 day pairs. | |
86 | */ | |
87 | m = n / 2; | |
88 | m *= 61; | |
89 | d += m; | |
90 | ||
91 | /* | |
92 | * if n is odd, we are in the second half of the | |
93 | * month pair | |
94 | */ | |
95 | if (n & 1) | |
96 | d += 31; | |
97 | } | |
98 | ||
99 | /* Add day of year to elapsed days, and convert to seconds */ | |
100 | tmp += d; | |
101 | tmp *= ONE_DAY; | |
102 | ret = tmp; | |
103 | ||
104 | /* compute 'fractional' day */ | |
105 | tmp = timeptr->tm_hour; | |
106 | tmp *= ONE_HOUR; | |
107 | tmp += timeptr->tm_min * 60UL; | |
108 | tmp += timeptr->tm_sec; | |
109 | ||
110 | ret += tmp; | |
111 | ||
112 | return ret; | |
113 | } |