source: Sophya/trunk/SophyaLib/BaseTools/timestamp.cc@ 3989

Last change on this file since 3989 was 3233, checked in by ansari, 18 years ago

correction au niveau de la doc - (suppression de SOPHYA::) apres ajout namespace SOPHYA { } dans les .cc , cmv+reza 27/04/2007

File size: 7.9 KB
Line 
1#include "machdefs.h"
2#include <stdio.h>
3#include <time.h>
4#include <ctype.h>
5#include <math.h>
6#include "timestamp.h"
7#include "pexceptions.h"
8#include <iostream>
9
10namespace SOPHYA {
11
12/*!
13 \class TimeStamp
14 \ingroup BaseTools
15 A simple class for representing date and time. Simple operations
16 on date/time are also provided.
17
18 \code
19 // Create a object with the current date and time and prints it to cout
20 TimeStamp ts;
21 cout << ts << endl;
22 // Create an object with a specified date and time
23 TimeStamp ts2("01/01/1905","00:00:00");
24 // Get the number of days since 0 Jan 1901
25 cout << ts2.ToDays() << endl;
26 \endcode
27*/
28
29#ifdef Linux
30// La fonction trunc non declaree ds math.h sous Linux
31extern "C" { double trunc (double x); }
32#endif
33//-------------------------------------------------------------------------
34//-------------------------- Classe TimeStamp --------------------------
35//-------------------------------------------------------------------------
36
37enum Jour {jour_Lundi=0, jour_Mardi, jour_Mercredi, jour_Jeudi, jour_Vendredi, jour_Samedi, jour_Dimanche};
38enum Mois {mois_Janvier=1, mois_Fevrier, mois_Mars, mois_Avril, mois_Mai, mois_Juin, mois_Juillet,
39 mois_Aout, mois_Septembre, mois_Octobre, mois_Novembre, mois_Decembre};
40
41 /*
42 //! Day of the week enum
43 enum WeekDay {day_Monday=0, day_Tuesday, day_Wednesday, day_Thursday, day_Friday, day_Saturday, day_Sunday};
44 */
45
46TimeStamp::TimeStamp()
47{
48 mSeconds = 0.;
49 mDays = 0;
50 SetNow();
51}
52
53TimeStamp::TimeStamp(TimeStamp const & ts)
54{
55 Set(ts);
56 mSeconds = ts.mSeconds;
57 mDays = ts.mDays;
58}
59
60TimeStamp::TimeStamp(int year, int month, int day, int hour, int min, double sec)
61{
62 SetDate(year, month, day);
63 SetHour(hour, min, sec);
64}
65
66
67TimeStamp::TimeStamp(double days)
68{
69 Set(days);
70}
71
72TimeStamp::TimeStamp(int_8 days, r_8 seconds)
73{
74 Set(days, seconds);
75}
76
77TimeStamp::TimeStamp(string const & date, string const & hour)
78{
79 SetDate(date);
80 SetHour(hour);
81}
82
83TimeStamp::TimeStamp(const char* date, const char* hour)
84{
85 SetDate(date);
86 SetHour(hour);
87}
88
89TimeStamp::TimeStamp(string& datim)
90{
91 Set(datim);
92}
93
94TimeStamp::TimeStamp(const char* datim)
95{
96 Set(datim);
97}
98
99void TimeStamp::Set(TimeStamp const & ts)
100{
101 mSeconds = ts.mSeconds;
102 mDays = ts.mDays;
103}
104
105void TimeStamp::Set(double days)
106{
107 if (days >= 0.) {
108 mDays = (int_8)trunc(days);
109 mSeconds = (days-trunc(days))*86400.;
110 }
111 else {
112 if ( (trunc(days)-days) > 0.) {
113 mDays = (int_8)trunc(days)-1;
114 mSeconds = (days-mDays)*86400.;
115 }
116 else {
117 mDays = (int_8)trunc(days);
118 mSeconds = 0.;
119 }
120 }
121}
122
123void TimeStamp::Set(int_8 days, r_8 seconds)
124{
125 if ( (seconds < 0.) || (seconds > 86400.) )
126 throw ParmError("TimeStamp::Set(int_8, r_8) seconds<0 or seconds>86400.");
127 mDays = days;
128 mSeconds = seconds;
129}
130
131void TimeStamp::Set(const char * datim)
132{
133 int year, month, day;
134 int hour, min;
135 double sec;
136 sscanf(datim,"%d-%d-%dT%d:%d:%lf", &year, &month, &day,
137 &hour, &min, &sec);
138 SetDate(year, month, day);
139 SetHour(hour, min, sec);
140}
141
142
143void TimeStamp::SetNow()
144{
145 time_t t = time(NULL);
146 struct tm* TM = gmtime(&t);
147
148 int JJ,MM,AA;
149 int hh,mm;
150 double ss;
151
152 AA = TM->tm_year + 1900;
153 MM = TM->tm_mon+1;
154 JJ = TM->tm_mday;
155 hh = TM->tm_hour;
156 mm = TM->tm_min;
157 ss = TM->tm_sec;
158 SetDate(AA,MM,JJ);
159 SetHour(hh,mm,ss);
160}
161
162void TimeStamp::SetDate(int year, int month, int day)
163{
164 mDays = ConvertToDays(year, month, day);
165}
166
167void TimeStamp::SetDate(const char* date)
168{
169 int day,month,year;
170 sscanf(date,"%d/%d/%d", &day, &month, &year);
171 mDays = ConvertToDays(year, month, day);
172}
173
174void TimeStamp::SetHour(int hour, int min, double sec)
175{
176 mSeconds = hour*3600.+min*60+sec;
177}
178
179void TimeStamp::SetHour(const char* shour)
180{
181 int hour, min;
182 double sec;
183 sscanf(shour,"%d:%d:%lf",&hour, &min, &sec);
184 mSeconds = hour*3600.+min*60+sec;
185
186}
187
188void TimeStamp::GetDate(int& year, int& month, int& day) const
189{
190 int_8 jours = mDays;
191 // Recherche de l'annee
192 if (jours < 0) {
193 year = 1901;
194 while(jours < 0) {
195 year--;
196 jours += YearDays(year);
197 }
198 }
199 else {
200 year = 1901;
201 while(jours > YearDays(year)) {
202 jours -= YearDays(year);
203 year++;
204 }
205 }
206 // Recherche du mois
207 month = 1;
208 while(jours > MonthDays(year, month) ) {
209 jours -= MonthDays(year, month);
210 month++;
211 }
212 day = jours;
213}
214
215void TimeStamp::GetHour(int& hour, int& min, double& sec) const
216{
217 double seconds = mSeconds;
218 hour = (int)trunc(seconds/3600.);
219 seconds -= hour*3600;
220 min = (int)trunc(seconds/60.);
221 while (min >= 60) { hour++; min -= 60; }
222 sec = seconds-min*60;
223 while (sec >= 60.) { min++; sec -= 60.; }
224}
225
226double TimeStamp::ToDays() const
227{
228 return((double)mDays + mSeconds/86400.);
229}
230
231/*!
232\param fmt : String format for the date
233 - FmtPackedDateTime : YYYY-MM-DDThh:mm:ss.s
234 - FmtDateOnly : dd/mm/yyyy
235 - FmtTimeOnly : hh:mm:ss.s
236 - FmtDateTime : dd/mm/yyyy hh:mm:ss.s UT
237*/
238string TimeStamp::ToString(StrFmt fmt) const
239{
240 char buff[128];
241 int aa, mm, jj;
242 int hh, min;
243 double sec;
244 GetDate(aa, mm, jj);
245 GetHour(hh, min, sec);
246 if (fmt == FmtPackedDateTime)
247 sprintf(buff,"%04d-%02d-%02dT%02d:%02d:%02.1f", aa,mm,jj, hh,min,sec);
248 else {
249 if (fmt == FmtDateOnly)
250 sprintf(buff,"%02d/%02d/%04d ", jj,mm,aa);
251 else if (fmt == FmtTimeOnly)
252 sprintf(buff,"%02d:%02d:%02.3f ", hh,min,sec);
253 else
254 sprintf(buff,"%02d/%02d/%04d %02d:%02d:%02.1f UT", jj,mm,aa,hh,min,sec);
255 }
256 return buff;
257}
258
259/*!
260\param fmt : String format for the date
261 - FmtPackedDateTime : YYYY-MM-DDThh:mm:ss.s
262 - FmtDateOnly : dd/mm/yyyy
263 - FmtTimeOnly : hh:mm:ss.s
264 - FmtDateTime : dd/mm/yyyy hh:mm:ss.s UT
265*/
266void TimeStamp::Print(ostream& os, StrFmt fmt) const
267{
268 os << " " << ToString(fmt) << " ";
269}
270
271int TimeStamp::MonthDays(int annee, int mois)
272{
273 if (mois<1 || mois>12) throw ParmError("TimeStamp::MonthDays month out of range");
274
275 switch(mois) {
276 case mois_Janvier:
277 case mois_Mars:
278 case mois_Mai:
279 case mois_Juillet:
280 case mois_Aout:
281 case mois_Octobre:
282 case mois_Decembre:
283 return 31;
284 case mois_Avril:
285 case mois_Juin:
286 case mois_Septembre:
287 case mois_Novembre:
288 return 30;
289 case mois_Fevrier:
290 return (((annee%4 == 0) && (annee%100 != 0)) || (annee%400 == 0)) ? 29 : 28;
291 }
292 return -1;
293}
294
295int TimeStamp::YearDays(int annee)
296// Retourne le nombre de jours dans l'année
297{
298 return (((annee%4 == 0) && (annee%100 != 0)) || (annee%400 == 0)) ? 366 : 365;
299}
300
301int_8 TimeStamp::ConvertToDays(int AA, int MM, int JJ)
302{
303 int_8 t = 0;
304 // if (!UndetDate()) {
305 int nban = AA-1901;
306 if (nban >= 0)
307 t = nban*365 + (nban/4) - (nban/100) + ((nban+300)/400);
308 else
309 t = nban*365 + (nban/4) - (nban/100) + ((nban-100)/400);
310 for (int i=1; i<MM; i++) t += TimeStamp::MonthDays(AA, i);
311 t += JJ;
312 // }
313 return t;
314}
315
316//----------------------------------------------------------
317// Classe pour la gestion de persistance
318// ObjFileIO<TimeStamp>
319//----------------------------------------------------------
320
321/* --Methode-- */
322DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
323void ObjFileIO<TimeStamp>::WriteSelf(POutPersist& s) const
324{
325 if (dobj == NULL)
326 throw NullPtrError("ObjFileIO<TimeStamp>::WriteSelf() dobj=NULL");
327 int_4 ver;
328 ver = 1;
329 s.Put(ver); // Lecture numero de version PPF
330 s.Put(dobj->DaysPart());
331 s.Put(dobj->SecondsPart());
332}
333
334/* --Methode-- */
335DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
336void ObjFileIO<TimeStamp>::ReadSelf(PInPersist& s)
337{
338 int_4 ver;
339 s.Get(ver); // Lecture numero de version PPF
340 r_8 seconds;
341 int_8 days;
342 s.Get(days);
343 s.Get(seconds);
344
345 if (dobj == NULL) dobj = new TimeStamp(days, seconds);
346 else dobj->Set(days, seconds);
347}
348
349
350#ifdef __CXX_PRAGMA_TEMPLATES__
351#pragma define_template ObjFileIO<TimeStamp>
352#endif
353
354#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
355template class ObjFileIO<TimeStamp>;
356#endif
357
358} // FIN namespace SOPHYA
Note: See TracBrowser for help on using the repository browser.