// file : odb/boost/date-time/mysql/posix-time-traits.hxx // copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_BOOST_DATE_TIME_MYSQL_POSIX_TIME_TRAITS_HXX #define ODB_BOOST_DATE_TIME_MYSQL_POSIX_TIME_TRAITS_HXX #include #include // std::abs #include #include #include #include namespace odb { namespace mysql { template <> struct default_value_traits< ::boost::posix_time::ptime, id_datetime> { typedef ::boost::posix_time::ptime ptime; typedef ::boost::posix_time::time_duration time_duration; typedef ::boost::gregorian::date date; typedef ptime value_type; typedef ptime query_type; typedef MYSQL_TIME image_type; static void set_value (ptime& v, const MYSQL_TIME& i, bool is_null) { if (is_null) v = ptime (::boost::date_time::not_a_date_time); else { // Since MySQL 5.6.4, the microseconds part is no longer ignored. // unsigned long long fract_s (i.second_part); fract_s = fract_s * time_duration::ticks_per_second () / 1000000ULL; v = ptime ( date (i.year, i.month, i.day), time_duration ( i.hour, i.minute, i.second, static_cast (fract_s))); } } static void set_image (MYSQL_TIME& i, bool& is_null, const ptime& v) { if (v.is_special ()) { if (v.is_not_a_date_time ()) is_null = true; else throw odb::boost::date_time::special_value (); } else { is_null = false; i.neg = false; const date& d (v.date ()); i.year = d.year (); i.month = d.month (); i.day = d.day (); const time_duration& t (v.time_of_day ()); i.hour = t.hours (); i.minute = t.minutes (); i.second = t.seconds (); unsigned long long ms (t.fractional_seconds ()); ms = ms * 1000000ULL / time_duration::ticks_per_second (); i.second_part = static_cast (ms); } } }; template <> struct default_value_traits< ::boost::posix_time::ptime, id_timestamp> { typedef ::boost::posix_time::ptime ptime; typedef ::boost::posix_time::time_duration time_duration; typedef ::boost::gregorian::date date; typedef ptime value_type; typedef ptime query_type; typedef MYSQL_TIME image_type; static void set_value (ptime& v, const MYSQL_TIME& i, bool is_null) { if (is_null) v = ptime (::boost::date_time::not_a_date_time); else { // Since MySQL 5.6.4, the microseconds part is no longer ignored. // unsigned long long fract_s (i.second_part); fract_s = fract_s * time_duration::ticks_per_second () / 1000000ULL; v = ptime ( date (i.year, i.month, i.day), time_duration ( i.hour, i.minute, i.second, static_cast (fract_s))); } } static void set_image (MYSQL_TIME& i, bool& is_null, const ptime& v) { if (v.is_special ()) { if (v.is_not_a_date_time ()) is_null = true; else throw odb::boost::date_time::special_value (); } else if (v < ptime (date (1970, ::boost::date_time::Jan, 1), time_duration (0, 0, 1)) || v > ptime (date (2038, ::boost::date_time::Jan, 19), time_duration (3, 14, 7))) throw odb::boost::date_time::value_out_of_range (); else { is_null = false; i.neg = false; const date& d (v.date ()); i.year = d.year (); i.month = d.month (); i.day = d.day (); const time_duration& t (v.time_of_day ()); i.hour = t.hours (); i.minute = t.minutes (); i.second = t.seconds (); unsigned long long ms (t.fractional_seconds ()); ms = ms * 1000000ULL / time_duration::ticks_per_second (); i.second_part = static_cast (ms); } } }; template <> struct default_value_traits< ::boost::posix_time::time_duration, id_time> { typedef ::boost::posix_time::time_duration time_duration; typedef time_duration value_type; typedef time_duration query_type; typedef MYSQL_TIME image_type; static const unsigned short max_hours = 838; static void set_value (time_duration& v, const MYSQL_TIME& i, bool is_null) { if (is_null) v = time_duration (::boost::date_time::not_a_date_time); else { // Since MySQL 5.6.4, the microseconds part is no longer ignored. // unsigned long long fract_s (i.second_part); fract_s = fract_s * time_duration::ticks_per_second () / 1000000ULL; v = time_duration ( i.hour, i.minute, i.second, static_cast (fract_s)); if (i.neg) v = v.invert_sign (); } } static void set_image (MYSQL_TIME& i, bool& is_null, const time_duration& v) { if (v.is_special ()) { if (v.is_not_a_date_time ()) is_null = true; else throw odb::boost::date_time::special_value (); } else if (std::abs (v.hours ()) > max_hours) throw odb::boost::date_time::value_out_of_range (); else { is_null = false; i.neg = v.is_negative (); i.year = 0; i.month = 0; i.day = 0; i.hour = std::abs (v.hours ()); i.minute = std::abs (v.minutes ()); i.second = std::abs (v.seconds ()); // Some compilers, e.g., VC8, don't have 64-bit abs() overload. // time_duration::fractional_seconds_type sms (v.fractional_seconds ()); unsigned long long ms (sms >= 0 ? sms : -sms); ms = ms * 1000000ULL / time_duration::ticks_per_second (); i.second_part = static_cast (ms); } } }; template <> struct default_type_traits< ::boost::posix_time::ptime> { static const database_type_id db_type_id = id_datetime; }; template <> struct default_type_traits< ::boost::posix_time::time_duration> { static const database_type_id db_type_id = id_time; }; } } #include #endif // ODB_BOOST_DATE_TIME_MYSQL_POSIX_TIME_TRAITS_HXX