Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Datetime f中定制时钟的更好解决方案#_Datetime_Time_F#_Clock_Intervals - Fatal编程技术网

Datetime f中定制时钟的更好解决方案#

Datetime f中定制时钟的更好解决方案#,datetime,time,f#,clock,intervals,Datetime,Time,F#,Clock,Intervals,我需要一个解决方案来为日期添加时间,忽略给定的时间间隔。 例如,如果给定日期为2015年1月1日19:00,则关闭间隔为20:00-8:00,再加上3个小时,结果为2015年1月2日10:00。另一个例子是 日期:2015年1月1日凌晨03:00,间隔20:00-08:00将给出结果2015年1月1日上午11:00 我的解决办法是: let nextInterval (d:DateTime) (s:TimeSpan) (f:TimeSpan) = let next (d:D

我需要一个解决方案来为日期添加时间,忽略给定的时间间隔。 例如,如果给定日期为2015年1月1日19:00,则关闭间隔为20:00-8:00,再加上3个小时,结果为2015年1月2日10:00。另一个例子是 日期:2015年1月1日凌晨03:00,间隔20:00-08:00将给出结果2015年1月1日上午11:00

我的解决办法是:

    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 nextInterval(d:DateTime)(s:TimeSpan)(f:TimeSpan)=
let next(d:DateTime)(ts:TimeSpan)
=如果d.TimeOfDay=f)和&f>=s)||
((dt=f)和&f

我的问题是:有谁能找到一个更简短的解决方案吗?

我会使用某种形式的模运算,而不是循环。换言之,考虑日期的更简单方法是:

  • 我现在处于哪个时期?(即,当前未忽略时间段从哪一天开始?)
  • 当前期间内已过了多少时间
如果要添加时间,请将其添加到当前时段内的时间,然后使用除法和余数拆分整个时段

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
使用第一个示例作为输入:

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

间隔时间内的时间对我来说很重要,应该跳过间隔时间,以给定的延迟超出间隔时间。我用它来通知你。例如,当一个事件在间隔内到达时,我必须以给定的延迟通知间隔外的用户。我在示例中所写的实际上就是我需要的工作流。例如,如果我的关闭间隔为23小时,延迟时间为4小时,则通知应在4小时后发送days@BogdanManole我废除了旧版本。它确实解决了这个问题,只对非工作时间输入进行了少量修改,但时间太长了。你觉得这个怎么样?请再次注意,
daybeagin
daySpan
是开启周期的开始和持续时间,而不是被忽略的周期。谢谢您的提问!我花了三次时间对我的答案进行了重大修改——最初太长了——才注意到这是一个多么棒的练习。太棒了!非常感谢您的解决方案。是的,我知道,对我来说,开始看起来很简单,过了一会儿,我意识到这是多么棘手。再次感谢您抽出时间;)
test (DateTime(2015, 01, 01, 19, 0, 0)) (TimeSpan(3, 0, 0))
// result: 2015-01-02 10:00:00