Ticket #2523: filetime_functions.hpp.patch

File filetime_functions.hpp.patch, 6.0 KB (added by Marc Halbruegge <marc.halbruegge@…>, 14 years ago)

patch for boost/date_time/filetime_function.hpp

  • filetime_functions.hpp

     
    1616 */
    1717
    1818#include <boost/date_time/compiler_config.hpp>
    19 
    2019#if defined(BOOST_HAS_FTIME) // skip this file if no FILETIME
    21 
    22 #if defined(BOOST_USE_WINDOWS_H)
    23 #  include <windows.h>
    24 #endif
    25 
     20#include <windows.h>
    2621#include <boost/cstdint.hpp>
    2722#include <boost/date_time/time.hpp>
    2823
     24
    2925namespace boost {
    3026namespace date_time {
    3127
    32 namespace winapi {
    3328
    34 #if !defined(BOOST_USE_WINDOWS_H)
    35 
    36 extern "C" {
    37 
    38     struct FILETIME
    39     {
    40         boost::uint32_t dwLowDateTime;
    41         boost::uint32_t dwHighDateTime;
    42     };
    43     struct SYSTEMTIME
    44     {
    45         boost::uint16_t wYear;
    46         boost::uint16_t wMonth;
    47         boost::uint16_t wDayOfWeek;
    48         boost::uint16_t wDay;
    49         boost::uint16_t wHour;
    50         boost::uint16_t wMinute;
    51         boost::uint16_t wSecond;
    52         boost::uint16_t wMilliseconds;
    53     };
    54 
    55     __declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(FILETIME* lpFileTime);
    56     __declspec(dllimport) int __stdcall FileTimeToLocalFileTime(const FILETIME* lpFileTime, FILETIME* lpLocalFileTime);
    57     __declspec(dllimport) void __stdcall GetSystemTime(SYSTEMTIME* lpSystemTime);
    58     __declspec(dllimport) int __stdcall SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, FILETIME* lpFileTime);
    59 
    60 } // extern "C"
    61 
    62 #endif // defined(BOOST_USE_WINDOWS_H)
    63 
    64     typedef FILETIME file_time;
    65     typedef SYSTEMTIME system_time;
    66 
    67     inline void get_system_time_as_file_time(file_time& ft)
    68     {
    69 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
    70         // Some runtime library implementations expect local times as the norm for ctime.
    71         file_time ft_utc;
    72         GetSystemTimeAsFileTime(&ft_utc);
    73         FileTimeToLocalFileTime(&ft_utc, &ft);
    74 #elif defined(BOOST_NO_GETSYSTEMTIMEASFILETIME)
    75         system_time st;
    76         GetSystemTime(&st);
    77         SystemTimeToFileTime(&st, &ft);
    78 #else
    79         GetSystemTimeAsFileTime(&ft);
    80 #endif
    81     }
    82 
    83     /*!
    84      * The function converts file_time into number of nanoseconds elapsed since 1970-Jan-01
    85      *
    86      * \note The function is templated on the FILETIME type, so that
    87      *       it can be used with both native FILETIME and the ad-hoc
    88      *       boost::date_time::winapi::file_time type.
    89      */
    90     template< typename FileTimeT >
    91     inline boost::uint64_t file_time_to_nanoseconds(FileTimeT const& ft)
    92     {
    93         /* shift is difference between 1970-Jan-01 & 1601-Jan-01
    94         * in 100-nanosecond intervals */
    95         const uint64_t c1 = 27111902UL;
    96         const uint64_t c2 = 3577643008UL; // issues warning without 'UL'
    97         const uint64_t shift = (c1 << 32) + c2;
    98 
    99         union {
    100             FileTimeT as_file_time;
    101             uint64_t as_integer;
    102         } caster;
    103         caster.as_file_time = ft;
    104 
    105         caster.as_integer -= shift; // filetime is now 100-nanos since 1970-Jan-01
    106         return (caster.as_integer * 100); // upscale to nanoseconds
    107     }
    108 
    109 } // namespace winapi
    110 
    11129  //! Create a time object from an initialized FILETIME struct.
    112   /*!
    113    * Create a time object from an initialized FILETIME struct.
     30  /*! Create a time object from an initialized FILETIME struct.
    11431   * A FILETIME struct holds 100-nanosecond units (0.0000001). When
    115    * built with microsecond resolution the file_time's sub second value
    116    * will be truncated. Nanosecond resolution has no truncation.
    117    *
    118    * \note The function is templated on the FILETIME type, so that
    119    *       it can be used with both native FILETIME and the ad-hoc
    120    *       boost::date_time::winapi::file_time type.
    121    */
    122   template< typename TimeT, typename FileTimeT >
     32   * built with microsecond resolution the FILETIME's sub second value
     33   * will be truncated. Nanosecond resolution has no truncation. */
     34  template<class time_type>
    12335  inline
    124   TimeT time_from_ftime(const FileTimeT& ft)
    125   {
    126     typedef typename TimeT::date_type date_type;
    127     typedef typename TimeT::date_duration_type date_duration_type;
    128     typedef typename TimeT::time_duration_type time_duration_type;
     36  time_type time_from_ftime(const FILETIME& ft){
     37    typedef typename time_type::date_type date_type;
     38    typedef typename time_type::date_duration_type date_duration_type;
     39    typedef typename time_type::time_duration_type time_duration_type;
    12940
    130     uint64_t nanos = winapi::file_time_to_nanoseconds(ft);
     41    const long sec_pr_day = 86400; // seconds per day
    13142
    132     uint64_t sec = nanos / 1000000000UL;
    133     uint32_t sub_sec = (nanos % 1000000000UL); // nanoseconds since the last second
    134 #if !defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG)
    135     sub_sec /= 1000; // truncate to microseconds
     43    uint64_t filetime = ft.dwHighDateTime;
     44    filetime <<= 32;
     45    filetime += ft.dwLowDateTime;
     46
     47    uint64_t sec = filetime / 10000000;
     48#if defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG)
     49    uint64_t sub_sec = (filetime % 10000000) * 100; // nanoseconds
     50#else
     51    uint64_t sub_sec = (filetime % 10000000) / 10; // truncate to microseconds
    13652#endif
    13753
    13854    // split sec into usable chunks: days, hours, minutes, & seconds
    139     const uint32_t sec_per_day = 86400; // seconds per day
    140     uint32_t days = static_cast< uint32_t >(sec / sec_per_day);
    141     uint32_t tmp = static_cast< uint32_t >(sec % sec_per_day);
    142     uint32_t hours = tmp / 3600; // sec_per_hour
     55    long _d = (long)(sec / sec_pr_day);
     56    long tmp = (long)(sec % sec_pr_day);
     57    long _h = tmp / 3600; // sec_pr_hour
    14358    tmp %= 3600;
    144     uint32_t minutes = tmp / 60; // sec_per_min
     59    long _m = tmp / 60; // sec_pr_min
    14560    tmp %= 60;
    146     uint32_t seconds = tmp; // seconds
     61    long _s = tmp; // seconds
    14762
    148     date_duration_type dd(days);
    149     date_type d = date_type(1970, Jan, 01) + dd;
    150     return TimeT(d, time_duration_type(hours, minutes, seconds, sub_sec));
    151   }
     63    date_duration_type dd(_d);
     64    date_type d = date_type(1601, Jan, 01) + dd;
     65    return time_type(d, time_duration_type(_h, _m, _s, sub_sec));
     66        }
    15267
    15368}} // boost::date_time
    15469