我只想更改F#中System.DateTime对象的日期和/或时间部分,同时保留现有字段。当我说“更改”时,我的意思是保持不变性,所以我想在操作之后接收一个新的DateTime对象。
我已经说明了如何改变时间,但这似乎是不正确的。
open System
type State = {
When: DateTime
}
// How would I actually do the following?
// let setTime h m state = { state with When = { state.When with Hour = h; Minute = m } }
理想情况下,该解决方案将同时在.NET Core和Framework上运行。
如评论中所述,有一个separate question on how to change a DateTime,但此问题似乎集中在C#(而不是F#)上,并且也集中在添加TimeSpan上。我想设置字段值(而不是添加到它们)。有一些答案可以复制字段并调用构造函数,但我希望有一个更优雅的解决方案。
可以用以下方法解决:
let setTime h m (t : DateTime) = DateTime(t.Year, t.Month, t.Day, h, m, 0)
let setDate y m d (t : DateTime) = DateTime(y, m, d, t.Hour, t.Minute, t.Second)
let setTimeInState h m state = { state with When = (setTime h m state.When) }
标准的System.DateTime
类型是一个类,这使其在某种程度上不适用于F#中的不变记录式编程-您可以使用所建议的帮助程序来解决该问题。
另一种方法是定义一个F#记录,并与System.DateTime
之间进行映射:
type ImmutableDateTime =
{ Day : int
Month : int
Year : int
Hour : int
Minute : int
Second : int }
member x.DateTime =
System.DateTime(x.Year, x.Month, x.Day, x.Hour, x.Minute, x.Second)
static member FromDateTime(dt:System.DateTime) =
{ Day = dt.Day; Month = dt.Month; Year = dt.Year
Hour = dt.Hour; Minute = dt.Minute; Second = dt.Second }
现在您可以将System.DateTime
转换为ImmutableDateTime
,对记录进行漂亮的功能编程,然后将其转换回:
let dt1 = ImmutableDateTime.FromDateTime(System.DateTime.Now)
let dt2 = { dt1 with Year = 2018 }
dt2.DateTime.ToShortDateString()
也就是说,实际上,我可能只接受System.DateTime
是一个类并以这种方式使用它的事实。
这是How to change time in DateTime?的答案,已翻译为F#:
open System
let x = DateTime.Now
let y = x.Date + TimeSpan(10, 30, 0)
哪里
printfn "%A" x
printfn "%A" y
打印
10/5/2019 1:49:58 PM
10/5/2019 10:30:00 AM
这不是您想要的吗?