C# 将时间拆分为小时块

Posted

技术标签:

【中文标题】C# 将时间拆分为小时块【英文标题】:C# Split Times into Hour Blocks 【发布时间】:2011-09-07 23:28:57 【问题描述】:

我需要一些帮助才能将 2 个日期时间拆分为它们之间的小时间隔。

这是使用“支付”数据,因此需要非常准确。我需要打卡和打卡,并将它们分成小时间隔。

示例:

时钟 = 2011 年 5 月 25 日下午 1:40:56

下班时间 = 2011 年 5 月 25 日下午 6:22:12

我需要它看起来像:

2011 年 5 月 25 日下午 1:40:56

2011 年 5 月 25 日下午 2:00:00

2011 年 5 月 25 日下午 3:00:00

2011 年 5 月 25 日下午 4:00:00

2011 年 5 月 25 日下午 5:00:00

2011 年 5 月 25 日下午 6:00:00

2011 年 5 月 25 日下午 6:22:12

然后我计划对照“差异”表检查这些时间,看看他们应该有一个新的支付代码。但我稍后会担心支付码。

对划分时间有什么帮助吗?更喜欢 C#,但我也可以访问 MSSQL2000(这是我们拉原始时代的地方)

【问题讨论】:

我不清楚 hours 变量代表什么。它看起来像一个数组,表示长达一小时的时间跨度的开始或结束。那是你要找的吗?一般来说,使用 DateTime.AddHour 的循环似乎是一个不错的起点。 @Tobias 我清理了问题并在您回复时删除了 hours 变量:)。至于添加时间,我想我可以做到,唯一的问题是我最终必须将这些时间加在一起。所以我几乎需要将它们转换为分钟而不是我上面的建议 【参考方案1】:

这样的事情怎么样?

static IEnumerable<DateTime> GetWorkingHourIntervals(DateTime clockIn, DateTime clockOut)

    yield return clockIn;

    DateTime d = new DateTime(clockIn.Year, clockIn.Month, clockIn.Day, clockIn.Hour, 0, 0, clockIn.Kind).AddHours(1);

    while (d < clockOut)
    
        yield return d;
        d = d.AddHours(1);
    

    yield return clockOut;

这使用了iterator blocks,但它很容易被重写为返回一个列表。

使用示例:

static void Main(string[] args)

    var clockIn = new DateTime(2011, 5, 25, 13, 40, 56);
    var clockOut = new DateTime(2011, 5, 25, 18, 22, 12);

    var hours = GetWorkingHourIntervals(clockIn, clockOut);

    foreach (var h in hours)
        Console.WriteLine(h);

    Console.ReadLine();

输出:

2011-05-25 13:40:56 2011-05-25 14:00:00 2011-05-25 15:00:00 2011-05-25 16:00:00 2011-05-25 17:00:00 2011-05-25 18:00:00 2011-05-25 18:22:12

更新:LukeH 足够聪明,建议您也应该复制 DateTimeKind。如果您打算稍后将日期时间转换为本地时间,这确实是一个明智的举措。

【讨论】:

这个答案非常好,我希望我能给出 2 个答案。这是非常灵活的。但是,对于我在这个问题上的具体需求,我选择了另一个答案,主要是因为我的团队。但是这个答案很棒!【参考方案2】:
var hours = new List<DateTime>();
hours.Add(clockin);

var next = new DateTime(clockin.Year, clockin.Month, clockin.Day,
                        clockin.Hour, 0, 0, clockin.Kind);

while ((next = next.AddHours(1)) < clockout)

    hours.Add(next);

hours.Add(clockout);

【讨论】:

复制 DateTimeKind 确实是明智之举!我也会将其包含在我的答案中。 我最终选择了这条路线。尽管 Markus Olssons 的回答更灵活,但它是如此简单,我无法抗拒使用它。应该让我的队友也能理解,而且他们是新手。【参考方案3】:

我认为这样的事情应该可行:

public IEnumerable<DateTime> GetHourlyBreakdown(DateTime startDate, DateTime endDate)

    var hours = new List<DateTime>();
    hours.Add(startDate);
    var currentDate = new DateTime(startDate.Year, startDate.Month, startDate.Day, startDate.Hour, 0, 0).AddHours(1);
    while(currentDate < endDate)
    
        hours.Add(new DateTime(currentDate.Year, currentDate.Month, currentDate.Day, currentDate.Hour, 0, 0));
        currentDate = currentDate.AddHours(1);
    
    hours.Add(endDate);
    return hours;

【讨论】:

【参考方案4】:

我会这样做:

public static IEnumerable<DateTime> GetIntervals(DateTime clockIn, DateTime clockOut)

    yield return clockIn;

    clockIn = clockIn.AddHours(1).Subtract(clockIn.TimeOfDay).AddHours(clockIn.Hour);

    for (DateTime dt = clockIn; dt < clockOut; dt = dt.AddHours(1))
        yield return dt;

    yield return clockOut;

像这样使用它:

    foreach (DateTime dt in GetIntervals(DateTime.Parse("5/25/2011 1:40:56PM", CultureInfo.InvariantCulture), DateTime.Parse("5/25/2011 6:22:12PM", CultureInfo.InvariantCulture)))
    
        Console.WriteLine(dt);
    

【讨论】:

以上是关于C# 将时间拆分为小时块的主要内容,如果未能解决你的问题,请参考以下文章

拆分为逗号,而不是一个一个地对数值求和 c#

Oracle,将持续时间行拆分为一小时

将 zip 存档拆分为多个块

将数组拆分为具有最小块大小的给定大小的块

如何将代码块拆分为列表?

以秒为单位将数字拆分为天、小时、分钟和秒?