简体   繁体   English

在 F# 中分别设置 DateTime 的日期/时间

[英]Set the date/time separately of DateTime in F#

I would like to change only the date and/or time parts of a System.DateTime object in F#, while maintaining the existing fields.我只想更改 F# 中 System.DateTime object 的日期和/或时间部分,同时保留现有字段。 When I say "change", I mean to maintain immutability, so I want to receive a new DateTime object after the operation.当我说“改变”时,我的意思是保持不变性,所以我想在操作后收到一个新的 DateTime object。

I have illustrated how I would think I would change the time, but this appears to be incorrect.我已经说明了我会如何改变时间,但这似乎是不正确的。

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

Ideally the solution will work on both .NET Core and Framework.理想情况下,该解决方案适用于 .NET 核心和框架。

Edit编辑

As mentioned in a comment, there is aseparate question on how to change a DateTime , but this question appears to be focused on C# (rather than F#) and also on adding a TimeSpan.正如评论中提到的,关于如何更改 DateTime 有一个单独的问题,但这个问题似乎集中在 C#(而不是 F#)以及添加 TimeSpan 上。 I want to set the field values (rather than add to them).我想设置字段值(而不是添加到它们)。 There are answers that give copying the fields and calling the constructor, but I was hoping for a more elegant solution.有一些答案可以复制字段并调用构造函数,但我希望有一个更优雅的解决方案。

This could possibly be solved with the following:这可以通过以下方式解决:

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

The standard System.DateTime type is a struct (rather than an F# record), which makes it somewhat unsuitable for immutable programming in F# - you can solve that using helpers like the ones you suggested.标准System.DateTime类型是一个结构(而不是 F# 记录),这使得它有点不适合 F# 中的不可变编程 - 您可以使用您建议的帮助程序来解决这个问题。

Another approach would be to define an F# record with mapping to and from System.DateTime :另一种方法是定义一个 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 }

Now you can take System.DateTime , turn it into ImmutableDateTime , do nice functional programming with the record and then convert it back:现在您可以使用System.DateTime ,将其转换为ImmutableDateTime ,对记录进行很好的函数式编程,然后将其转换回来:

let dt1 = ImmutableDateTime.FromDateTime(System.DateTime.Now)
let dt2 = { dt1 with Year = 2018 }
dt2.DateTime.ToShortDateString()

That said, in practice, I would probably just accept the fact that System.DateTime is a struct and use it in that way.也就是说,在实践中,我可能会接受System.DateTime是一个结构并以这种方式使用它的事实。

This is the top answer fromHow to change time in DateTime?这是如何在 DateTime 中更改时间的最佳答案? translated to F#:翻译为 F#:

open System

let x = DateTime.Now
let y = x.Date + TimeSpan(10, 30, 0)

where在哪里

printfn "%A" x
printfn "%A" y

prints印刷

10/5/2019 1:49:58 PM
10/5/2019 10:30:00 AM

You can set the Date part in a similar manner:您可以以类似的方式设置日期部分:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM