libcryptosec
DateTime.h
Go to the documentation of this file.
1 #ifndef DATETIME_H_
2 #define DATETIME_H_
3 
4 #include <openssl/asn1.h>
5 
6 #include <time.h>
7 #include <string>
8 #include <iostream>
9 #include <iomanip>
10 #include <sstream>
11 #include <cmath>
12 
13 #include "BigInteger.h"
15 
16 
17 
27 class DateTime
28 {
29 public:
30 
35  struct DateVal
36  {
37  int sec; /* Seconds. [0-60] (1 leap second) */
38  int min; /* Minutes. [0-59] */
39  int hour; /* Hours. [0-23] */
40  int dayOfMonth; /* Day. [1-31] */
41  int mon; /* Month. [0-11] */
42  int year; /* Year */
43  int dayOfWeek; /* Day of week. [0-6] */
44  int dayOfYear; /* Days of year.[0-365] */
45  };
46 
52 
59  DateTime(time_t dateTime) throw(BigIntegerException);
60 
66  DateTime(BigInteger const& dateTime) throw(BigIntegerException);
67 
73  DateTime(ASN1_TIME *asn1Time) throw(BigIntegerException);
74 
81  DateTime(std::string utc) throw(BigIntegerException);
82 
86  virtual ~DateTime();
87 
92  std::string getXmlEncoded(std::string tab = "") const throw(BigIntegerException);
93 
98  void setDateTime(time_t dateTime) throw(BigIntegerException);
99 
104  void setDateTime(BigInteger const& dateTime) throw(BigIntegerException);
105 
110  time_t getDateTime() const throw(BigIntegerException);
111 
116  BigInteger const& getSeconds() const throw();
117 
122  ASN1_TIME* getAsn1Time() const throw(BigIntegerException);
123 
128  ASN1_TIME* getGeneralizedTime() const throw(BigIntegerException);
129 
134  ASN1_TIME* getUTCTime() const throw(BigIntegerException);
135 
140  std::string getISODate() const throw(BigIntegerException);
141 
146  DateTime& operator =(const DateTime& value) throw(BigIntegerException);
147 
153  static DateTime::DateVal getDate(BigInteger const& epoch) throw(BigIntegerException)
154  {
155  const long SECS_DAY = 86400L;
156  DateTime::DateVal ret;
157  BigInteger yearsSinceEpoch(0L);
158  BigInteger leapDays(0L);
159  BigInteger daysSinceEpoch(0L);
160  BigInteger tmp;
161  BigInteger hours(epoch);
162  BigInteger days(epoch);
163  int dayOfYear;
164  int sizeOfMonth;
165 
166  hours.mod(SECS_DAY);
167  days.div(SECS_DAY);
168 
169  tmp = hours % 60;
170  ret.sec = static_cast<int>(tmp.getValue());
171 
172  tmp = (hours % 3600).div(60);
173  ret.min = static_cast<int>(tmp.getValue());
174 
175  hours.div(3600);
176  ret.hour = static_cast<int>(hours.getValue());
177 
178  ret.year = 1970;
179  //remover
180  //int anos = 0;
181  //BigInteger sum(0L);
182  //cout << "days inicial " <<days.toDec() << endl;
183  //
184  while(days >= DateTime::getYearSize(ret.year))
185  {
186  days.sub(DateTime::getYearSize(ret.year));
187  ret.year++;
188 
189  //remover
190  //anos++;
191  //sum.add(DateTime::getYearSize(ret.year));
192  }
193  //cout << "sum "<< sum.toDec() << endl;
194  //cout << "days restantes " << days.toDec() << endl;
195  //cout << "anos" << anos << endl;
196 
197  ret.dayOfYear = static_cast<int>(days.getValue());
198  dayOfYear = ret.dayOfYear;
199 
200  ret.mon = 0;
201  sizeOfMonth = DateTime::getMonthSize(ret.mon, ret.year);
202  while(dayOfYear >= sizeOfMonth)
203  {
204  dayOfYear-= sizeOfMonth;
205  ret.mon++;
206  sizeOfMonth = DateTime::getMonthSize(ret.mon, ret.year);
207  }
208  ret.dayOfMonth = dayOfYear + 1;
209 
210  ret.dayOfWeek = DateTime::getDayOfWeek(ret.year, ret.mon, ret.dayOfMonth);
211 
212  return ret;
213  }
214 /* {
215  int daysOfMonths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
216  DateTime::DateVal ret;
217  int month = 1;
218  int minLeft = 0;
219  BigInteger yearsSinceEpoch(0L);
220  BigInteger leapDays(0L);
221  BigInteger daysSinceEpoch(0L);
222  BigInteger tmp;
223  int mod;
224 
225  ret.mon = 0;
226 
227  //anos desde 1970
228  //yearsSinceEpoch = epoch / (365 * 24 * 60 * 60);
229 
230  //ret.year = static_cast<int>((1970 + yearsSinceEpoch).getValue());
231 
232  //leapdays decorrentes a anos bissextos
233  yearsSinceEpoch = epoch / (365 * 24 * 60 * 60);
234  leapDays = yearsSinceEpoch / 4;
235 
236 
237  * A divisao (ano-1970)/4 mostra quantos anos bissextos existem. Esse numero é fracionário
238  * que e deve ser interpretado da seguinte forma: fracao >= 5 -> arredonda pra cima, caso contrário
239  * arredonda pra baixo.
240  *
241  * Porém a parte fracionária é truncada na divisão entre inteiros. Assim usa-se módulo da seguinte forma:
242  *
243  * (ano-1970)mod 4 = 0/1 => corresponde a .0 e .25 => Nao faz nada.
244  * (ano-1970)mod 4 = 2 => ano é bissexto. Verificar se o mês > fevereiro
245  * (ano-1970)mod 4 = 3 => corresponde a .75 => Incrementa
246  *
247  mod = static_cast<int>((yearsSinceEpoch % 4).getValue());
248  //cout << yearsSinceEpoch.toDec() << endl;
249  switch(mod)
250  {
251  case 3:
252  leapDays.add(1);
253  break;
254 
255  case 2:
256  daysOfMonths[1]++;
257  break;
258 
259  default :
260  break;
261  }
262 
263  //yearsSinceEpoch descontando-se os leapdays
264  yearsSinceEpoch = (epoch - (leapDays * 24 * 60 *60)) / (365 * 24 * 60 * 60);
265  ret.year = static_cast<int>((1970 + yearsSinceEpoch).getValue());
266 
267  //dias desde 1970
268  daysSinceEpoch = epoch / (24*60*60);
269 
270  //cout << daysSinceEpoch.toDec() << endl;
271  //cout << leapDays.toDec() << endl;
272 
273  //subtract leap days
274  daysSinceEpoch = daysSinceEpoch - leapDays;
275 
276  //dayofyear
277  ret.dayOfYear = static_cast<int>((daysSinceEpoch % 365).getValue());
278 
279  //verifica se eh ano bissexto
280  if(DateTime::isLeapYear(ret.year))
281  {
282  daysOfMonths[1]++;
283  }
284 
285  //dayOfMonth = ret.tm_yday;
286  ret.dayOfMonth = ret.dayOfYear + 1; //dayOfYear [0-365], dayOfMonth [1-31]
287 
288  for(int i = 0 ; i < 12 ; i++)
289  {
290  ret.dayOfMonth-= daysOfMonths[i];
291 
292  if(ret.dayOfMonth > 0)
293  {
294  month++;
295  ret.mon++;
296  }
297  else
298  {
299  ret.dayOfMonth+= daysOfMonths[i];
300  break;
301  }
302  }
303 
304  tmp = epoch - ((daysSinceEpoch + leapDays) * 24 * 60 * 60);
305  ret.sec = static_cast<int>(tmp.getValue());
306 
307  ret.hour = ret.sec / (60*60);
308 
309  minLeft = ret.sec - (ret.hour * 60 * 60);
310 
311  ret.min = minLeft / 60;
312 
313  ret.sec = minLeft - (ret.min * 60);
314 
315  ret.dayOfWeek = DateTime::getDayOfWeek(ret.year, ret.mon, ret.dayOfMonth);
316 
317  return ret;
318  }*/
319 
324  void addSeconds(long b) throw(BigIntegerException);
325 
330  void addMinutes(long b) throw(BigIntegerException);
331 
336  void addHours(long b) throw(BigIntegerException);
337 
342  void addDays(long b) throw(BigIntegerException);
343 
348  void addYears(long b) throw(BigIntegerException);
349 
355  static BigInteger date2epoch(string aString) throw(BigIntegerException)
356  {
357  int year;
358  int month; //[0-11]
359  int day; //[1-31]
360  int hour; //[0-23]
361  int min; //[0-59]
362  int sec; //[0-59] + leap second?
363  bool utc = false;
364  istringstream stream;
365  int gtoffset = 0; //deslocamento adicionar para substring se for generalizedtime
366 
367  utc = aString.size() == 13;
368 
369  //year
370  if(utc)
371  {
372  stream.str(aString.substr(0,2));
373  stream >> year;
374 
375  if(year >= 50)
376  {
377  year+= 1900;
378  }
379  else
380  {
381  year+= 2000;
382  }
383  }
384  else //gt
385  {
386  stream.str(aString.substr(0,4));
387  stream >> year;
388  gtoffset = 2;
389  }
390 
391  //month
392  stream.clear();
393  stream.str(aString.substr(2 + gtoffset,2));
394  stream >> month;
395  month--;
396 
397  //day
398  stream.clear();
399  stream.str(aString.substr(4 + gtoffset,2));
400  stream >> day;
401 
402  //hour
403  stream.clear();
404  stream.str(aString.substr(6 + gtoffset,2));
405  stream >> hour;
406 
407  //min
408  stream.clear();
409  stream.str(aString.substr(8 + gtoffset,2));
410  stream >> min;
411 
412  //sec
413  stream.clear();
414  stream.str(aString.substr(10 + gtoffset,2));
415  stream >> sec;
416 
417  return date2epoch(year, month, day, hour, min, sec);
418  }
419 
424  static BigInteger date2epoch(int year, int month, int day, int hour, int min, int sec) throw(BigIntegerException)
425  {
426  BigInteger ret(0L);
427 
428  for(int i = 1970; i < year; i++)
429  {
430  ret.add(DateTime::getYearSize(i));
431  }
432 
433  for(int i = 0 ; i < month ; i ++)
434  {
435  ret.add(DateTime::getMonthSize(i, year));
436  }
437 
438  ret.add(day - 1);
439  ret.mul(24);
440  ret.add(hour);
441  ret.mul(60);
442  ret.add(min);
443  ret.mul(60);
444  ret.add(sec);
445 
446  return ret;
447  }
448 
449  /***
450  * Retorna o dia da semana dados ano, mês [0-11] e dia [1-31].
451  * @return dia da semana: 0 para Domingo, 6 para Sábado.
452  * obs: code adapted from http://www.sislands.com/coin70/week3/dayofwk.htm
453  * */
454  static int getDayOfWeek(int year, int month, int day) throw()
455  {
456  month++; //para adaptar ao algoritmo
457 
458  int a = (14 - month) / 12;
459  int y = year - a;
460  int m = month + 12 * a - 2;
461  return (day + y + (y / 4) - (y / 100) + (y / 400) + ((31 * m) / 12)) % 7;
462  }
463 
464  /* static int getDayOfWeek(int year, int month, int day) throw()
465  {
466  int doomsDays[] = {3, 28, 7, 4, 9, 6, 11, 8, 5, 10, 7, 12};
467  int doomsDay;
468  int ret = 0;
469  int dayOfWeek;
470 
471  dayOfWeek = DateTime::getDoomsday(year);
472 
473  doomsDay = doomsDays[month];
474 
475  if(isLeapYear(year) & ( (month == 0) || (month == 1)) ) //jan and feb
476  {
477  doomsDay++;
478  }
479 
480  if(day < doomsDay)
481  {
482  ret = (dayOfWeek - (doomsDay - day)) % 7;
483  }
484  else if(day > doomsDay)
485  {
486  ret = (dayOfWeek + (day - doomsDay)) % 7;
487  }
488  else
489  {
490  ret = dayOfWeek;
491  }
492 
493  if(ret < 0)
494  {
495  ret += 7;
496  }
497 
498  return ret;
499  }*/
500 
506  /*inline static int getDoomsday(int year) throw() //YYYY
507  {
508  return (2 + year + (year/4) - (year/100) + (year/400)) % 7;
509  }*/
510 
516  inline static bool isLeapYear(int y) throw()
517  {
518  return (y>0) && !(y%4) && ( (y%100) || !(y%400) );
519  }
520 
526  inline static int getYearSize(int year)
527  {
528  int ret = 365;
529 
530  if(DateTime::isLeapYear(year))
531  {
532  ret = 366;
533  }
534 
535  return ret;
536  }
537 
544  inline static int getMonthSize(int month, int year)
545  {
546  int daysOfMonths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
547 
548  int ret = daysOfMonths[month];
549 
550  if( (DateTime::isLeapYear(year)) && (month == 1) )
551  {
552  ret++;
553  }
554 
555  return ret;
556  }
557 
558  bool operator==(const DateTime& other) const throw();
559  bool operator==(time_t other) const throw(BigIntegerException);
560 
561  bool operator<(const DateTime& other) const throw();
562  bool operator<(time_t other) const throw(BigIntegerException);
563 
564  bool operator>(const DateTime& other) const throw();
565  bool operator>(time_t other) const throw(BigIntegerException);
566 
567 
568 protected:
569  /*
570  * Segundos desde 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
571  * */
573 };
574 
575 #endif /*DATETIME_H_*/
void addMinutes(long b)
Definition: DateTime.cpp:351
Classe usada para representar números grandes. A limitação do tamanho do número depende da memória di...
Definition: BigInteger.h:23
BigInteger & mod(BigInteger const &a)
Definition: BigInteger.cpp:424
Implementa a representação da data. É utilizada em certificados, LCRs. Utiliza o formato epoch (time_...
Definition: DateTime.h:27
static int getMonthSize(int month, int year)
Definition: DateTime.h:544
static int getYearSize(int year)
Definition: DateTime.h:526
BigInteger & div(BigInteger const &a)
Definition: BigInteger.cpp:362
int dayOfYear
Definition: DateTime.h:44
int hour
Definition: DateTime.h:39
DateTime()
Definition: DateTime.cpp:4
int dayOfMonth
Definition: DateTime.h:40
ASN1_TIME * getUTCTime() const
Definition: DateTime.cpp:240
int dayOfWeek
Definition: DateTime.h:43
ASN1_TIME * getAsn1Time() const
Definition: DateTime.cpp:185
BigInteger & add(BigInteger const &a)
Definition: BigInteger.cpp:282
std::string getISODate() const
Definition: DateTime.cpp:289
BigInteger const & getSeconds() const
Definition: DateTime.cpp:341
int min
Definition: DateTime.h:38
bool operator==(const DateTime &other) const
Definition: DateTime.cpp:485
void addHours(long b)
Definition: DateTime.cpp:358
int mon
Definition: DateTime.h:41
time_t getDateTime() const
Definition: DateTime.cpp:134
void addSeconds(long b)
Definition: DateTime.cpp:346
double getValue() const
Definition: BigInteger.cpp:119
bool operator>(const DateTime &other) const
Definition: DateTime.cpp:505
void setDateTime(time_t dateTime)
Definition: DateTime.cpp:124
int year
Definition: DateTime.h:42
void addYears(long b)
Definition: DateTime.cpp:375
static DateTime::DateVal getDate(BigInteger const &epoch)
Definition: DateTime.h:153
BigInteger & mul(BigInteger const &a)
Definition: BigInteger.cpp:313
static int getDayOfWeek(int year, int month, int day)
Definition: DateTime.h:454
BigInteger & sub(BigInteger const &a)
Definition: BigInteger.cpp:298
Definition: BigIntegerException.h:7
BigInteger seconds
Definition: DateTime.h:572
static BigInteger date2epoch(string aString)
Definition: DateTime.h:355
void addDays(long b)
Definition: DateTime.cpp:366
std::string getXmlEncoded(std::string tab="") const
Definition: DateTime.cpp:172
static bool isLeapYear(int y)
Definition: DateTime.h:516
int sec
Definition: DateTime.h:37
static BigInteger date2epoch(int year, int month, int day, int hour, int min, int sec)
Definition: DateTime.h:424
bool operator<(const DateTime &other) const
Definition: DateTime.cpp:495
ASN1_TIME * getGeneralizedTime() const
Definition: DateTime.cpp:202
Definition: DateTime.h:35