ClickHouse/libs/libmysqlxx/include/mysqlxx/Date.h

185 lines
4.3 KiB
C
Raw Normal View History

2011-03-09 19:18:01 +00:00
#ifndef MYSQLXX_DATE_H
#define MYSQLXX_DATE_H
2011-03-15 20:56:42 +00:00
#include <string.h>
2011-03-09 19:18:01 +00:00
#include <string>
#include <Yandex/DateLUT.h>
#include <mysqlxx/Exception.h>
namespace mysqlxx
{
2011-03-18 20:26:54 +00:00
/** Хранит дату в broken-down виде.
* Может быть инициализирован из даты в текстовом виде '2011-01-01' и из time_t.
* Может быть инициализирован из даты в текстовом виде '20110101...(юзаются первые 8 символов)
2011-03-18 20:26:54 +00:00
* Неявно преобразуется в time_t.
* Сериализуется в ostream в текстовом виде.
* Внимание: преобразование в unix timestamp и обратно производится в текущей тайм-зоне!
* При переводе стрелок назад, возникает неоднозначность - преобразование производится в меньшее значение.
*
2011-03-31 15:38:32 +00:00
* packed - для memcmp (из-за того, что m_year - 2 байта, little endian, работает корректно только до 2047 года)
2011-03-18 20:26:54 +00:00
*/
2011-10-14 11:32:08 +00:00
class Date
2011-03-09 19:18:01 +00:00
{
private:
2011-10-14 11:32:08 +00:00
struct __attribute__ ((__packed__)) {
unsigned short m_year;
unsigned char m_month;
unsigned char m_day;
} data;
2011-03-09 19:18:01 +00:00
2011-03-10 20:31:02 +00:00
void init(time_t time)
2011-03-09 19:18:01 +00:00
{
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
const Yandex::DateLUT::Values & values = date_lut.getValues(time);
2011-10-14 11:32:08 +00:00
data.m_year = values.year;
data.m_month = values.month;
data.m_day = values.day_of_month;
2011-03-10 20:31:02 +00:00
}
void init(const char * s, size_t length)
{
if(length < 8)
2011-03-10 20:31:02 +00:00
throw Exception("Cannot parse Date: " + std::string(s, length));
2011-10-14 11:32:08 +00:00
data.m_year = (s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0');
if(s[4] == '-')
{
if(length < 10)
throw Exception("Cannot parse Date: " + std::string(s, length));
2011-10-14 11:32:08 +00:00
data.m_month = (s[5] - '0') * 10 + (s[6] - '0');
data.m_day = (s[8] - '0') * 10 + (s[9] - '0');
}
else
{
2011-10-14 11:32:08 +00:00
data.m_month = (s[4] -'0') * 10 + (s[5] -'0');
data.m_day = (s[6] - '0')* 10 + (s[7] -'0');
}
2011-03-10 20:31:02 +00:00
}
public:
2011-03-15 20:56:42 +00:00
explicit Date(time_t time)
2011-03-10 20:31:02 +00:00
{
init(time);
2011-03-09 19:18:01 +00:00
}
Date(unsigned short year_, unsigned char month_, unsigned char day_)
{
2011-10-14 11:32:08 +00:00
data.m_year = year_;
data.m_month = month_;
data.m_day = day_;
2011-03-09 19:18:01 +00:00
}
2011-03-15 20:56:42 +00:00
explicit Date(const std::string & s)
2011-03-09 19:18:01 +00:00
{
2011-03-10 20:31:02 +00:00
init(s.data(), s.size());
}
2011-03-09 19:18:01 +00:00
2011-03-10 20:31:02 +00:00
Date(const char * data, size_t length)
{
init(data, length);
2011-03-09 19:18:01 +00:00
}
2011-03-10 20:31:02 +00:00
Date()
2011-03-09 19:18:01 +00:00
{
2011-03-10 20:31:02 +00:00
init(time(0));
2011-03-09 19:18:01 +00:00
}
2011-04-25 20:31:34 +00:00
Date(const Date & x)
{
operator=(x);
}
Date & operator= (const Date & x)
{
2011-10-14 11:32:08 +00:00
data.m_year = x.data.m_year;
data.m_month = x.data.m_month;
data.m_day = x.data.m_day;
2011-04-25 20:31:34 +00:00
return *this;
}
2011-03-15 20:56:42 +00:00
Date & operator= (time_t time)
{
init(time);
return *this;
}
2011-03-09 19:18:01 +00:00
operator time_t() const
{
2011-10-14 11:32:08 +00:00
return Yandex::DateLUTSingleton::instance().makeDate(data.m_year, data.m_month, data.m_day);
2011-03-09 19:18:01 +00:00
}
Yandex::DayNum_t getDayNum() const
{
2011-10-14 11:32:08 +00:00
return Yandex::DateLUTSingleton::instance().makeDayNum(data.m_year, data.m_month, data.m_day);
}
operator Yandex::DayNum_t() const
{
return getDayNum();
}
2011-10-14 11:32:08 +00:00
unsigned short year() const { return data.m_year; }
unsigned char month() const { return data.m_month; }
unsigned char day() const { return data.m_day; }
2011-03-09 19:18:01 +00:00
2011-10-14 11:32:08 +00:00
void year(unsigned short x) { data.m_year = x; }
void month(unsigned char x) { data.m_month = x; }
void day(unsigned char x) { data.m_day = x; }
2011-03-09 19:18:01 +00:00
bool operator< (const Date & other) const
{
2011-10-14 11:32:08 +00:00
if(memcmp( &data, &other.data, sizeof(data)) < 0)
return true;
return false;
2011-03-09 19:18:01 +00:00
}
2011-03-21 19:46:50 +00:00
bool operator> (const Date & other) const
{
2011-10-14 11:32:08 +00:00
if(memcmp( &data, &other.data, sizeof(data)) > 0)
return true;
return false;
2011-03-21 19:46:50 +00:00
}
bool operator<= (const Date & other) const
{
2011-10-14 11:32:08 +00:00
if(memcmp(&data, &other.data, sizeof(data)) <= 0)
return true;
return false;
2011-03-21 19:46:50 +00:00
}
bool operator>= (const Date & other) const
{
2011-10-14 11:32:08 +00:00
if(memcmp(&data, &other.data, sizeof(data)) >= 0)
return true;
return false;
2011-03-21 19:46:50 +00:00
}
2011-03-09 19:18:01 +00:00
bool operator== (const Date & other) const
{
2011-10-14 11:32:08 +00:00
if(memcmp(&data, &other.data, sizeof(data)) == 0)
return true;
return false;
2011-03-09 19:18:01 +00:00
}
bool operator!= (const Date & other) const
{
return !(*this == other);
}
};
inline std::ostream & operator<< (std::ostream & ostr, const Date & date)
{
return ostr << date.year()
2011-03-10 20:31:02 +00:00
<< '-' << (date.month() / 10) << (date.month() % 10)
<< '-' << (date.day() / 10) << (date.day() % 10);
2011-03-09 19:18:01 +00:00
}
}
#endif