File indexing completed on 2025-01-18 09:30:38
0001 #ifndef DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
0002 #define DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <boost/cstdint.hpp>
0018 #include <boost/shared_ptr.hpp>
0019 #include <boost/detail/workaround.hpp>
0020 #include <boost/date_time/compiler_config.hpp>
0021 #include <boost/date_time/c_time.hpp>
0022 #include <boost/date_time/time_clock.hpp>
0023 #if defined(BOOST_HAS_FTIME)
0024 #include <boost/winapi/time.hpp>
0025 #endif
0026
0027 #ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
0028
0029 namespace boost {
0030 namespace date_time {
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 template<class time_type>
0041 class microsec_clock
0042 {
0043 private:
0044
0045 typedef std::tm* (*time_converter)(const std::time_t*, std::tm*);
0046
0047 public:
0048 typedef typename time_type::date_type date_type;
0049 typedef typename time_type::time_duration_type time_duration_type;
0050 typedef typename time_duration_type::rep_type resolution_traits_type;
0051
0052
0053
0054 template<class time_zone_type>
0055 static time_type local_time(shared_ptr<time_zone_type> tz_ptr)
0056 {
0057 typedef typename time_type::utc_time_type utc_time_type;
0058 typedef second_clock<utc_time_type> second_clock;
0059
0060
0061 utc_time_type utc_time = second_clock::universal_time();
0062 time_duration_type utc_offset = second_clock::local_time() - utc_time;
0063
0064
0065 utc_time = microsec_clock<utc_time_type>::local_time() - utc_offset;
0066 return time_type(utc_time, tz_ptr);
0067 }
0068
0069
0070 static time_type local_time()
0071 {
0072 return create_time(&c_time::localtime);
0073 }
0074
0075
0076 static time_type universal_time()
0077 {
0078 return create_time(&c_time::gmtime);
0079 }
0080
0081 private:
0082 static time_type create_time(time_converter converter)
0083 {
0084 #ifdef BOOST_HAS_GETTIMEOFDAY
0085 timeval tv;
0086 gettimeofday(&tv, 0);
0087 std::time_t t = tv.tv_sec;
0088 boost::uint32_t sub_sec = tv.tv_usec;
0089 #elif defined(BOOST_HAS_FTIME)
0090 boost::winapi::FILETIME_ ft;
0091 boost::winapi::GetSystemTimeAsFileTime(&ft);
0092 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
0093
0094 {
0095 boost::winapi::FILETIME_ local_ft;
0096 boost::winapi::FileTimeToLocalFileTime(&ft, &local_ft);
0097 ft = local_ft;
0098 }
0099 #endif
0100
0101 boost::uint64_t micros = file_time_to_microseconds(ft);
0102
0103 std::time_t t = static_cast<std::time_t>(micros / 1000000UL);
0104
0105 boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);
0106 #else
0107 #error Internal Boost.DateTime error: BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is defined, however neither gettimeofday nor FILETIME support is detected.
0108 #endif
0109
0110 std::tm curr;
0111 std::tm* curr_ptr = converter(&t, &curr);
0112 date_type d(static_cast< typename date_type::year_type::value_type >(curr_ptr->tm_year + 1900),
0113 static_cast< typename date_type::month_type::value_type >(curr_ptr->tm_mon + 1),
0114 static_cast< typename date_type::day_type::value_type >(curr_ptr->tm_mday));
0115
0116
0117
0118
0119
0120 int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000);
0121
0122 time_duration_type td(static_cast< typename time_duration_type::hour_type >(curr_ptr->tm_hour),
0123 static_cast< typename time_duration_type::min_type >(curr_ptr->tm_min),
0124 static_cast< typename time_duration_type::sec_type >(curr_ptr->tm_sec),
0125 sub_sec * adjust);
0126
0127 return time_type(d,td);
0128 }
0129
0130 #if defined(BOOST_HAS_FTIME)
0131
0132
0133
0134
0135
0136 static boost::uint64_t file_time_to_microseconds(boost::winapi::FILETIME_ const& ft)
0137 {
0138
0139
0140 const boost::uint64_t shift = 116444736000000000ULL;
0141
0142
0143 boost::uint64_t ft_as_integer = (static_cast< boost::uint64_t >(ft.dwHighDateTime) << 32) | static_cast< boost::uint64_t >(ft.dwLowDateTime);
0144
0145 ft_as_integer -= shift;
0146 return (ft_as_integer / 10U);
0147 }
0148 #endif
0149 };
0150
0151
0152 } }
0153
0154 #endif
0155
0156
0157 #endif
0158