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

Last change on this file since 3208 was 3082, checked in by ansari, 19 years ago

Ajout qualification explicite du namespace SOPHYA pour instanciation explicite ds timestamp.cc - Reza 19/09/2006

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