Установите дату / время отдельно от DateTime в F # - PullRequest
0 голосов
/ 05 октября 2019

Я хотел бы изменить только части даты и / или времени объекта System.DateTime в F # при сохранении существующих полей. Когда я говорю «изменить», я имею в виду сохранение неизменности, поэтому я хочу получить новый объект 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, так и на платформе.

Редактировать

Как уже упоминалось в комментарии, есть отдельныйвопрос о том, как изменить DateTime , но этот вопрос, кажется, сосредоточен на C # (а не на F #), а также на добавлении TimeSpan. Я хочу установить значения полей (а не добавлять к ним). Есть ответы, которые дают копирование полей и вызов конструктора, но я надеялся на более элегантное решение.

Ответы [ 3 ]

2 голосов
/ 05 октября 2019

Стандартный тип 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 является структурой, и использовал бы его таким образом.

2 голосов
/ 05 октября 2019

Это лучший ответ из Как изменить время в 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
1 голос
/ 05 октября 2019

Возможно, это можно решить с помощью следующего:

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