System.DateTime比较(';>;';)或(';<;';)没有给出我所期望的结果

System.DateTime比较(';>;';)或(';<;';)没有给出我所期望的结果,datetime,operators,Datetime,Operators,我想从所有文件的列表中获取文件,这些文件的filedate>今天的截止日期-因此,我有以下代码 string[] MyFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf") .Where(file => new FileInfo(file).LastWriteTime > dtCutOff).ToArray(); 我有一个文件,它的最新写入时间是“{11/3/2015 1:33:26 PM

我想从所有文件的列表中获取文件,这些文件的filedate>今天的截止日期-因此,我有以下代码

string[] MyFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf")
        .Where(file => new FileInfo(file).LastWriteTime > dtCutOff).ToArray();

我有一个文件,它的最新写入时间是“{11/3/2015 1:33:26 PM}”,由我的集合以dtCutOff==“{11/3/2015 1:33:26 PM}”拾取!所以“>”似乎不起作用。

因为文件每天被送入队列一次,所以精度不需要降到毫秒或其他什么级别。因此,一秒钟的时间跨度差异是可以接受的,这样做的技巧,使我的案件工作

string[] MyFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf")
  .Where(file => new FileInfo(file).LastWriteTime - TimeSpan.FromSeconds(1) > dtCutOff)
  .ToArray();

现在,当我的截止日期为“{11/3/2015 1:33:26 PM}”时,修改日期为“{11/3/2015 1:33:26 PM}”的文件没有进入我的收藏,而另一个修改日期为“{11/3/2015 1:33:27 PM}”的文件已按预期成功进入我的收藏!!所以,它是有效的,这就是它应该如何工作后,所有这些建议!谢谢大家。

看起来您的Where子句lambda可能不正确。试试这个

string[] MyFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf").Where(file => file.modified > dtCutOff).ToArray();
此代码适用于:

var cutffDate = new DateTime(2015,1,1); // or whatever
var allFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf");
var datedFiles = allFiles.Where(f => (new FileInfo(f)).LastWriteTime > cutffDate);
更新: 由于您的问题似乎与精度相关,您可以将比较更改为:

const long precision = 10; // vary this as needed
allFiles.Where(f =>
  (new FileInfo(f)).LastWriteTime.ToFileTime()/precision > cutffDate.ToFileTime()/precision);
或者,您可以使用
…LastAccessTime.Ticks/TimeSpan.ticksPermillSecond

除此之外,您可能需要将所有日期时间值转换为UTC(LastAccessTimeUtc和DateTime.UtcNow),以确保这不是什么奇怪的时区问题,只是为了确保您期望的所有文件确实是从
目录.GetFiles
返回的初始数组的一部分。完全有可能日期/时间比较不是差异的来源。它可能与问题评论中Ivan链接的问题更相关,也可能与许可相关,或者其他一些事情

接下来,请注意
DateTime
的冲突在于它有一个
Kind
属性,该属性是三个
DateTimeKind
枚举值之一。它要么是
本地
Utc
,要么是
未指定

DateTime.Now
的情况下,
Kind
将是
DateTimeKind.Local
File.GetLastWriteTime
还返回其具有本地种类的值。因此,如果您总是从
DateTime中导出
dtCutOff
。现在,按照您在问题中显示的方式,它几乎总是正确的比较函数

“几乎”源于这样一个事实,
DateTimeKind.Local
实际上可以在封面下表示两种不同的类型。换句话说,实际上有四种,但其中两种被一种暴露出来。这在Jon Skeet的博客文章中被描述为“DateTime的深层秘密”,并且也被提到。在实践中,您应该只在回退过渡期间(如2015-11-01上周日在美国刚刚发生的情况)的模糊时间遇到这种情况

现在,更可能的情况是,您的
dtCutOff
实际上不是从
DateTime.Now
派生的,而是从用户输入或数据库查找或其他某种机制派生的,那么它实际上可能表示本地计算机上的时区以外的其他时区中的本地时间。换句话说,如果
dtCutOff
Kind
DateTimeKind.Utc
,则该值以Utc为单位。如果它的
种类
DateTimeKind.Unspecified
,则该值可能以UTC、本地时区或其他时区表示

这里有一个要点:比较两个
DateTime
值只计算
Ticks
属性下面的值。不考虑<代码>类< /代码> < <强> > /p> 由于文件时间是世界时的绝对点(无论如何在NTFS上),因此您确实应该使用
file.GetLastWriteTimeUtc
方法,而不是在本地时间工作的方法

您可以使用两种方法:

  • 使用以下命令将
    修改后的
    属性加载为UTC:

    myResult.modified = File.GetLastWriteTimeUtc(myFile);
    
  • 适当填充
    dtOffset

    • 如果从当前时间加载,则使用
      DateTime.UtcNow
    • 如果从其他输入加载,请确保将值转换为UTC以匹配输入场景。例如,如果值以本地时区表示,则使用
      .ToUniversalTime()
      ,如果值位于另一时区,则使用
      时区信息
      类中的转换函数

  • modified
    属性更改为
    DateTimeOffset
    而不是
    DateTime
  • 使用以下方法加载:

    myResult.modified = new DateTimeOffset(File.GetLastWriteTimeUtc(myFile));
    
  • dtCutOff
    定义为
    DateTimeOffset
    ,并适当填充

    • 如果从当前时间加载,则使用
      DateTimeOffset.UtcNow
    • 如果从其他输入加载,请确保将偏移设置为与输入场景匹配。如果需要从其他时区转换,请使用
      TimeZoneInfo
      功能

DateTimeOffset
DateTime
有许多优点,例如不违反SRP。它总是代表一个绝对的时刻。在此场景中,了解
DateTimeOffset
上的比较运算符始终反映该绝对时刻是有帮助的。(换句话说,在进行比较之前,它会在内部调整为UTC。)

请显示完整的代码和示例。我们不知道您是如何定义
fn_fileInfo
dtCutOff
的,也不知道
dtCutOff
中的值或与之比较的文件日期。这没有帮助
fn_fileInfo
不是.NET的标准功能,据我所知,它也不是由LinqPad提供的。你需要