簡體   English   中英

在 F# 中分別設置 DateTime 的日期/時間

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

我只想更改 F# 中 System.DateTime object 的日期和/或時間部分,同時保留現有字段。 當我說“改變”時,我的意思是保持不變性,所以我想在操作后收到一個新的 DateTime object。

我已經說明了我會如何改變時間,但這似乎是不正確的。

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 核心和框架。

編輯

正如評論中提到的,關於如何更改 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# 中的不可變編程 - 您可以使用您建議的幫助程序來解決這個問題。

另一種方法是定義一個 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 中更改時間的最佳答案? 翻譯為 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM