【问题标题】:Looping start to end timespans overnight在一夜之间循环开始到结束时间跨度
【发布时间】:2012-06-28 15:57:05
【问题描述】:

希望一切顺利!

我希望我已经解决了这个问题,但看起来我们今天早上遇到了一些错误。

这是一个 asp.net web 应用程序,这部分是用 c# 编写的。我们正在动态填充下拉列表,其中 openTime、closeTime 和 15 分钟的间隔都是 TimeSpan 类型。

TimeSpan interval = new TimeSpan(0,15,0);

    for (TimeSpan i = openTime; i <= closeTime; i = i.Add(interval))
    {

        string stringTime = i.ToString();
        ddlTime.Items.Add(new ListItem(stringTime, stringTime));
    }

如果时间不超过午夜,这将非常有用。例如:

  • 开放时间:07:00(上午 7:00)
  • 关闭时间:10:00(上午 10:00)

将按预期填充:

  • 07:00:00
  • 07:15:00
  • 07:30:00
  • 07:45:00
  • 10:00:00

这不起作用的地方是开放时间在午夜之前开始,而关闭时间在午夜之后开始。

  • 开放时间:11:00(上午 11:00)
  • 关闭时间:02:00(凌晨 2:00)

我需要填充

  • 11:15:00
  • 11:30:00
  • 11:45:00
  • .
  • .
  • .
  • 2:00:00

但正如您可以很快看出的那样,循环不会运行,因为在这种情况下 openTime 不是

只需创建另一个 for 循环来检查 closeTime

  • 02:00:00
  • 02:15:00
  • 02:30:00
  • .
  • .
  • .
  • 11:00:00

在这个主题上更有经验的人能否提供成功完成这项工作所需的逻辑。

感谢您的宝贵时间,克里斯。

【问题讨论】:

    标签: c# asp.net .net datetime timespan


    【解决方案1】:

    听起来最好为每个开始和结束创建一个DateTime,然后循环那个直到你到达结束,为每个值取TimeOfDay

    TimeSpan interval = TimeSpan.FromMinutes(15);
    
    for (DateTime current = openTime; current <= closeTime; current += interval)
    {
        string stringTime = current.TimeOfDay.ToString();
        ddlTime.Items.Add(new ListItem(stringTime, stringTime));
    }
    

    现在,如果您的营业时间是(比如说)2012 年 6 月 28 日晚上 11 点,而关闭时间是 2012 年 6 月 29 日凌晨 2 点,那么它可以正常工作。

    如果您将打开/关闭时间设为 TimeSpan,您可以随时使用:

    // The dates don't really matter here... we just want a sample start/end
    // for an opening period
    DateTime open = new DateTime(2000, 1, 1) + openTimespan;
    DateTime close = new DateTime(2000, 1, 1) + closeTimespan;
    
    if (open > close)
    {
        close = close.AddDays(1);
    }
    

    当然,我个人建议使用我自己的 .NET 日期/时间 API,Noda Time,它具有特定的 LocalTime 类型,但那是另一回事 :)

    【讨论】:

    • 嗨,乔恩,再次感谢您的帮助!如果打开时间较短,我通过在关闭时间增加一天来解决这个问题,这样,我的循环总是会触发,处理正确的时间段。
    • @ChrisBuckler:很酷 - 我已经修复了损坏的示例代码 :)
    【解决方案2】:

    如果您还关心日期,为什么要为此使用TimeSpan

    使用DateTime.Add(new TimeSpan(0,0,interval)) 代替TimeSpan.Add(interval),并修改其余代码以解决DateTime 对象而不是TimeSpan 对象。

    【讨论】:

      【解决方案3】:

      我认为你在应该使用 DateTime 的地方使用 TimeSpan。

      【讨论】:

        【解决方案4】:

        我看到了几个选项:

        1. 使用DateTime 结构代替您的15 分钟增量。将DateTime.TimeOfDay 作为您的数据。 (在我写这篇文章时,其他人已经建议过)
        2. 如果TimeSpan 值超过 24 小时,则包含减去 24 小时的逻辑。

        关于#1 的一个重要说明和其他人的建议是夏令时的不可否认的时间变化。您必须验证您的序列在我们后退时没有重复,或者在我们向前跳时跳过 1h 块。

        这有意义吗?

        问候。

        【讨论】:

        • 我使用 TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(stringid) 为指定的时区 id 加载时区信息对象。然后我使用 TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow,tzi) 加载 DateTime 对象。 tzi obj 实际上支持夏令时!感谢您提供 DateTime 结构提示!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-11
        • 1970-01-01
        • 2017-07-05
        • 1970-01-01
        相关资源
        最近更新 更多