F# 如何比较两个日期时间值

F# How to Compare Two DateTime Values

我一直在研究这个问题,但我找到的答案是针对 C# 的,而不是针对 F# 的。看起来我需要使用 DateTime.Compare,但我希望有一个本地解决方案。

函数(下)的目的是判断一个文件的访问时间是否>=到一个阈值。阈值是上次访问时间减去天数。

days_old 连同文件名 fn 被传递给函数 isFileStale

我很困惑为什么这个函数总是returns false.

let isFileStale fn days_old  =
    let rc =
        let currentTime = ((System.DateTime.Now).ToLocalTime())
        let lastFileUsed = File.GetLastAccessTime(fn)
        let timeSpan = new TimeSpan(days_old, 0, 0, 0, 0)
        let fileDeleteThreshhold = lastFileUsed.Subtract(timeSpan)

        if fileDeleteThreshhold >= lastFileUsed then
            true
        else
            false
    rc

我不确定你想做什么,但你总是得到错误,因为 lastFileUsed.Subtract(timeSpan)(这是你的 fileDeleteThreshhold 值)总是低于 lastFileUsed(或等于 days_old = 0)

也许这就是您要找的:

let isFileStale fn days_old  =
    let currentTime = DateTime.Now
    let lastFileUsed = File.GetLastAccessTime(fn)
    (currentTime - lastFileUsed).Days >= days_old

顺便说一句,根据一般经验,任何时候在函数内部使用 DateTime.Now 时,我都建议通过移动 pure 将它变成 纯函数 currentTime 变成一个参数。这使您的单元测试更加简单,因为您不必模拟 DateTime.Now,您只需要传入您希望成为该单元测试的 "current" 时间。例如,要使用当前函数测试 isFileStale,您的单元测试必须检查当前时间,创建一个时间戳为(当前时间 - N 天)的文件,然后对该文件调用 isFileStale .但是使用 isFileStale 的版本将 currentTime 作为参数,您的测试将是:

  • 创建时间戳为 2010-01-01 的文件
  • 2010-01-07 是 7 天吗?答案应该是 "no".
  • 2010-01-08 是 7 天吗?答案应该是 "yes".

这还允许您轻松地测试像 2 月 29 日这样的事情,而不需要每四年在正确的时间精确地运行您的单元测试。

现在,对于isFileStale这样简单的功能,这可能没有必要。但记住这是一个很好的经验法则。我建议编写以下 函数(从 gi​​leCAD 的代码开始,因为它非常出色):

let isFileStale currentTime days_old fn  =
    let lastFileUsed = File.GetLastAccessTime(fn)
    (currentTime - lastFileUsed).Days >= days_old

let isFileOlderThanNDays days_old fn =
    isFileStale DateTime.Now days_old fn

请注意,我调换了 days_oldfn 参数的顺序,因为这允许您编写在管道中有意义的代码:

if "/path/to/file" |> isFileOlderThanNDays 7 then
    printfn "File is at least a week old"
else
    printfn "File is relatively fresh"