| | 117 | #else |
| | 118 | /* convert... |
| | 119 | 0. time_t to int64_t to avoid overflows |
| | 120 | 1. epoch beginning 1970 to one beginning 1601 |
| | 121 | 2. seconds to 100ns |
| | 122 | 3. int64_t to FILETIME */ |
| | 123 | int64_t t64 = static_cast<int64_t>(*t); |
| | 124 | t64 += 11644473600; |
| | 125 | t64 *= 10000000; |
| | 126 | FILETIME utc_time; |
| | 127 | utc_time.dwLowDateTime = static_cast<DWORD>(t64 & 0xFFFFFFFF); |
| | 128 | utc_time.dwHighDateTime= static_cast<DWORD>(t64 >> 32); |
| | 129 | // convert to local time |
| | 130 | FILETIME local_time; |
| | 131 | if(!FileTimeToLocalFileTime(&utc_time, &local_time)) |
| | 132 | boost::throw_exception(std::runtime_error("could not convert calendar time to local time")); |
| | 133 | // split into year, month, day etc |
| | 134 | SYSTEMTIME st; |
| | 135 | if(!FileTimeToSystemTime(&local_time, &st)) |
| | 136 | boost::throw_exception(std::runtime_error("could not convert calendar time to local time")); |
| | 137 | systime_to_tm(result, st); |
| | 138 | /* I'm not sure if MS Windows CE actually supports things like DST, at |
| | 139 | least I haven't found a way to retrieve the info. For that reason, use |
| | 140 | -1 to mark the info as not available. */ |
| | 141 | result->tm_isdst = -1; |
| | 142 | return result; |
| | 143 | #endif |
| | 154 | #else |
| | 155 | /* convert... |
| | 156 | 0. time_t to int64_t to avoid overflows |
| | 157 | 1. epoch beginning 1970 to one beginning 1601 |
| | 158 | 2. seconds to 100ns |
| | 159 | 3. int64_t to FILETIME */ |
| | 160 | int64_t t64 = static_cast<int64_t>(*t); |
| | 161 | t64 += 11644473600; |
| | 162 | t64 *= 10000000; |
| | 163 | FILETIME utc_time; |
| | 164 | utc_time.dwLowDateTime = static_cast<DWORD>(t64 & 0xFFFFFFFF); |
| | 165 | utc_time.dwHighDateTime= static_cast<DWORD>(t64 >> 32); |
| | 166 | // split into year, month, day etc |
| | 167 | SYSTEMTIME st; |
| | 168 | if(!FileTimeToSystemTime(&utc_time, &st)) |
| | 169 | boost::throw_exception(std::runtime_error("could not convert calendar time to local time")); |
| | 170 | systime_to_tm(result, st); |
| | 171 | /* MSVC8 implementation always sets tm_isdst=0 in gmtime(), using a |
| | 172 | German MS Windows XP, not sure if that is correct... */ |
| | 173 | result->tm_isdst = 0; |
| | 174 | return result; |
| | 175 | #endif |
| 123 | | return std::time(t); |
| | 186 | #if !defined(UNDER_CE) |
| | 187 | return std::time(p); |
| | 188 | #else |
| | 189 | SYSTEMTIME systime; |
| | 190 | GetSystemTime(&systime); |
| | 191 | FILETIME ft; |
| | 192 | if(!SystemTimeToFileTime(&systime, &ft)) |
| | 193 | boost::throw_exception(std::runtime_error("could not convert local time to file time")); |
| | 194 | /* convert |
| | 195 | 1. FILETIME to int64_t |
| | 196 | 2. 100ns to seconds |
| | 197 | 3. epoch beginning 1601 to one beginning 1970 |
| | 198 | 4. int64_t to time_t */ |
| | 199 | int64_t t64 = (static_cast<int64_t>(ft.dwHighDateTime) << 32) + ft.dwLowDateTime; |
| | 200 | t64 = (t64 + 5000000) / 10000000; |
| | 201 | t64 -= 11644473600; |
| | 202 | std::time_t res = static_cast<std::time_t>(t64); |
| | 203 | // make sure the static cast didn't truncate the result |
| | 204 | if(res != t64) |
| | 205 | boost::throw_exception(std::runtime_error("could not convert t64 to time_t")); |
| | 206 | if(p) |
| | 207 | *p = res; |
| | 208 | return res; |
| | 209 | #endif |
| | 211 | #if defined(UNDER_CE) |
| | 212 | private: |
| | 213 | /* utility function to convert a SYSTIME to a std::tm |
| | 214 | Most fields are equal or similar, but the day of the year requires some |
| | 215 | computations. */ |
| | 216 | inline static void systime_to_tm(std::tm* result, SYSTEMTIME const& st) |
| | 217 | { |
| | 218 | // assign the common values |
| | 219 | result->tm_sec = st.wSecond; |
| | 220 | result->tm_min = st.wMinute; |
| | 221 | result->tm_hour = st.wHour; |
| | 222 | result->tm_mday = st.wDay; |
| | 223 | result->tm_mon = st.wMonth - 1; |
| | 224 | result->tm_year = st.wYear - 1900; |
| | 225 | result->tm_wday = st.wDayOfWeek; |
| | 226 | // compute day of year |
| | 227 | bool leapyear; |
| | 228 | if((st.wYear % 1000) == 0) |
| | 229 | leapyear = true; |
| | 230 | else if((st.wYear % 100) == 0) |
| | 231 | leapyear = false; |
| | 232 | else if((st.wYear % 4) == 0) |
| | 233 | leapyear = true; |
| | 234 | else |
| | 235 | leapyear = false; |
| | 236 | result->tm_yday = result->tm_mday - 1; |
| | 237 | if(leapyear) |
| | 238 | { |
| | 239 | int const dpm[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
| | 240 | for(int i=0; i!=result->tm_mon; ++i) |
| | 241 | result->tm_yday += dpm[i]; |
| | 242 | } |
| | 243 | else |
| | 244 | { |
| | 245 | int const dpm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
| | 246 | for(int i=0; i!=result->tm_mon; ++i) |
| | 247 | result->tm_yday += dpm[i]; |
| | 248 | } |
| | 249 | } |
| | 250 | #endif |