Изменить время вперед - PullRequest
       9

Изменить время вперед

0 голосов
/ 31 августа 2018

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

Например, если дата из базы данных - [06.06.2017, 5:00:00 AM], а заданное фиксированное время - 22:00, тогда я хочу получить [06.07.2017 10:00: 00:00].

Однако, если фиксированное время - 02:00, то я хочу получить [7/7/2017 02:00:00 AM] (обратите внимание, что дата увеличилась на единицу)

Примечание: код выполняется, но я изменил код, чтобы сделать его короче и более понятным. Таким образом, могут быть синтаксические или орфографические ошибки.

Мое первое решение было примерно таким:

    private DateTime setTimeForeward(DateTime date) {

        DateTime today = DateTime.ParseExact(FixedTime, "hh:mm tt", CultureInfo.InvariantCulture);

        TimeSpan difference = today.TimeOfDay - date.TimeOfDay;

        return date + difference;

    }

Это не сработало, как ожидалось, когда фиксированное время - 02:00. Разница становится отрицательной (она не идет круглосуточно), и дата будет [6/7/2017 02:00:00 AM].

Я получил следующий код

   private DateTime setTimeForeward(DateTime date) {

        DateTime today = DateTime.ParseExact(FixedTime "hh:mm tt", CultureInfo.InvariantCulture);

        TimeSpan difference = today.TimeOfDay - date.TimeOfDay;

        if (difference.Hours < 0) {

            difference += new TimeSpan(24, 0, 0);

        }

        return date + difference;

    }

Я не уверен, что моя функция логически верна, и я чувствую, что переосмыслил ее Кроме того, я не уверен, есть ли лучший способ или встроенная функция, которая делает то, что я хочу для меня. По сути, я ищу правильное и элегантное решение.

Большое спасибо в продвинутом.

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

В этом методе я использую DateTime fixedTime для представления времени. Меня не особо волнуют его Day, Month, and Year значения.

static DateTime GetClosingTime(DateTime fixedTime, DateTime dbTime)
{
    var cutoff = new DateTime(dbTime.Year, dbTime.Month, dbTime.Day, fixedTime.Hour, fixedTime.Minute, fixedTime.Second);
    if (dbTime < cutoff)
        return cutoff;
    else
    {
        cutoff = cutoff.AddDays(1);
        return cutoff;
    }
}

Здесь вызывается с предоставленным вами примером ввода.

var FixedTime10PM = new DateTime(1, 1, 1, 22, 0, 0);
var FixedTime02AM = new DateTime(1, 1, 1, 2, 0, 0);

var dbTime = new DateTime(2018, 6, 20, 5, 0, 0);

var dt1 = GetClosingTime(FixedTime10PM, dbTime);
var dt2 = GetClosingTime(FixedTime02AM, dbTime);

Console.WriteLine(dt1.ToLongDateString() + " " + dt1.ToLongTimeString());
Console.WriteLine(dt2.ToLongDateString() + " " + dt2.ToLongTimeString());

А вот мой вывод:

enter image description here


EDIT:

Упрощенный метод на основе предложений в комментариях:

static DateTime GetClosingTime(DateTime fixedTime, DateTime dbTime)
{
    var cutoff = new DateTime(dbTime.Year, dbTime.Month, dbTime.Day, fixedTime.Hour, fixedTime.Minute, fixedTime.Second);
    return dbTime < cutoff ? cutoff : cutoff.AddDays(1);
}
0 голосов
/ 31 августа 2018

Немного другой подход:

private DateTime setTimeForeward(DateTime date)
{
    var targetTimeOfDay = TimeSpan.ParseExact(FixedTime, "hh:mm tt", CultureInfo.InvariantCulture);

    if (targetTimeOfDay < date.TimeOfDay)
    {
        date = date.AddDays(1);
    }

    return date.Date + targetTimeOfDay;
}

Я получаю целевое время как TimeSpan с самого начала вместо создания DateTime и получения TimeOfDay (который является TimeSpan). Затем я проверяю, меньше ли целевое время дня, чем время, которое нужно изменить, и добавляю ли я один день. Я использую date.Date + targetTimeOfDay в качестве возвращаемого значения, так как date.Date вернет дату со временем, установленным на 00:00, и добавление целевого времени к нему уже установит целевой час без расчета разницы.

0 голосов
/ 31 августа 2018

Ваша логика почти правильная, но вы не должны проверять difference.Hours, потому что может быть разница в минутах (или даже секундах, если вы изменили формат позже).

Я настроил вашу функцию и изменил некоторые имена переменных, чтобы им было легче следовать:

private DateTime SetTimeForward(DateTime originalDate)
{
    TimeSpan newTime = DateTime.ParseExact(FixedTime, 
                                           "hh:mm tt", 
                                           CultureInfo.InvariantCulture).TimeOfDay;
    TimeSpan diff = newTime - originalDate.TimeOfDay;

    if (diff.Ticks < 0)
        diff = diff.Add(new TimeSpan(24, 0, 0));

    return originalDate.Add(diff);
}

Некоторые замечания:

  • Если ваш FixedTime является действительно фиксированным, вы можете сохранить его непосредственно как TimeSpan, чтобы вам не приходилось каждый раз анализировать его.

  • Если вы анализируете FixedTime, потому что он является изменяемым, вы можете вместо этого передать его в качестве второго аргумента:

    private DateTime SetTimeForward(DateTime originalDate, string fixedTime)
    

    Или:

    private DateTime SetTimeForward(DateTime originalDate, TimeSpan newTime)
    
  • Текущая реализация не изменяет значение даты, если newTime равно originalDate.TimeOfDay. Т.е., если originalDate равно 7/6/2017 2:00 AM и FixedTime / newTime равно 02:00 AM, возвращаемая дата будет равна originalDate. Если это не ваше поведение, вы можете изменить diff.Ticks < 0 на diff.Ticks <= 0.

...