1 /* $Id: qfits_time.c,v 1.7 2006/02/17 10:24:52 yjung Exp $
2 *
3 * This file is part of the ESO QFITS Library
4 * Copyright (C) 2001-2004 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 /*
22 * $Author: yjung $
23 * $Date: 2006/02/17 10:24:52 $
24 * $Revision: 1.7 $
25 * $Name: qfits-6_2_0 $
26 */
27
28 /*-----------------------------------------------------------------------------
29 Includes
30 -----------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <time.h>
36 #ifndef _WIN32 //# Modified by Robert Lancaster for the StellarSolver Internal Library
37 #include <pwd.h>
38 #include <sys/time.h>
39 #else
40 #include "tic.h"
41 #endif
42 #include <unistd.h>
43
44 #include "qfits_time.h"
45
46 /*-----------------------------------------------------------------------------
47 Macros
48 -----------------------------------------------------------------------------*/
49
50 /* Get century from a date in long format */
51 #define GET_CENTURY(d) (int) ( (d) / 1000000L)
52 /* Get century year from a date in long format */
53 #define GET_CCYEAR(d) (int) ( (d) / 10000L)
54 /* Get year from a date in long format */
55 #define GET_YEAR(d) (int) (((d) % 1000000L) / 10000L)
56 /* Get month from a date in long format */
57 #define GET_MONTH(d) (int) (((d) % 10000L) / 100)
58 /* Get day from a date in long format */
59 #define GET_DAY(d) (int) ( (d) % 100)
60
61 /* Get hours from a date in long format */
62 #define GET_HOUR(t) (int) ( (t) / 1000000L)
63 /* Get minutes from a date in long format */
64 #define GET_MINUTE(t) (int) (((t) % 1000000L) / 10000L)
65 /* Get seconds from a date in long format */
66 #define GET_SECOND(t) (int) (((t) % 10000L) / 100)
67 /* Get centi-seconds from a date in long format */
68 #define GET_CENTI(t) (int) ( (t) % 100)
69
70 /* Make date in long format from its components */
71 #define MAKE_DATE(c,y,m,d) (long) (c) * 1000000L + \
72 (long) (y) * 10000L + \
73 (long) (m) * 100 + (d)
74 /* Make time in long format from its components */
75 #define MAKE_TIME(h,m,s,c) (long) (h) * 1000000L + \
76 (long) (m) * 10000L + \
77 (long) (s) * 100 + (c)
78
79 /* Interval values, specified in centiseconds */
80 #define INTERVAL_CENTI 1
81 #define INTERVAL_SEC 100
82 #define INTERVAL_MIN 6000
83 #define INTERVAL_HOUR 360000L
84 #define INTERVAL_DAY 8640000L
85
86 /*-----------------------------------------------------------------------------
87 Private to this module
88 -----------------------------------------------------------------------------*/
89
90 static long timer_to_date(time_t time_secs);
91 static long timer_to_time(time_t time_secs);
92 static long qfits_time_now(void);
93 static long qfits_date_now (void);
94
95 #ifdef _MSC_VER //# Modified by Robert Lancaster for the StellarSolver Internal Library
96 struct timeval {
97 long tv_sec; /* seconds */
98 long tv_usec; /* and microseconds */
99 };
100 #endif
101
102
103 /*----------------------------------------------------------------------------*/
104 /**
105 * @defgroup qfits_time Get date/time, possibly in ISO8601 format
106 *
107 * This module contains various utilities to get the current date/time,
108 * and possibly format it according to the ISO 8601 format.
109 */
110 /*----------------------------------------------------------------------------*/
111 /**@{*/
112
113 /*-----------------------------------------------------------------------------
114 Function codes
115 -----------------------------------------------------------------------------*/
116
117 /*----------------------------------------------------------------------------*/
118 /**
119 @brief Returns the current date and time as a static string.
120 @return Pointer to statically allocated string
121
122 Build and return a string containing the date of today and the
123 current time in ISO8601 format. The returned pointer points to a
124 statically allocated string in the function, so no need to free it.
125 */
126 /*----------------------------------------------------------------------------*/
qfits_get_datetime_iso8601(void)127 char * qfits_get_datetime_iso8601(void)
128 {
129 static char date_iso8601[20];
130 long curdate;
131 long curtime;
132
133 curdate = qfits_date_now();
134 curtime = qfits_time_now();
135
136 sprintf(date_iso8601, "%04d-%02d-%02dT%02d:%02d:%02d",
137 GET_CCYEAR(curdate),
138 GET_MONTH(curdate),
139 GET_DAY(curdate),
140 GET_HOUR(curtime),
141 GET_MINUTE(curtime),
142 GET_SECOND(curtime));
143 return date_iso8601;
144 }
145
146 /**@}*/
147
148 /*----------------------------------------------------------------------------*/
149 /**
150 @brief Returns the current date as a long (CCYYMMDD).
151 @return The current date as a long number.
152
153 Returns the current date as a long value (CCYYMMDD). Since most
154 system clocks do not return a century, this function assumes that
155 all years 80 and above are in the 20th century, and all years 00 to
156 79 are in the 21st century. For best results, consume before 1 Jan
157 2080.
158 Example: 19 Oct 2000 is returned as 20001019
159 */
160 /*----------------------------------------------------------------------------*/
qfits_date_now(void)161 static long qfits_date_now (void)
162 {
163 return (timer_to_date (time (NULL)));
164 }
165
166 /*----------------------------------------------------------------------------*/
167 /**
168 @brief Returns the current time as a long (HHMMSSCC).
169 @return The current time as a long number.
170
171 Returns the current time as a long value (HHMMSSCC). If the system
172 clock does not return centiseconds, these are set to zero.
173
174 Example: 15:36:12.84 is returned as 15361284
175 */
176 /*----------------------------------------------------------------------------*/
qfits_time_now(void)177 static long qfits_time_now(void)
178 {
179 struct timeval time_struct;
180
181 gettimeofday (&time_struct, 0);
182 return (timer_to_time (time_struct.tv_sec)
183 + time_struct.tv_usec / 10000);
184 }
185
186 /*----------------------------------------------------------------------------*/
187 /**
188 @brief Converts a timer value to a date.
189 @param time_secs Current time definition in seconds.
190 @return Current date as a long (CCYYMMDD).
191
192 Converts the supplied timer value into a long date value. Dates are
193 stored as long values: CCYYMMDD. If the supplied value is zero,
194 returns zero. If the supplied value is out of range, returns 1
195 January, 1970 (19700101). The timer value is assumed to be UTC
196 (GMT).
197 */
198 /*----------------------------------------------------------------------------*/
timer_to_date(time_t time_secs)199 static long timer_to_date(time_t time_secs)
200 {
201 struct tm *time_struct;
202
203 if (time_secs == 0) {
204 return 0;
205 } else {
206 /* Convert into a long value CCYYMMDD */
207 time_struct = localtime (&time_secs);
208 if (time_struct) {
209 time_struct-> tm_year += 1900;
210 return (MAKE_DATE ( time_struct-> tm_year / 100,
211 time_struct-> tm_year % 100,
212 time_struct-> tm_mon + 1,
213 time_struct-> tm_mday));
214 } else {
215 return (19700101);
216 }
217 }
218 }
219
220 /*----------------------------------------------------------------------------*/
221 /**
222 @brief Convert a timer value to a time.
223 @param time_secs Current time definition in seconds.
224 @return Current time as a long.
225
226 Converts the supplied timer value into a long time value. Times are
227 stored as long values: HHMMSS00. Since the timer value does not
228 hold centiseconds, these are set to zero. If the supplied value was
229 zero or invalid, returns zero. The timer value is assumed to be UTC
230 (GMT).
231 */
232 /*----------------------------------------------------------------------------*/
timer_to_time(time_t time_secs)233 static long timer_to_time(time_t time_secs)
234 {
235 struct tm *time_struct;
236
237 if (time_secs == 0) {
238 return 0;
239 } else {
240 /* Convert into a long value HHMMSS00 */
241 time_struct = localtime (&time_secs);
242 if (time_struct) {
243 return (MAKE_TIME (time_struct-> tm_hour,
244 time_struct-> tm_min,
245 time_struct-> tm_sec,
246 0));
247 } else {
248 return 0;
249 }
250 }
251 }
252
253