簡體   English   中英

f#中自定義時鍾的更好解決方案

[英]Better solution for a Custom Clock in f#

我需要一個解決方案,將時間添加到忽略給定時間間隔的日期。 例如,如果給定日期是2015年1月1日19:00,則關閉間隔是20:00 - 8:00,因此將在2015年1月10日10:00添加3小時。 另一個例子是Date:01 jan 2015 03:00 AM,Interval 20:00 - 08:00將給出結果01 jan 2015 11:00 AM

我的解決方案是:

    let nextInterval (d:DateTime) (s:TimeSpan) (f:TimeSpan) =
       let next (d:DateTime) (ts:TimeSpan) 
                = if d.TimeOfDay < ts 
                      then d.Date.Add(ts)
                      else d.Date.AddDays(1.0).Add(ts)
       let ns = next d s
       let nf = next d f
       (ns,nf)

    let addTime (d:DateTime) (n:TimeSpan) (s:TimeSpan) (f:TimeSpan) = 
      let rec loop (d:DateTime) (n:TimeSpan) = 
        let dt = d.TimeOfDay
        let (ns,nf) = nextInterval d s f //next start interval and next finish interval
        let outOfInterval = ((dt < s || dt >= f) && f >= s) ||
                            ((dt < s && dt >=f) && f < s)
        if n = TimeSpan.Zero
            then if outOfInterval then d
                                  else nf
            else 
             if outOfInterval 
                then if (d+n < ns) 
                        // before next start
                        then loop (d+n) TimeSpan.Zero
                        // intersecting with interval
                        else if (d+n < nf)
                                    then loop (d+n) (n - (ns - d)) 
                                    else loop nf    (n - (ns - d))
                else //in interval
                    loop nf n
       loop d n

我的問題是:有沒有人為此提供更短的解決方案?

我會使用某種形式的模運算,而不是循環。 換句話說,考慮日期的更簡單方法是:

  • 我在哪個時期? (即,哪一天的當前時間沒有被忽略的時間開始?)
  • 本期內部已經過了多少時間?

如果要添加時間,請將其添加到當前時間段內的時間,然后使用除法和余數拆分整個句點。

let day = TimeSpan(1, 0, 0, 0).Ticks

let addTime (dayBegin : TimeSpan) (daySpan : TimeSpan) (d : DateTime) (dt : TimeSpan) =
    if dt.Ticks < 0L then invalidArg "dt" "Negative time-spans are not supported."
    let t0 = (d - dayBegin).Ticks
    let rawSlot, rawSpan = t0 / day * day, t0 % day
    let slot, span = if rawSpan > daySpan.Ticks then rawSlot + day, dt.Ticks
                     else rawSlot, rawSpan + dt.Ticks
    DateTime(slot + span / daySpan.Ticks * day + span % daySpan.Ticks) + dayBegin

測試 20:00 - 8:00作為忽略的間隔,日期從8:00開始,需要12h:

let test = addTime (TimeSpan(8, 0, 0)) (TimeSpan(12, 0, 0))

使用第一個示例作為輸入:

test (DateTime(2015, 01, 01, 19, 0, 0)) (TimeSpan(3, 0, 0))
// result: 2015-01-02 10:00:00

暫無
暫無

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

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