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
这样简单的功能,这可能没有必要。但记住这是一个很好的经验法则。我建议编写以下 对 函数(从 gileCAD 的代码开始,因为它非常出色):
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_old
和 fn
参数的顺序,因为这允许您编写在管道中有意义的代码:
if "/path/to/file" |> isFileOlderThanNDays 7 then
printfn "File is at least a week old"
else
printfn "File is relatively fresh"
我一直在研究这个问题,但我找到的答案是针对 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
这样简单的功能,这可能没有必要。但记住这是一个很好的经验法则。我建议编写以下 对 函数(从 gileCAD 的代码开始,因为它非常出色):
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_old
和 fn
参数的顺序,因为这允许您编写在管道中有意义的代码:
if "/path/to/file" |> isFileOlderThanNDays 7 then
printfn "File is at least a week old"
else
printfn "File is relatively fresh"