将 c++ tm struct 和 mktime 转换为 C#

Converting c++ tm struct and mktime to C#

提问人:pfinferno 提问时间:5/2/2023 更新时间:5/2/2023 访问量:109

问:

我正在将一些 c++ 转换为 c# 代码。从 struct 转换为 c# 时,我无法重现等效值。tmmktime()

例: 两个版本使用相同的值:

int year = 2022;
int month = 9;
int day = 5;
int hour = 0;
int minute = 27;
int second = 20;

在 C++ 中:

struct tm sampleTime;
unsigned long longTime;
sampleTime.tm_year = year;
sampleTime.tm_mon  = month - 1;
sampleTime.tm_mday = day;
sampleTime.tm_hour = hour;
sampleTime.tm_min  = minute;
sampleTime.tm_sec  = second;
sampleTime.tm_wday = 0;
sampleTime.tm_yday = 0;
sampleTime.tm_isdst= 0;

longTime = mktime(&thistime); 

的值为 。longTime1662366439

在 C# 中:

DateTime sampleTime = new DateTime(year, month, day, hour, minute, second);
DateTime unixEpoch = new DateTime(1970, 1, 1);
ulong longTime = (ulong)(sampleTime - unixEpoch).TotalSeconds;

的值为 。longTime1662337639

所以它们非常接近但关闭,我需要它们是等价的。我在这里错过了什么?

C# C++ 时间 日期 转换 MKTimtime

评论

1赞 PaulMcKenzie 5/2/2023
忘记 C++ 的存在,并根据 C# 的最佳实践实现日期和时间。不要尝试通过逐行翻译来将 C++ 对 C# 执行的操作“翻译”为“C++”。我确信 C# 有办法做到这一点,无论 C++ 如何做到这一点。
1赞 pfinferno 5/2/2023
@PaulMcKenzie我听说过,但这些值需要匹配,因为它们用于很久以前的计算和存储值(直到它们可以更新)。
0赞 PaulMcKenzie 5/2/2023
C# 使用 .NET 来完成它尝试完成的任务,而 C++ 则不这样做。你试图让两个完全不同的东西具有完全相同的价值,而它们都不受你的控制。另外,假设你得到了一些匹配的值 -- 当你收到错误报告时,你会怎么做,成千上万的奇数值不匹配?这可能是一个失败的游戏,试图修复这个“错误”,只是在其他地方引入了一个错误。
3赞 Avi Berger 5/2/2023
相差 8 小时。这在我看来,原因在于是否考虑了时区。

答:

2赞 Remy Lebeau 5/2/2023 #1

mktime()采用以本地时间表示的,而 Unix 纪元则以 UTC 时间表示。tm

您调用的 C# 构造函数不知道指定的日期/时间值是本地时间还是 UTC 时间,因此结果 s 的属性为 ,这可能会导致计算错误。因此,您需要使用其他构造函数来明确每个构造函数,以便在计算过程中根据需要进行调整,例如:DateTime()KindDateTimeUnspecifiedDateTimeKind

DateTime sampleTime = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Local);
DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

话虽如此,请注意,C++ 代码设置为指示指定的日期/时间不是 DST 时间,即使实际日期/时间实际上是 DST 时间。sampleTime.tm_isdst = 0

我不确定如何在 C# 方面处理它。您可能需要查找指定的内容是否实际上在 DST 中(即,通过 TimeZoneInfo.Local.IsDaylightSavingTime()),如果是,则相应地调整它以将其移出 DST,然后再对其进行进一步计算,例如:sampleTime

DateTime sampleTime = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Local);
DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

TimeZoneInfo tz = TimeZoneInfo.Local;
if (tz.SupportsDaylightSavingTime && if tz.IsDaylightSavingTime(sampleTime))
{
    // figure out the difference between Standard/Daylight times
    // for this timezone at the specified date/time and adjust 
    // sampleTime accordingly ...
}

评论

0赞 pfinferno 5/2/2023
我认为你对夏令时的看法是对的,没有抓住这一点。不知道我该如何调整它,但我会搞砸它。谢谢!