1 /* $NetBSD: cdf_time.c,v 1.1.1.1 2009/05/08 16:35:06 christos Exp $ */
4 * Copyright (c) 2008 Christos Zoulas
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE 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.
33 FILE_RCSID("@(#)$File: cdf_time.c,v 1.6 2009/03/10 11:44:29 christos Exp $")
35 __RCSID("$NetBSD: cdf_time.c,v 1.1.1.1 2009/05/08 16:35:06 christos Exp $");
47 #define isleap(y) ((((y) % 4) == 0) && \
48 ((((y) % 100) != 0) || (((y) % 400) == 0)))
50 static const int mdays
[] = {
51 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
55 * Return the number of days between jan 01 1601 and jan 01 of year.
63 for (y
= CDF_BASE_YEAR
; y
< year
; y
++)
64 days
+= isleap(y
) + 365;
70 * Return the day within the month
73 cdf_getday(int year
, int days
)
77 for (m
= 0; m
< sizeof(mdays
) / sizeof(mdays
[0]); m
++) {
78 int sub
= mdays
[m
] + (m
== 1 && isleap(year
));
87 * Return the 0...11 month number.
90 cdf_getmonth(int year
, int days
)
94 for (m
= 0; m
< sizeof(mdays
) / sizeof(mdays
[0]); m
++) {
96 if (m
== 1 && isleap(year
))
105 cdf_timestamp_to_timespec(struct timespec
*ts
, cdf_timestamp_t t
)
108 #ifdef HAVE_STRUCT_TM_TM_ZONE
109 static char UTC
[] = "UTC";
113 /* Unit is 100's of nanoseconds */
114 ts
->tv_nsec
= (t
% CDF_TIME_PREC
) * 100;
117 tm
.tm_sec
= (int)(t
% 60);
120 tm
.tm_min
= (int)(t
% 60);
123 tm
.tm_hour
= (int)(t
% 24);
127 tm
.tm_year
= (int)(CDF_BASE_YEAR
+ (t
/ 365));
129 rdays
= cdf_getdays(tm
.tm_year
);
131 tm
.tm_mday
= cdf_getday(tm
.tm_year
, (int)t
);
132 tm
.tm_mon
= cdf_getmonth(tm
.tm_year
, (int)t
);
136 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
139 #ifdef HAVE_STRUCT_TM_TM_ZONE
143 ts
->tv_sec
= mktime(&tm
);
144 if (ts
->tv_sec
== -1) {
153 cdf_timespec_to_timestamp(cdf_timestamp_t
*t
, const struct timespec
*ts
)
161 if (gmtime_r(&ts
->ts_sec
, &tm
) == NULL
) {
165 *t
= (ts
->ts_nsec
/ 100) * CDF_TIME_PREC
;
167 *t
+= tm
.tm_min
* 60;
168 *t
+= tm
.tm_hour
* 60 * 60;
169 *t
+= tm
.tm_mday
* 60 * 60 * 24;
177 main(int argc
, char *argv
[])
180 static const cdf_timestamp_t tst
= 0x01A5E403C2D59C00ULL
;
181 static const char *ref
= "Sat Apr 23 01:30:00 1977";
184 cdf_timestamp_to_timespec(&ts
, tst
);
185 p
= ctime(&ts
.tv_sec
);
186 if ((q
= strchr(p
, '\n')) != NULL
)
188 if (strcmp(ref
, p
) != 0)
189 errx(1, "Error date %s != %s\n", ref
, p
);