У меня есть унаследованное приложение на C ++, которое создает временную метку входящего сетевого трафика с помощью функции CRT _ftime()
. Функция _ftime()
возвращает структуру _timeb
, которая имеет 32-битную и 64-битную реализацию. Мы используем 32-битную реализацию, которая выглядит следующим образом:
struct _timeb {
long time; // 4 bytes
unsigned short millitm; // 2 bytes
short timezone; // 2 bytes
short dstflag; // 2 bytes
};
Из документации MSDN, вот как интерпретируется каждое поле:
- dstflag - ненулевое значение, если в настоящее время действует переход на летнее время для местного часового пояса (объяснение того, как определяется летнее время, см.
_tzset
).
- миллиметр - доля секунды в миллисекундах
- время - время в секундах с полуночи (00:00:00), 1 января 1970 года, всемирное координированное время (UTC).
- часовой пояс - разница в минутах, двигаясь на запад, между UTC и местным временем. Значение часового пояса задается из значения глобальной переменной
_timezone
(см. _tzset
).
Я перерабатываю часть кода, которая делает отметку времени для использования C # в .NET 3.5 . Метки времени теперь генерируются с использованием структуры System.DateTime
, но мне все еще нужно преобразовать их обратно в структуру _timeb
, чтобы унаследованный код C ++ мог работать с ними. Вот как я делаю это в моей управляемой библиотеке C ++ bridge:
DateTime dateTime = DateTime::UtcNow;
DateTime baseTime(1970, 1, 1, 0, 0, 0, DateTimeKind::Utc);
TimeSpan delta = dateTime - baseTime;
_timeb timestamp;
timestamp.time = delta.TotalSeconds;
timestamp.millitm = dateTime.Millisecond;
timestamp.dstflag = TimeZoneInfo::Local->IsDaylightSavingTime(dateTime) ? 1 : 0;
timestamp.timezone = TimeZoneInfo::Local->BaseUtcOffset.TotalMinutes * -1;
Из того, что я могу сказать, похоже, это реконструирует структуру _timeb
, как если бы я звонил _ftime()
напрямую, и это хорошо. Дело в том, что временные метки являются важной частью нашего приложения, поэтому это должно быть правильно.
У меня вопрос двоякий.
- Мой алгоритм как-то несовершенен? Кто-нибудь видит что-нибудь очевидное, что я пропустил? Существуют ли граничные условия, в которых это не сработает?
- Есть ли лучший способ сделать преобразование? Есть ли в .NET способ сделать это более простым способом?