C # разделить время на часовые блоки - PullRequest
5 голосов
/ 03 июня 2011

Я нуждаюсь в некоторой помощи для того, чтобы разбить 2 дня на интервалы между ними.

Это работает с «платными» данными, поэтому они должны быть очень точными. Мне нужно взять Clockin и Clockout, и разделить их на часовые интервалы.

Пример:

clockin = 25.05.2011 1:40:56 PM

время выхода = 25.05.2011 6:22:12 PM

Мне нужно, чтобы это выглядело так:

5/25/2011 1:40:56 PM

5/25/2011 2:00:00 PM

5/25/2011 3:00:00 PM

5/25/2011 4:00:00 PM

5/25/2011 5:00:00 PM

5/25/2011 6:00:00 PM

5/25/2011 6:22:12 PM

Затем я планирую сравнить эти времена с «дифференциальной» таблицей, чтобы выяснить, должен ли у них быть новый код оплаты. Но я буду беспокоиться о коде оплаты позже.

Любая помощь, разделяющая время? Предпочитаю C #, но у меня также есть доступ к MSSQL2000 (где мы извлекаем исходное время)

Ответы [ 4 ]

11 голосов
/ 03 июня 2011

Как насчет чего-то подобного?

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;
}

При этом используется блоков итераторов , но его можно легко переписать для возврата списка.

Пример использования:

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.Это действительно разумный шаг, если позже вы планируете преобразовать дату в местное время и обратно.

4 голосов
/ 03 июня 2011
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);
3 голосов
/ 03 июня 2011

Я думаю, что-то вроде этого должно работать:

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;
}
1 голос
/ 03 июня 2011

Я бы сделал это:

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);
    }
...