c#时间表以字符串形式显示工作时间,如9:00-13:00;14:00-18:00

本文关键字:00-18 00-13 时间 字符串 时间表 工作 显示 | 更新日期: 2023-09-27 18:17:13

我有一个每周每天的对象列表,其中存储了每周每天的工作时间和非工作时间。

public class Schedule
{
    public bool IsOn { get; set; }
    public DayOfWeek DayOfWeek { get; set; }
    public short TimeFrom { get; set; } // store time as amount of minutes since start of day
    public short TimeTo { get; set; } // store time as amount of minutes since start of day
}

所以我想要得到的是一周中每一天的时间范围。例如,我们周一有两个项目

new Schedule() { IsOn = true, DayOfWeek = DayOfWeek.Moday, TimeFrom = 540, TimeTo = 1080 }
new Schedule() { IsOn = false, DayOfWeek = DayOfWeek.Moday, TimeFrom = 780, TimeTo = 840 }

我需要在UI上显示如下:周一:9:00-13:00;14:00-18:00

我主要想知道的是如何解决这样的问题的算法。如果你看例子周一:9:00-13:00;14:00-18:00您将看到我只想显示工作时间。我想它是类似TimeRange的东西,但是我不知道如何编码。

更新2

为了更清楚,我将提供一个示例。用户可以输入程序的工作时间,如时间段,如9:00-12:00用户也可以输入非工作时间的程序,如一个时间段,如10:00-11:00。对于一周中的一天,可以输入用户想要的任意多个时间段(工作或非工作)。添加并存储到数据库是没有问题的。

问题是在预览期间为用户显示时间段。

例如用户输入:

  1. 9:00-12:00工作时间
  2. 10:00-11:00非工作时间
  3. 14:00-17:00工作时间
  4. 15:00-15:30非工作时间

我需要显示所有这些

9:00-10:00;11:00-12:00;14:00-15:00;15:30-17:00;

更新3

我认为这可能与图表有关。请帮忙选择算法

c#时间表以字符串形式显示工作时间,如9:00-13:00;14:00-18:00

下面应该给出您想要的输出。使用您提供的示例数据,这就是结果。

周一:09:00-18:00;13:00-14:00

void Main()
{
    var schedules = new[]{
        new Schedule() { IsOn = true, DayOfWeek = DayOfWeek.Monday, TimeFrom = 540, TimeTo = 1080 },
        new Schedule() { IsOn = false, DayOfWeek = DayOfWeek.Monday, TimeFrom = 780, TimeTo = 840 }
    };

    var byDay = schedules.GroupBy(i => i.DayOfWeek)
                .Select(i =>
                {
                    var times = i.Select(t => string.Format(@"{0:hh':mm}-{1:hh':mm}", TimeSpan.FromMinutes(t.TimeFrom), TimeSpan.FromMinutes(t.TimeTo)));
                    return string.Format("{0}: {1}", i.Key, string.Join("; ", times));
                });
    foreach (var day in byDay)
    {
        Console.WriteLine(byDay);
    }
}
public class Schedule
{
    public bool IsOn { get; set; }
    public DayOfWeek DayOfWeek { get; set; }
    public short TimeFrom { get; set; } // store time as amount of minutes since start of day
    public short TimeTo { get; set; } // store time as amount of minutes since start of day
}

我终于找到了解决办法。

    public static IEnumerable<Tuple<short, short>> ExcludeIntervals(IEnumerable<ISchedule> range)
    {
        var list = range
            .SelectMany(x => new[] {Tuple.Create(x.TimeFrom, x.IsOn), Tuple.Create(x.TimeTo, !x.IsOn)})
            .OrderBy(d => d.Item1).ThenBy(d => d.Item2)
            .ToList();
        var first = default(short);
        var count = 1;
        foreach (var item in list)
        {
            if (item.Item2) // false - start of unavailability interval. true - end of unavailability interval.
            {
                if (--count == 0) // Become available.
                {
                    first = item.Item1;
                }
            }
            else
            {
                if (++count == 1)
                {
                    var last = item.Item1;
                    if (last >= first) // if next unavailability starts right after previous ended, then no gap.
                    {
                        yield return Tuple.Create(first, last);
                    }
                }
            }
        }
    }
    public interface ISchedule
    {
        bool IsOn { get; set; }
        short TimeFrom { get; set; }
        short TimeTo { get; set; }
    }