1 /* ======================================================= *
2  * Copyright 1998-2005 Stephen C. Grubb                    *
3  * http://ploticus.sourceforge.net                         *
4  * Covered by GPL; see the file ./Copyright for details.   *
5  * ======================================================= */
6 
7 /* DATETIME - datetime routines */
8 #include <stdio.h>
9 #include <string.h>
10 #include <ctype.h>
11 
12 extern int DT_setdatetimefmt(), GL_getchunk(), DT_setdatefmt(), DT_settimefmt();
13 extern int DT_datetime2days(), DT_jdate(), DT_tomin(), DT_frame_mins(), TDH_err(), DT_days2datetime(), DT_fromjul(), DT_frommin();
14 extern int DT_formatdatetime(), DT_formatdate(), DT_formattime();
15 extern int atoi();
16 
17 
18 static double Dtwinbegin = 0.0, Dtwinend = 1440.0, Dtwinsize = 1440.0; /* default: 24 hours */
19 static int Suppress_twin_warn = 0;
20 static char Dtsep[4] = "."; /* must be one character only */  /* added scg 9/26/03 */
21 
22 /* ================================== */
23 int
DT_datetime_initstatic()24 DT_datetime_initstatic()
25 {
26 Dtwinbegin = 0.0;
27 Dtwinend = 1440.0;
28 Dtwinsize = 1440.0;
29 Suppress_twin_warn = 0;
30 strcpy( Dtsep, "." );
31 return( 0 );
32 }
33 
34 /* ================================== */
35 /* SETDATETIMEFMT - set the format for the date and time
36    	components of datetime */
37 int
DT_setdatetimefmt(fmt,window)38 DT_setdatetimefmt( fmt, window )
39 char *fmt;
40 char *window; /* Specifies a 'window' of hours to be shown for each day.
41 		 Notation nn-mm where nn is hour to begin with and mm is
42 		hour to end with (0-24) */
43 {
44 char datepart[20], timepart[20];
45 char beginpart[20], endpart[20];
46 int i;
47 
48 if( fmt[0] != '\0' ) {  /* condition added scg 9/29/03 */
49 	i = 0;
50 	GL_getchunk( datepart, fmt, &i, Dtsep );
51 	GL_getchunk( timepart, fmt, &i, Dtsep );
52 	DT_setdatefmt( datepart );
53 	DT_settimefmt( timepart );
54 	}
55 
56 if( window[0] != '\0' ) { /* parse 'window' specification */
57 	i = 0;
58 	GL_getchunk( beginpart, window, &i, "-" );
59 	GL_getchunk( endpart, window, &i, "-" );
60 	Dtwinbegin = atoi( beginpart ) * 60.0;
61 	Dtwinend = atoi( endpart ) * 60.0;
62 	Dtwinsize = (Dtwinend - Dtwinbegin);
63 	}
64 if( window[0] == '\0' || Dtwinsize == 0.0 ) {
65 	Dtwinbegin = 0.0;
66 	Dtwinend = 1440.0;
67 	Dtwinsize = 1440.0;
68 	}
69 
70 return( 0 );
71 }
72 
73 /* ================================== */
74 /* GETDTPARTS - split out the date and time portions of a datetime value */
75 /* note - this should only be called when w/ 'datetime' scaletype, never w/ 'date' (messes up w/ formats such as dd.mm.yy) */
76 
77 int
DT_getdtparts(dt,datepart,timepart)78 DT_getdtparts( dt, datepart, timepart )
79 char *dt, *datepart, *timepart;
80 {
81 int i;
82 i = 0;
83 GL_getchunk( datepart, dt, &i, Dtsep );
84 GL_getchunk( timepart, dt, &i, Dtsep );
85 return( 0 );
86 }
87 
88 
89 /* ================================== */
90 /* DATETIME2DAYS - convert a datetime to julian date with
91 	decimal portion representing the time component.
92    	Returns 0 if ok, 1 on error */
93 
94 int
DT_datetime2days(dt,days)95 DT_datetime2days( dt, days )
96 char *dt;
97 double *days;
98 {
99 char datepart[20], timepart[20];
100 long jul;
101 int i, stat;
102 double mins;
103 
104 i = 0;
105 GL_getchunk( datepart, dt, &i, Dtsep );
106 GL_getchunk( timepart, dt, &i, Dtsep );
107 stat = DT_jdate( datepart, &jul );
108 if( stat != 0 ) return( 1 );
109 
110 if( strcmp( timepart, "" )==0 ) mins = Dtwinbegin; /* added scg 9/26/03 */
111 else 	{
112 	stat = DT_tomin( timepart, &mins );
113 	if( stat != 0 ) return( 1 );
114 	}
115 
116 stat = DT_frame_mins( &mins );
117 if( stat && !Suppress_twin_warn ) TDH_err( 4279, "warning: time is outside of window range- displaying it at window boundary", dt );
118 
119 mins = (mins-Dtwinbegin) / Dtwinsize; /* normalize to  0.0 - 1.0 */
120 *days = jul+mins;
121 return( 0 );
122 }
123 
124 
125 /* ================================== */
126 /* DAYS2DATETIME - convert decimal julian date to datetime */
127 
128 int
DT_days2datetime(days,dt)129 DT_days2datetime( days, dt )
130 double days;
131 char *dt;
132 {
133 char s[30], t[30];
134 double datepart, timepart, floor(), fmod();
135 
136 datepart = floor( days );
137 timepart = days - datepart;
138 
139 timepart = (timepart * Dtwinsize) + Dtwinbegin; /* convert from 0.0 - 1.0 to #min past midnite */
140 timepart = floor( timepart + 0.5 ); /* remove any rounding error introduced by above */
141 
142 DT_fromjul( (long)datepart, s );
143 DT_frommin( timepart, t );
144 
145 
146 sprintf( dt, "%s%s%s", s, Dtsep, t );
147 return( 0 );
148 }
149 
150 /* ================================== */
151 /* FORMATDATETIME - convert a datetime from current format
152 	to a new format for display.  Either the date or
153 	time component may be omitted for display purposes.
154 */
155 
156 int
DT_formatdatetime(dt,format,newdt)157 DT_formatdatetime( dt, format, newdt )
158 char *dt, *format, *newdt;
159 {
160 char datepart[20], timepart[20];
161 char datefmt[20], timefmt[20];
162 char s[30], t[30];
163 int i;
164 
165 i = 0;
166 strcpy( datefmt, "" );
167 strcpy( timefmt, "" );
168 if( format[0] != Dtsep[0] && tolower(format[0]) != 'h' ) GL_getchunk( datefmt, format, &i, Dtsep );
169 GL_getchunk( timefmt, format, &i, Dtsep );
170 
171 i = 0;
172 GL_getchunk( datepart, dt, &i, Dtsep );
173 GL_getchunk( timepart, dt, &i, Dtsep );
174 
175 if( datefmt[0] != '\0' ) {
176 	DT_formatdate( datepart, datefmt, s );
177 	}
178 else strcpy( s, "" );
179 if( timefmt[0] != '\0' ) {
180 	if( datefmt[0] != '\0' )strcpy( t, Dtsep );
181 	else strcpy( t, "" );
182 	DT_formattime( timepart, timefmt, &t[strlen(t)] );
183 	}
184 else strcpy( t, "" );
185 
186 sprintf( newdt, "%s%s", s, t );
187 
188 return( 0 );
189 }
190 
191 /* ================================= */
192 /* FRAME_MINS - if mins is outsize window, adjust mins to a window boundary */
193 
194 int
DT_frame_mins(mins)195 DT_frame_mins( mins )
196 double *mins;
197 {
198 if( *mins < Dtwinbegin || *mins > Dtwinend ) {
199 	if( *mins < Dtwinbegin ) *mins = Dtwinbegin;
200 	if( *mins > Dtwinend ) *mins = Dtwinend;
201 	return( 1 ); /* indicates an adjustment had to be made.. */
202 	}
203 return( 0 );
204 }
205 
206 /* ================================= */
207 /* SUPPRESS_TWIN_WARN - allow warning message 'value outside datetime
208 	window' to be suppressed */
209 
210 int
DT_suppress_twin_warn(mode)211 DT_suppress_twin_warn( mode )
212 int mode;
213 {
214 Suppress_twin_warn = mode;
215 return( 0 );
216 }
217 
218 /* ================================== */
219 /* GETWIN - return the date window size in hours */
220 
221 int
DT_getwin(winsize)222 DT_getwin( winsize  )
223 double *winsize;
224 {
225 *winsize = Dtwinsize / 60.0;
226 return( 0 );
227 }
228 
229 /* =================================== */
230 /* BUILD_DT - build a datetime string from a date part and a time part */
231 
232 int
DT_build_dt(datepart,timepart,result)233 DT_build_dt( datepart, timepart, result )
234 char *datepart, *timepart, *result;
235 {
236 if( timepart[0] == '\0' ) strcpy( result, datepart ); 		/* scg 1/28/05 */
237 else sprintf( result, "%s%s%s", datepart, Dtsep, timepart );
238 return( 0 );
239 }
240 
241 /* =================================== */
242 /* SETDTSEP - set the datetime separator character */
243 
244 int
DT_setdtsep(c)245 DT_setdtsep( c )
246 char c;
247 {
248 sprintf( Dtsep, "%c", c );
249 return( 0 );
250 }
251 
252 /* =================================== */
253 /* GETDTSEP - get the datetime separator character */
254 
255 int
DT_getdtsep(sep)256 DT_getdtsep( sep )
257 char *sep;
258 {
259 strcpy( sep, Dtsep );
260 return( 0 );
261 }
262 
263 
264 #ifdef TESTING
265 /* ================================== */
main()266 main()
267 {
268 double min;
269 char result[80];
270 char result2[80];
271 
272 DT_tomin( "now", &min );
273 DT_frommin( min, result );
274 DT_formattime( result, "hh:mmA", result2 );
275 printf( "%s\n", result2 );
276 }
277 #endif
278 
279 
280 /* ======================================================= *
281  * Copyright 1998-2005 Stephen C. Grubb                    *
282  * http://ploticus.sourceforge.net                         *
283  * Covered by GPL; see the file ./Copyright for details.   *
284  * ======================================================= */
285