繁体   English   中英

使用DateTime类处理夏令时

[英]Working with daylight saving time with the DateTime class

我正在将C ++程序移植到C#。 程序需要能够读取文件的“修改”时间戳并将其存储在List 这是我到目前为止:

C#代码:

ret = new List<Byte>(); //list to store the timestamp

var file = new FileInfo(filename);

//Get revision date/time
DateTime revTime_lastWriteTime_LT = file.LastWriteTime;

//Copy date/time into the List (binary buffer)
ret.Add(Convert.ToByte(revTime_lastWriteTime_LT.Month));
ret.Add(Convert.ToByte(revTime_lastWriteTime_LT.Day));
ret.Add(Convert.ToByte(revTime_lastWriteTime_LT.Year % 100)); // 2-digit year
ret.Add(Convert.ToByte(revTime_lastWriteTime_LT.Hour));
ret.Add(Convert.ToByte(revTime_lastWriteTime_LT.Minute));
ret.Add(Convert.ToByte(revTime_lastWriteTime_LT.Second));

当我读入Hours值时会出现问题。 如果在夏令时期间(如夏季月份)修改了文件,则C ++程序中的小时值将减1。 我似乎无法在我的程序中复制这个。 DateTimeMSDN文章中 ,它在“DateTime values”下面说:“本地时间可选择受夏令时影响,从一天的长度增加或减去一小时”。 在我的C#代码中,我确保使用ToLocalTime()将我的DateTime对象更改为本地时间,但显然我还没有设置文章所讨论的选项。 在读取夏令时期间修改的文件时,如何确保本地时间的DateTime对象减去一个值?

C ++代码以防万一:

static WIN32_FILE_ATTRIBUTE_DATA get_file_data(const std::string & filename)
{
  WIN32_FILE_ATTRIBUTE_DATA ret;
  if (!GetFileAttributesEx(filename.c_str(), GetFileExInfoStandard, &ret))
    RaiseLastWin32Error();
  return ret;
}
//---------------------------------------------------------------------------
static SYSTEMTIME get_file_time(const std::string & filename)
{
  const WIN32_FILE_ATTRIBUTE_DATA data(get_file_data(filename));
  FILETIME local;
  if (!FileTimeToLocalFileTime(&data.ftLastWriteTime, &local))
    RaiseLastWin32Error();
  SYSTEMTIME ret;
  if (!FileTimeToSystemTime(&local, &ret))
    RaiseLastWin32Error();
  return ret;
}

void parse_asm()
{
    // Get revision date/time and size
    const SYSTEMTIME rev = get_file_time(filename);
    // Copy date/time into the binary buffer
    ret.push_back(rev.wMonth);
    ret.push_back(rev.wDay);
    ret.push_back(rev.wYear % 100); // 2-digit year
    ret.push_back(rev.wHour);
    ret.push_back(rev.wMinute);
    ret.push_back(rev.wSecond);
}

更新清晰度:

在Windows时间设置中,我在(UTC-05:00)东部时间(美国和加拿大)。 该文件最后修改于2013年9月3日星期二下午12:13:52。 C ++应用程序将小时值显示为11,C#应用程序使用上面的代码将小时值显示为12。 我需要C#应用程序显示与C ++应用程序相同的小时值。

这个bug实际上不是.NET,而是你的C ++代码。 你正在使用FileTimeToLocalFileTime ,它有一个众所周知的bug,如KB932955中所述

注意 FileTimeToLocalFileTime()函数和LocalFileTimeToFileTime()函数仅使用当前时区信息和DST信息执行UTC时间和本地时间之间的转换。 无论转换的时间戳如何,都会发生此转换。

因此,在2013年9月3日美国东部时区12:13:52给出的示例中,确实应该是夏令时。 但是因为它现在 (2015年2月)不是夏令时,所以你目前在C ++程序中获得11小时。 如果您在下个月的转换(2015年3月8日)之后运行完全相同的C ++代码,那么您将获得每小时12个。

FileTimeToLocalFileTime函数的MSDN条目的备注部分中描述了C ++代码的修复:

要在将文件时间转换为本地时间时考虑夏令时,请使用以下函数序列代替使用FileTimeToLocalFileTime

  1. FileTimeToSystemTime
  2. SystemTimeToTzSpecificLocalTime
  3. SystemTimeToFileTime

既然你已经理解了这个错误 - 如果你真的想在C#中保留这种行为(我推荐),那么你会做以下事情:

TimeSpan currentOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);
DateTime revTime_LastWriteTime_Lt = file.LastWriteTimeUtc.Add(currentOffset);

更好的做法就是保持当前代码file.LastWriteTime (使用file.LastWriteTime ),并修复错误。

抱歉,您需要使用Add not AddHoursAdd接受TimeSpan 所以你正在寻找:

 file.LastWriteTimeUtc.Add(TimeZoneInfo.Local.BaseUtcOffset);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM