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

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

Ajout namespace SOPHYA ds les fichiers .cc au lieu de include sopnamsp.h en presence de DECL_TEMP_SPEC , 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 SOPHYA::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.