【问题标题】:Set the date/time separately of DateTime in F#在 F# 中分别设置 DateTime 的日期/时间
【发布时间】:2020-02-03 10:21:57
【问题描述】:

我只想更改 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 上。 我想设置字段值(而不是添加到它们)。 有一些答案可以复制字段并调用构造函数,但我希望有一个更优雅的解决方案。

【问题讨论】:

标签: .net datetime time .net-core f#


【解决方案1】:

标准的 System.DateTime 类型是一个结构(而不​​是 F# 记录),这使得它有点不适合在 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 是一个结构并以这种方式使用它的事实。

【讨论】:

  • 但是DateTime 是一个不可变结构?
  • @TheQuickBrownFox 我确定了答案 - 我想说的主要是它是 .NET 类型而不是 F# 记录:-)
【解决方案2】:

这是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

你可以用类似的方式设置日期部分:

let x = DateTime.Now
let y = DateTime(2015, 03, 15) + x.TimeOfDay

【讨论】:

  • 我误读了原始答案中Date 属性的使用,答案没有包含如何设置日期但保持时间,我收集到的将是TimeOfDay财产。谢谢你的澄清。
  • 啊,对不起,我错过了你也想独立设置日期。我已经用类似的方法更新了答案。
【解决方案3】:

这可以通过以下方式解决:

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) }

【讨论】:

    猜你喜欢
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 2019-08-08
    • 1970-01-01
    相关资源
    最近更新 更多