1 /*
2  * ===========================
3  * VDK Visual Development Kit
4  * Version 0.4
5  * October 1998
6  * ===========================
7  *
8  * Copyright (C) 1998, Mario Motta
9  * Developed by Mario Motta <mmotta@guest.net>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24  * 02111-1307, USA.
25  *
26  */
27 
28 
29 #include "vdk/vdkdate.h"
30 #include <string>
31 #include <cstdlib>
32 #include <cstdio>
33 #include <time.h>
34 
35 /*
36 days, moths, names
37 */
38 static int monthDays[] =
39 { 31,29,31,30,
40   31,30,31,31,
41   30,31,30,31
42 };
43 static char *days_name[] =
44 {
45 "Domenica","Luned�","Marted�",
46 "Mercoled�","Gioved�","Venerd�",
47  "Sabato"
48 };
49 static char *days_name_E[] =
50 {
51 "Sunday","Monday","Tuesday",
52 "Wednesday","Thursday","Friday",
53  "Saturday"
54 };
55 static char *months_name[] =
56 {
57 "?","Gennaio","Febbraio","Marzo","Aprile",
58 "Maggio","Giugno","Luglio","Agosto",
59 "Settembre","Ottobre","Novembre","Dicembre"
60 };
61 static char *months_name_E[] =
62 {
63 "?","January","February","March","April",
64 "May","June","July","August",
65 "September","October","November","December"
66 };
67 
68 static char internal_buffer[128];
69 
70 
71 /*
72   private:
73   from calendar to julian
74   */
Julian(void)75 long calendardate::Julian(void)
76 {
77   long jul;
78   int ja,jy = year, jm;
79   int error = 0;
80   /*
81 	checks correct date
82     */
83   error = jy <= 0;
84   if(! error) error = (month <= 0 || month > 12);
85   if(! error) error = day > monthDays[month-1];
86   if(! error && month == 2)
87     error = (! Leap(year)) && (day > 28);
88   if(error) return -1L;
89 
90   if(month > 2) jm = month+1;
91   else { jy--; jm = month+13; }
92   jul = (long) (floor(365.25*jy)+floor(30.6001*jm)+day+1720995);
93   if(day+31L*(month+12L*year) >= IGREG)
94     {
95       ja = (int) (0.01*jy);
96       jul += 2 - ja + (int) (0.25*ja);
97     }
98   return jul;
99 }
100 /*
101   private:
102   compute month and year
103   */
Caldate(void)104 void calendardate::Caldate(void)
105 {
106   long ja,jalfa,jb,jc,jd,je;
107   if(julian >= IGREG)
108     {
109       jalfa = (long)
110 	(((float) (julian-1867216L)-0.25)/36524.25);
111       ja = julian+1+jalfa - (long) (0.25*jalfa);
112     }
113   else ja= julian;
114   jb = ja+1524;
115   jc = (long) (6680.0 + ((float) (jb-2439870L)-122.1)/365.25);
116   jd = (long) (365*jc+(0.25*jc));
117   je = (long) ((jb-jd)/30.6001);
118   day = jb-jd-(long)(30.6001*je);
119   month = je-1;
120   if(month > 12) month -= 12;
121   year = jc - 4715;
122   if(month > 2) --year;
123   if(year <= 0) --year;
124 }
125 
126 /*
127   make a date
128   from system date
129   */
calendardate(int mode)130 calendardate::calendardate(int mode): mode(mode)
131 {
132   time_t curtime;
133   struct tm *loctime;
134   /* Get the current time. */
135   curtime = time (NULL);
136   /* Convert it to local time representation. */
137   loctime = localtime (&curtime);
138   day = loctime->tm_mday;
139   month = loctime->tm_mon+1;
140   year = loctime->tm_year+1900;
141   julian = Julian();
142 }
143 /*
144   expects a date in mmddyyyy or ddmmyyyy format,
145   use separators included in sep
146   */
calendardate(char * s,int mode,char * sep)147 calendardate::calendardate(char* s, int mode, char* sep):
148   mode(mode)
149 {
150   char *p,*p1;
151   int error = 0;
152   memset(internal_buffer,(char) 0, sizeof(internal_buffer));
153   strcpy(internal_buffer,s);
154   p = p1 = internal_buffer;
155 
156   if((p1 = strpbrk(p,sep)) != (char*) 0)
157     {
158       *p1 = '\0';
159       if(mode == ddmmyyyy)
160 	day = atoi(p);
161       else
162 	month = atoi(p);
163       p = ++p1;
164     }
165   else error = 1;
166 
167   if (! error && (p1 = strpbrk(p,sep)) != (char*) 0)
168     {
169       *p1 = '\0';
170       if(mode == ddmmyyyy)
171 	month = atoi(p);
172       else
173 	day = atoi(p);
174       p = ++p1;
175     }
176   else error = 1;
177 
178   if (! error) year = atoi(p);
179   else error = 1;
180   // cast to XX century.
181   year = year < 1900 ? year+1900: year;
182   if(! error) julian = Julian();
183   else julian = -1L;
184 }
185 /*
186   stream output
187   ostream& operator<<(ostream& os, calendardate& d)
188   {
189   if(d.day < 10) os << '0';
190   os << d.day << '.';
191   if(d.month < 10) os << '0';
192   os << d.month << '.';
193   os << d.year;
194   if(d.julian < 0L) os << "(!)";
195    return os;
196   }
197 */
198 /*
199   return formatted date
200   */
operator char*()201 calendardate::operator char*()
202 {
203   if(julian < 0) return "invalid";
204   if(mode == ddmmyyyy)
205     sprintf(internal_buffer,"%02d/%02d/%d",day,month,year);
206   else
207     sprintf(internal_buffer,"%02d/%02d/%d",month,day,year);
208   return internal_buffer;
209 }
210 /*
211 in yyyymmdd format
212 */
AsString()213 char* calendardate::AsString()
214 {
215   if(julian < 0) return "invalid";
216   sprintf(internal_buffer,"%4d%02d%02d",year,month,day);
217   return internal_buffer;
218 }
CalendarDate()219 char* calendardate::CalendarDate()
220 {
221   if(mode == ddmmyyyy)
222     sprintf(internal_buffer,"%s %d %s %d",
223 	    days_name[DayIndex()],
224 	    day,
225 	    months_name[month],
226 	    year);
227   else
228     sprintf(internal_buffer,"%s %s %d %d",
229 	    days_name_E[DayIndex()],
230 	    months_name_E[month],
231 	    day,
232 	    year);
233     return internal_buffer;
234 }
235 
InternalBuffer()236 char* calendardate::InternalBuffer()
237 { return internal_buffer; }
238 /*
239 expect a date in
240 yyyymmdd format
241 */
MakeDate(char * s,int mode)242 calendardate MakeDate(char* s,int mode)
243 {
244 calendardate today(mode);
245 int d,m,y;
246 if(strlen(s) != 8)
247     return today;
248 char buffer[9];
249 strcpy(buffer,s);
250 d = atoi(&buffer[6]);
251 buffer[6] = '\0';
252 m = atoi(&buffer[4]);
253 buffer[4] = '\0';
254 y = atoi(buffer);
255 return calendardate(d,m,y,mode);
256 }
257