我有一个基于 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
。)<
- millitm - 以毫秒为单位的秒数
- time - 自 1970 年 1 月 1 日午夜 (00:00:00) 以来的秒数,协调世界时 (UTC)。
- 时区 - UTC 时间和本地时间之间向西移动的分钟差。 timezone 的值是根据全局变量
_timezone
的值设置的(参见 _tzset
)。
我正在重新处理执行时间戳的代码部分,以便在 .NET 3.5 中使用 C#。现在使用 System.DateTime
结构生成时间戳,但我仍然需要将它们转换回 _timeb
结构,以便遗留 C++ 代码可以对它们进行操作。以下是我在托管 C++ 桥接库中的做法:
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 是否有办法以更直接的方式执行此操作?
您知道 Y2K38 问题吗?我假设您检查了 .timezone 的标志。避免巧妙地使用 dateTime.Millisecond,这只会让下一个人感到困惑。否则看起来不错。
我是一名优秀的程序员,十分优秀!