【问题标题】:Elegant way to set the DateTime to the latest business hour将 DateTime 设置为最新营业时间的优雅方式
【发布时间】:2014-04-26 17:08:58
【问题描述】:

我想在记录上设置一个“截至”值,以反映可用的最新营业时间。

例如,假设我们将工作时间定义为 M-F,上午 9 点到下午 5 点。如果我在星期四下午 4:00 调用它,“截至”应该是星期四下午 4:00;但是,如果我在周一早上 1:30 调用它,“截至”应该是上周五的下午 5:00。

我可以用一堆逻辑来解决这个问题,但这似乎是某个类的“功能”,其中工作几乎已经完成,或者有一种简单的方法可以做到这一点。

有吗?还是我一直在写一些讨厌的算法?

【问题讨论】:

  • 我猜你被卡住了,需要编写自己的逻辑...... :)
  • 你在说什么?你需要一个用 c# 编写的方法吗?如果是这样,您尝试过什么?
  • 我希望我不需要为此使用 C# 编写的方法;我希望有一个已经存在的类或机制。
  • 不,没有任何东西是开箱即用的。
  • .net 框架中没有这样的类,因为它非常具体。您必须使用日期时间和时间跨度创建自己的课程。

标签: c# date date-math


【解决方案1】:

C# 不包含任何开箱即用的功能,但您可以尝试以下方法:

public DateTime? GetLatestOpen(DateTime current) 
{
    var openHours = ...collection of pairs of  int (Day) and two date times (TimeRange[])...
    if (!openHours.Any()) { return null; } //prevent inf. loop if no open hours ever

    var currentDay = current.DayOfWeek;
    var hoursToday = openHours.FirstOrDefault(oh => oh.DayOfWeek == currentDay);

    if (hoursToday != null)
    {
        var currentTime = current.TimeOfDay();
        if (currentTime >= hoursToday.TimeRange[0] && 
            currentTime <= hoursToday.TimeRange[1]) 
        {
            return currentTime;
        } 
        else 
        {
            return hoursToday.TimeRange[1];
        } 
    }

    return GetLatestOpen(current.AddDays(-1));
}


...

var latestOpen = GetLatestOpen(DateTime.Now);

...

您的 openHours 集合如下所示(为简化示例,我使用了匿名类型):

var openHours = new [] { new { Day = 1, TimeRange = new DateTime[] { ...Open..., ...Close...} }, new { Day = 2...... } };


注意事项:

关于以上几点需要注意:

  1. Day = 0 是星期日,Day = 1 是星期一 .... Day = 6 是星期六
  2. 如果需要,您可以为 TimeRange 使用其他类型的集合
  3. 对于...Open......Close... DateTime 对象,您不必担心实际的日期;你只携带时间部分


如果您对此有任何疑问,请告诉我。我希望这有帮助!祝你好运,编码愉快! :)

【讨论】:

  • 我最终做了与此非常相似的事情。
【解决方案2】:

您可以使用Time Period Library for .NETCalendarPeriodCollector

// ----------------------------------------------------------------------
public DateTime GetLatestBusinessHour( DateTime moment )
{
  // filter the business hours: - Monday to Friday, 9AM to 5PM
  CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
  filter.AddWorkingWeekDays();
  filter.CollectingHours.Add( new HourRange( 9, 17 ) );

  // collect business hours of the past week
  CalendarPeriodCollector collector = new CalendarPeriodCollector( filter,
    new TimeRange( moment.AddDays( -7 ), moment ), SeekDirection.Forward,
    new TimeCalendar( new TimeCalendarConfig { EndOffset = TimeSpan.Zero } ) );
  collector.CollectHours();

  // end of the last period
  return collector.Periods.End;
} // GetLatestBusinessHour

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 2011-11-08
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多