You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中时区依赖信息处理:业务时段任务调度优化咨询

优化营业时间判断的延迟计算方案

我有一个业务场景:需要判断任务应延迟至后续日期排队还是立即提交处理。判断逻辑基于客户本地时区的业务营业时间(例如早8:00营业、晚5:00打烊),客户时区需单独存储。任务记录的创建时间是服务器UTC时间,我先将其转换为客户时区时间,再通过遍历一周内的小时数计算延迟时长——延迟为0则立即执行,大于0则将服务器UTC时间偏移对应时长。当前实现代码如下,求更优方案:

Private Function CalcDelay() As Integer
    Dim d = _localTime '// 当前客户本地时间
    Dim n = d.DayOfWeek()
    Dim now = d.Hour() & "." & d.Minute()
    Dim delayHours As Integer = 0
    Dim _day
    For i = 0 To 168
        d = _localTime.AddHours(i)
        n = d.DayOfWeek()
        now = d.Hour() & "." & d.Minute()
        _day = _bh.Hours(n)
        If (ConvertTime(now) >= ConvertTime(_bh.Hours(n).Open1c) And ConvertTime(now) < ConvertTime(_bh.Hours(n).Close1c)) _
            Or (ConvertTime(now) >= ConvertTime(_bh.Hours(n).Open2c) And ConvertTime(now) < ConvertTime(_bh.Hours(n).Close2c)) Then
            delayHours = i
            Exit For
        End If
    Next
    Return delayHours
End Function

注:ConvertTime用于将客户的营业时间(格式为HH.MM,如08.00、15.00等)转换为可比较的数值


优化思路与方案

1. 干掉冗余的字符串拼接与重复转换

原代码把小时和分钟拼接成字符串再转数值,完全是多此一举。直接把客户的营业时间(HH.MM)转成TimeSpan,和当前时间的TimeOfDay做比较,既高效又不容易出错。

2. 减少循环次数,直接计算最近营业时段

逐小时遍历整整一周(168次)太浪费性能。我们可以先判断当前时间是否在营业时段内:

  • 如果是,直接返回0;
  • 如果不是,先算当天剩余的营业时段(如果当天还有没结束的时段),再不行就算到次日营业开始的时间,依次往后找,直到找到最近的营业时段。

优化后的代码示例

Private Function CalcDelay() As Integer
    Dim currentLocalTime = _localTime
    Dim currentDayOfWeek = currentLocalTime.DayOfWeek
    Dim currentTimeOfDay = currentLocalTime.TimeOfDay

    ' 先检查当前时间是否在营业时段内,是的话直接返回0
    Dim todayHours = _bh.Hours(currentDayOfWeek)
    If IsInBusinessHours(currentTimeOfDay, todayHours) Then
        Return 0
    End If

    Dim delayHours As Integer = 0
    Dim checkTime = currentLocalTime

    ' 从下一小时开始找,最多遍历一周防止死循环
    For i = 1 To 168
        checkTime = checkTime.AddHours(1)
        Dim checkDayOfWeek = checkTime.DayOfWeek
        Dim checkTimeOfDay = checkTime.TimeOfDay
        Dim dayHours = _bh.Hours(checkDayOfWeek)

        If IsInBusinessHours(checkTimeOfDay, dayHours) Then
            delayHours = i
            Exit For
        End If
    Next

    Return delayHours
End Function

' 辅助函数:判断当前时间是否属于该日的营业时段
Private Function IsInBusinessHours(currentTime As TimeSpan, dayHours As BusinessHours) As Boolean
    ' 把HH.MM格式的营业时间转成TimeSpan
    Dim open1 = ParseTimeString(dayHours.Open1c)
    Dim close1 = ParseTimeString(dayHours.Close1c)
    Dim open2 = ParseTimeString(dayHours.Open2c)
    Dim close2 = ParseTimeString(dayHours.Close2c)

    ' 检查是否在第一个或第二个营业时段内
    Return (currentTime >= open1 AndAlso currentTime < close1) OrElse 
           (currentTime >= open2 AndAlso currentTime < close2)
End Function

' 辅助函数:解析HH.MM格式的字符串为TimeSpan
Private Function ParseTimeString(timeStr As String) As TimeSpan
    Dim parts = timeStr.Split("."c)
    Dim hours = Integer.Parse(parts(0))
    Dim minutes = Integer.Parse(parts(1))
    Return New TimeSpan(hours, minutes, 0)
End Function

额外优化点

  • 可以缓存ParseTimeString的解析结果,毕竟同一周的同一天营业时间是固定的,不用每次循环都重复解析;
  • 如果业务允许,还可以提前计算出一周内所有营业时段的时间范围,直接查找当前时间之后的第一个时段,进一步减少循环次数。

内容的提问来源于stack exchange,提问作者DDulla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 11:57:37