Вычисление даты и времени для будущего события

Я создаю функцию, которая будет устанавливать дату события на основе текущего времени.

У меня есть перечисление событий:

public enum EventTimings
{
     Every12Hours,  // 12pm and midnight
     Weekly // sunday at midnight
}


public static DateTime CalculateEventTime(EventTimings eventTime)
{
  DateTime time;

  switch(eventTime)
  {
     case EventTimings.Every12Hours:
        break;

  }

  return time;
}

Итак (тип события Every12Hour), если текущее время 10:00, то дата события будет в тот же день, но в 12:00.

Как мне это написать?

Я также должен убедиться, что это работает для 31 декабря и любой другой странной даты/времени.

Является ли datetime лучшим для этого сценария?


person codecompleting    schedule 29.09.2011    source источник


Ответы (4)


Если вы хотите что-то протестировать, я бы сделал DateTime, который вы пытаетесь «округлить», явным, что-то вроде

public static DateTime RoundedDate(DateTime eventTime, EventTimings strategy)
{
   switch (strategy)
      case EventTimings.Weekly :
         return WeeklyRounding(eventTime);
   ... etc ...

Таким образом, теперь вы можете написать специализированный метод для 12-часового интервала, недельного интервала и протестировать его для любой возможной входной даты, не завися от часов вашего компьютера.

person Mathias    schedule 29.09.2011

Вы также можете попробовать что-то подобное, хотя это не работает, если вы хотите делать что-то ежемесячно (потому что в каждом месяце разное количество дней). будет каждые 7 дней со дня начала... не обязательно по воскресеньям. Однако вы можете легко приспособить такое поведение с помощью оператора switch. Перегруженный метод также дает вам некоторую гибкость для предоставления пользовательского смещения.

Кроме того, чтобы ответить на ваш вопрос, да, я бы использовал System.DateTime и System.TimeSpan. Они определяют, «перекатился» ли для вас год или месяц.

public enum EventTimings : int
{
    Default = 12,           // Default every 12 hours.
    NoonAndMidnight = 12,   // Every 12 hours.
    Weekly = 168,           // 168 hours in a week.
    ThirtyDays = 720        // 720 hours in 30 days.
}

public DateTime CalculateDateTime(DateTime starting, EventTimings timing)
{
    return CalculateDateTime(starting, TimeSpan.FromHours((int)timing));
}

public DateTime CalculateDateTime(DateTime starting, TimeSpan span)
{
    DateTime baseTime = new DateTime(starting.Year, starting.Month, starting.Day, starting.Hour >= 12 ? 12 : 0, 0, 0);
    return baseTime.Add(span);
}
person bporter    schedule 29.09.2011

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

Как мне это написать?

Для каждые 12 часов проверьте свойство часа входной даты и убедитесь, что оно меньше 12. Если это так, создайте новый TimeSpan для 12 часов дня и добавьте его в часть даты входной даты. Если нет, добавьте 1 день к дате ввода, создайте TimeSpan для 12:00 и добавьте его в часть даты ввода.

Для еженедельного (понедельник 12:00) проверьте день недели ввода и просто добавьте количество дней, чтобы сделать его равным входящему понедельнику (что так же просто, как (8 - dayoftheweek)) и добавьте 12:00 TimeSpan к дате входящего Дата понедельника.

   public enum EventTimings
    {
        Every12Hours,  // 12pm and midnight
        Weekly // sunday at midnight
    }


    public static DateTime CalculateEventTime(EventTimings eventTime, DateTime inputDate)
    {
        DateTime time = DateTime.Now;
        switch (eventTime)
        {
            case EventTimings.Every12Hours:
                time = inputDate.Hour > 12 ? inputDate.AddDays(1).Date + new TimeSpan(0, 0, 0) : inputDate.Date + new TimeSpan(12, 0, 0);
                return time;
            case EventTimings.Weekly:
                int dayoftheweek = (int) inputDate.DayOfWeek;
                time = inputDate.AddDays(8 - dayoftheweek).Date + new TimeSpan(0, 0, 0);
                return time;
// other cases

        }

    }

Является ли datetime лучшим для этого сценария?

да. Ваши вычисления даты и времени с использованием DateTime и TimeSpan должны учитывать високосные годы, летнее время или сценарии конца года. Кроме того, вы можете попробовать добавить SpecifyKind, чтобы обозначить местное время.

person Kash    schedule 29.09.2011

Алгоритм, которому я следую, выглядит так...

  1. Поместите полдень eventTime в переменную
  2. Проверьте, находится ли эта переменная перед eventTime
  3. Если это не так, добавьте к нему 12 часов.
  4. Вернуть переменную

    switch (strategy)
    {
        case EventTimings.Every12Hours:
        //get noon for the event date
        DateTime x = eventTime.Date.AddHours(12);
    
        //check to see if x is after the eventTime
        if (x < eventTime)
        {
            //if so, advance x by 12 hours to get midnight on the next day
            x = x.AddHours(12);
        }
    
        return x;
    
        break;
    
        //other cases...
    }
    
person Rick Liddle    schedule 29.09.2011