Преобразование числа 100 нс с 1601 года для ускорения посикса в C ++ - PullRequest
0 голосов
/ 26 января 2011

Я получаю метки времени от поставщика данных, которые соответствуют этой спецификации:

number of 100 nanoseconds since 1601

Я использую boost::posix_time::ptime и хочу преобразовать метки времени в posix time.Есть ли простой способ сделать это?

Ответы [ 2 ]

3 голосов
/ 26 января 2011

Когда произошло переключение с юлианского на григорианский календарь для этой системы? Некоторые страны перешли до 1 января 1601 года; другие не переключались намного позже. Это критически повлияет на ваши расчеты - примерно на 11 дней.

Поскольку имеется 10 7 единиц по 100 нс каждая в одну секунду, вы делите начальное число на 10 7 , чтобы получить количество секунд с начала отсчета времени (остаток это доля секунды). Затем вы делите это на 86400, чтобы получить количество дней (остаток - время дня). Затем вы можете вычислить дату из числа дней.

Поскольку время POSIX использует 1970-01-01 00:00:00 в качестве эталона, вам может просто потребоваться вычислить правильное количество секунд между 1601-01-01 00:00:00 и эпохой POSIX (как это известен) и вычтите это число из рассчитанного вами количества секунд.

1 голос
/ 26 января 2011

number of 100 nanoseconds since 1601

Это значение Windows FILETIME.

Boost.DateTime фактически использует Windows FILETIME для платформы Windows.

Ниже приведен соответствующий исходный код Boost, который преобразует FILETIME в boost :: posix_time :: ptime:
(из boost / date_time / microsec_time_clock.hpp)

static time_type create_time(time_converter converter)
{
  winapi::file_time ft;
  winapi::get_system_time_as_file_time(ft);
  uint64_t micros = winapi::file_time_to_microseconds(ft); // it will not wrap, since ft is the current time
                                                           // and cannot be before 1970-Jan-01
  std::time_t t = static_cast<std::time_t>(micros / 1000000UL); // seconds since epoch
  // microseconds -- static casts supress warnings
  boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);

  std::tm curr;
  std::tm* curr_ptr = converter(&t, &curr);
  date_type d(curr_ptr->tm_year + 1900,
              curr_ptr->tm_mon + 1,
              curr_ptr->tm_mday);

  //The following line will adjust the fractional second tick in terms
  //of the current time system.  For example, if the time system
  //doesn't support fractional seconds then res_adjust returns 0
  //and all the fractional seconds return 0.
  int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000);

  time_duration_type td(curr_ptr->tm_hour,
                        curr_ptr->tm_min,
                        curr_ptr->tm_sec,
                        sub_sec * adjust);

  return time_type(d,td);
}

Вы можете просмотреть вашу установку Boost для детальной реализации.

...