| 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 |