Contiki 3.x
tm_to_epoch.c
1 /*
2  * Adapted from CyrusIMAP - http://www.opensource.apple.com/source/CyrusIMAP/CyrusIMAP-125.11/cyrus_imap/lib/mkgmtime.c
3  */
4 
5 /*
6  * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The name "Carnegie Mellon University" must not be used to
21  * endorse or promote products derived from this software without
22  * prior written permission. For permission or any other legal
23  * details, please contact
24  * Office of Technology Transfer
25  * Carnegie Mellon University
26  * 5000 Forbes Avenue
27  * Pittsburgh, PA 15213-3890
28  * (412) 268-4387, fax: (412) 268-7395
29  * tech-transfer@andrew.cmu.edu
30  *
31  * 4. Redistributions of any form whatsoever must retain the following
32  * acknowledgment:
33  * "This product includes software developed by Computing Services
34  * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
35  *
36  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43  *
44  *
45  */
46 /*
47  * Copyright (c) 1987, 1989, 1993
48  * The Regents of the University of California. All rights reserved.
49  *
50  * This code is derived from software contributed to Berkeley by
51  * Arthur David Olson of the National Cancer Institute.
52  *
53  * Redistribution and use in source and binary forms, with or without
54  * modification, are permitted provided that the following conditions
55  * are met:
56  * 1. Redistributions of source code must retain the above copyright
57  * notice, this list of conditions and the following disclaimer.
58  * 2. Redistributions in binary form must reproduce the above copyright
59  * notice, this list of conditions and the following disclaimer in the
60  * documentation and/or other materials provided with the distribution.
61  * 3. All advertising materials mentioning features or use of this software
62  * must display the following acknowledgement:
63  * This product includes software developed by the University of
64  * California, Berkeley and its contributors.
65  * 4. Neither the name of the University nor the names of its contributors
66  * may be used to endorse or promote products derived from this software
67  * without specific prior written permission.
68  *
69  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
70  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
71  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
72  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
73  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
74  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
75  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
76  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
77  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
78  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
79  * SUCH DAMAGE.
80  */
81 
82 /*
83 ** Adapted from code provided by Robert Elz, who writes:
84 ** The "best" way to do mktime I think is based on an idea of Bob
85 ** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
86 ** It does a binary search of the time_t space. Since time_t's are
87 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
88 ** would still be very reasonable).
89 */
90 
91 #include "utc_time.h"
92 
93 #define WRONG (-1)
94 
95 static int
96 tmcomp(atmp, btmp)
97 register const struct tm * const atmp;
98 register const struct tm * const btmp;
99 {
100  register int result;
101 
102  if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
103  (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
104  (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
105  (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
106  (result = (atmp->tm_min - btmp->tm_min)) == 0)
107  result = atmp->tm_sec - btmp->tm_sec;
108  return result;
109 }
110 
111 time_t
113 struct tm * const tmp;
114 {
115  register int dir;
116  register int bits;
117  register int saved_seconds;
118  time_t t;
119  struct tm yourtm, mytm;
120 
121  yourtm = *tmp;
122  saved_seconds = yourtm.tm_sec;
123  yourtm.tm_sec = 0;
124  /*
125  ** Calculate the number of magnitude bits in a time_t
126  ** (this works regardless of whether time_t is
127  ** signed or unsigned, though lint complains if unsigned).
128  */
129  for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
130  ;
131  /*
132  ** If time_t is signed, then 0 is the median value,
133  ** if time_t is unsigned, then 1 << bits is median.
134  */
135  t = (t < 0) ? 0 : ((time_t) 1 << bits);
136 
137  /* Some gmtime() implementations are broken and will return
138  * NULL for time_ts larger than 40 bits even on 64-bit platforms
139  * so we'll just cap it at 40 bits */
140  if(bits > 40) bits = 40;
141 
142  for ( ; ; ) {
143  epoch_to_tm(&t, &mytm);
144 
145  dir = tmcomp(mytm, &yourtm);
146  if (dir != 0) {
147  if (bits-- < 0)
148  return WRONG;
149  if (bits < 0)
150  --t;
151  else if (dir > 0)
152  t -= (time_t) 1 << bits;
153  else t += (time_t) 1 << bits;
154  continue;
155  }
156  break;
157  }
158  t += saved_seconds;
159  return t;
160 }
Utility functions for operating on UTC times.
time_t tm_to_epoch(struct tm *const tmp)
Convert a tm struct to a UNIX epoch.
Definition: tm_to_epoch.c:112
tm
Definition: utc_time.h:20
void epoch_to_tm(const time_t *timer, struct tm *const tmp)
Convert a UNIX epoch to a tm struct.