Как изменить время в DateTime?

353

Как я могу изменить только время в моей DateTimeпеременной "s"?

DateTime s = some datetime;
Santhosh
источник

Ответы:

598

Вы не можете изменить значение DateTime - оно неизменно. Однако вы можете изменить переменную на новое значение. Самый простой способ сделать это, чтобы изменить только время, это создать TimeSpan с соответствующим временем и использовать свойство DateTime.Date:

DateTime s = ...;
TimeSpan ts = new TimeSpan(10, 30, 0);
s = s.Date + ts;

s будет та же дата, но в 10:30 утра.

Обратите внимание, что DateTimeне учитываются переходы на летнее время, представляющие «наивное» григорианское время в обоих направлениях (см. Раздел «Примечания» в DateTimeдокументации ). Единственными исключениями являются .Nowи .Today: они получают текущее системное время, которое отражает эти события по мере их возникновения.

Именно это побудило меня начать проект Noda Time , который сейчас готов к производству. Его ZonedDateTimeтип делается «осведомленным» , связывая его с tzзаписью базы данных .

Джон Скит
источник
11
s.Date.Add (новый TimeSpan (0, 0, 0)) также должен работать. Использование его для обнуления времени при проверке между днями.
Йогурт Мудрый
8
@ user295734: Почему бы вам назвать Addнулевой промежуток времени? Ваше выражение эквивалентно s.Date, но дольше ...
Джон Скит
Забыл исправить это, понял это после того, как я поместил его в код для установки на ноль (то, что я искал изначально). Но я просто пытался показать, как установить время в одной строке, если не установить 0.
Йогурт Мудрый
3
Если у вас есть 2 DateTimeс (один для даты и один для времени), вы можете сделать это:var result = date.Date + time.TimeOfDay;
Захария Йейтс
2
@ZacharyYates: Да, хотя я бы сказал, что на этом этапе ваша модель изначально timeне работает , и не должна быть DateTime. (Конечно, я бы использовал Noda Time, но ...)
Джон Скит,
100

Хорошо, я погружаюсь с моим предложением, метод расширения:

public static DateTime ChangeTime(this DateTime dateTime, int hours, int minutes, int seconds, int milliseconds)
{
    return new DateTime(
        dateTime.Year,
        dateTime.Month,
        dateTime.Day,
        hours,
        minutes,
        seconds,
        milliseconds,
        dateTime.Kind);
}

Затем позвоните:

DateTime myDate = DateTime.Now.ChangeTime(10,10,10,0);

Важно отметить, что это расширение возвращает новый объект даты, поэтому вы не можете сделать это:

DateTime myDate = DateTime.Now;
myDate.ChangeTime(10,10,10,0);

Но вы можете сделать это:

DateTime myDate = DateTime.Now;
myDate = myDate.ChangeTime(10,10,10,0);
joshcomley
источник
6
Это по сути то же самое, что и Datetime.Today.Add(time.TimeOfDay). Это связано с тем, что внутренне конструктор не делает никаких корректировок на основе календаря, за исключением учета високосного года для части даты. Т.е. DateTimeэто «наивная» реализация в терминах datetimeмодуля Python .
ivan_pozdeev
68
s = s.Date.AddHours(x).AddMinutes(y).AddSeconds(z);

Таким образом, вы сохраняете дату, добавляя новые часы, минуты и секунды по своему вкусу.

Webleeuw
источник
@Webleeuw Конечно, удаленная возможность ArgumentOutOfRangeException в зависимости от добавленных значений. Вот загадка Пекса, которая демонстрирует это.
спасательный круг
И в зависимости от варианта использования, также может сделать, .AddMilliseconds()если это необходимо.
Broots Waymb
41

один лайнер

var date = DateTime.Now.Date.Add(new TimeSpan(4, 30, 0));

вернул бы текущую дату со временем 4:30:00, заменив DateTime.Now на любой объект даты

Карл Вудхаус
источник
22

DateTime является неизменяемым типом, поэтому вы не можете его изменить .

Однако вы можете создать новый экземпляр DateTime на основе вашего предыдущего экземпляра. В вашем случае это звучит так, как будто вам нужно свойство Date, и вы можете добавить TimeSpan, который представляет время дня.

Что-то вроде этого:

var newDt = s.Date + TimeSpan.FromHours(2);
Марк Симанн
источник
17

Если у вас уже есть время, сохраненное в другом DateTimeобъекте, вы можете использовать Addметод.

DateTime dateToUse = DateTime.Now();
DateTime timeToUse = new DateTime(2012, 2, 4, 10, 15, 30); //10:15:30 AM

DateTime dateWithRightTime = dateToUse.Date.Add(timeToUse.TimeOfDay);

TimeOfDayСвойство является TimeSpanобъектом и может быть передан Addметоду. И поскольку мы используем Dateсвойство dateToUseпеременной, мы получаем только дату и добавляем промежуток времени.

ShaneA
источник
16

Самое простое решение:

DateTime s = //some Datetime that you want to change time for 8:36:44 ;
s = new DateTime(s.Year, s.Month, s.Day, 8, 36, 44);

И если вам нужен конкретный формат даты и времени:

s = new DateTime(s.Year, s.Month, s.Day, 8, 36, 44).ToString("yyyy-MM-dd h:mm:ss");
Мистер рубикс
источник
9
DateTime ts = DateTime.Now;
ts = new DateTime ( ts.Year, ts.Month, ts.Day, 0, 0, 0 ) ;
Console.WriteLine ( "Today = " + ts.ToString("M/dd/yy HH:mm:ss") ) ;

Выполнено: сегодня = 9/04/15 00:00:00

Филипп
источник
8

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

DateTime dayOpen = DateTime.Parse(processDay.ToShortDateString() + " 05:00 AM");
BlackLarry
источник
4

Так как DateTimeявляется неизменным, новый экземпляр должен быть создан, когда необходимо изменить компонент даты. К сожалению, нет встроенной функциональности для установки отдельных компонентовDateTime экземпляра.

Используя следующие методы расширения

public static DateTime SetPart(this DateTime dateTime, int? year, int? month, int? day, int? hour, int? minute, int? second)
{
    return new DateTime(
        year ?? dateTime.Year,
        month ?? dateTime.Month,
        day ?? dateTime.Day,
        hour ?? dateTime.Hour,
        minute ?? dateTime.Minute,
        second ?? dateTime.Second
    );
}

public static DateTime SetYear(this DateTime dateTime, int year)
{
    return dateTime.SetPart(year, null, null, null, null, null);
}

public static DateTime SetMonth(this DateTime dateTime, int month)
{
    return dateTime.SetPart(null, month, null, null, null, null);
}

public static DateTime SetDay(this DateTime dateTime, int day)
{
    return dateTime.SetPart(null, null, day, null, null, null);
}

public static DateTime SetHour(this DateTime dateTime, int hour)
{
    return dateTime.SetPart(null, null, null, hour, null, null);
}

public static DateTime SetMinute(this DateTime dateTime, int minute)
{
    return dateTime.SetPart(null, null, null, null, minute, null);
}

public static DateTime SetSecond(this DateTime dateTime, int second)
{
    return dateTime.SetPart(null, null, null, null, null, second);
}

Вы можете установить отдельные DateTimeкомпоненты, такие как

var now = DateTime.Now;

now.SetSecond(0);
solidsparrow
источник
3

Если у вас есть DateTime, например 2014/02/05 18:19:51 и вы хотите просто 2014/02/05, вы можете сделать это:

_yourDateTime = new DateTime(_yourDateTime.Year, _yourDateTime.Month, _yourDateTime.Day)
Кассио Алан Гарсия
источник
3

Добавление. Дата к вашей дате устанавливает его на полночь (00:00).

MyDate.Date

Примечание . Эквивалентный SQLCONVERT(DATETIME, CONVERT(DATE, @MyDate))

Что делает этот метод настолько хорошим, так это то, что он быстро набирается и легко читается. Бонус в том, что нет конвертации из строк.

Т.е. чтобы установить сегодняшнюю дату на 23:30, используйте:

DateTime.Now.Date.AddHours(23).AddMinutes(30)

Конечно, вы можете заменить DateTime.Now или MyDate на любую дату по вашему выбору.

Чудотворец
источник
3

На самом деле, вы не можете изменить время, как только оно будет создано. Но вы можете легко создать его с помощью многих конструкторов: https://docs.microsoft.com/en-us/dotnet/api/system.datetime.-ctor?view=netframework-4.7.2

Например, если вы хотите создать DateTime, изменяющий Seconds, вы можете просто сделать это:

DateTime now = DateTime.Now;
DateTime secondschanged = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, yourseconds);
Франческ М.П.
источник
2
int year = 2012;
int month = 12;
int day = 24;
int hour = 0;
int min = 0;
int second = 23;
DateTime dt = new DateTime(year, month, day, hour, min, second);
Сагар Равал
источник
2

Используйте Date.Addи добавьте New TimeSpanс новым временем, которое вы хотите добавить

DateTime dt = DateTime.Now
dt.Date.Add(new TimeSpan(12,15,00))
Йонатан Тучинский
источник
1

Когда вы создаете свой DateTimeобъект, используйте конструктор, который позволяет вам указать время:

var myDateTime = new DateTime(2000, 01, 01, 13, 37, 42);  // 2000-01-01 13:37:42

Если у вас уже есть DateTimeобъект и вы хотите изменить время, вы можете добавить минуты, часы или секунды, DateTimeиспользуя простые методы:

var myDateTime = new DateTime(2000, 01, 01);              // 2000-01-01 00:00:00
myDateTime = myDateTime.AddHours(13);                     // 2000-01-01 13:00:00
myDateTime = myDateTime.AddMinutes(37);                   // 2000-01-01 13:37:00
myDateTime = myDateTime.AddSecounds(42);                  // 2000-01-01 13:37:42

Обратите внимание, как мы должны «сохранять» результат каждого вызова метода в myDateTimeпеременной. Это связано с тем, что DateTimeобъект является неизменным, а его методы просто создают новые экземпляры с добавлением дополнительных часов / минут / секунд.

Если вам нужно добавить часы и минуты (и / или секунды) и одно и то же время, вы можете упростить код, добавив вместо этого TimeSpanк оригиналу DateTime:

var myDateTime = new DateTime(2000, 01, 01);              // 2000-01-01 00:00:00
myDateTime += new TimeSpan(13, 37, 42);                   // 2000-01-01 13:37:42

Если вы хотите установить абсолютные часы / минуты / секунды, а не добавлять к существующим значениям, вы можете использовать вышеупомянутый DateTimeконструктор и повторно использовать значения для года / месяца / дня из ранее:

myDateTime = new DateTime(myDateTime.Year, myDateTime.Month, myDateTime.Day,
                          20, 33, 19)                     // 2000-01-01 20:33:19
Йорн Шоу-Роде
источник
Сложение и вычитание с использованием методов AddXXX
Chris Richner
1

Вот метод, который вы могли бы использовать, чтобы сделать это для вас, используйте его следующим образом

DateTime newDataTime = ChangeDateTimePart(oldDateTime, DateTimePart.Seconds, 0);

Вот метод, возможно, есть лучший способ, но я только что это сделал:

public enum DateTimePart { Years, Months, Days, Hours, Minutes, Seconds };
public DateTime ChangeDateTimePart(DateTime dt, DateTimePart part, int newValue)
{
    return new DateTime(
        part == DateTimePart.Years ? newValue : dt.Year,
        part == DateTimePart.Months ? newValue : dt.Month,
        part == DateTimePart.Days ? newValue : dt.Day,
        part == DateTimePart.Hours ? newValue : dt.Hour,
        part == DateTimePart.Minutes ? newValue : dt.Minute,
        part == DateTimePart.Seconds ? newValue : dt.Second
        );
}
naspinski
источник
1

Я только что наткнулся на этот пост, потому что у меня была похожая проблема, из-за которой я хотел установить время для объекта Entity Framework в MVC, который получает дату из представления (datepicker), поэтому компонент времени - 00:00:00, но мне нужно это будет текущее время. На основании ответов в этом посте я придумал:

myEntity.FromDate += DateTime.Now.TimeOfDay;
обкрадывать
источник
1
//The fastest way to copy time            

DateTime justDate = new DateTime(2011, 1, 1); // 1/1/2011 12:00:00AM the date you will be adding time to, time ticks = 0
DateTime timeSource = new DateTime(1999, 2, 4, 10, 15, 30); // 2/4/1999 10:15:30AM - time tick = x

justDate = new DateTime(justDate.Date.Ticks + timeSource.TimeOfDay.Ticks);

Console.WriteLine(justDate); // 1/1/2011 10:15:30AM
Console.Read();
Павел Cioch
источник
1

Вы можете назначить начальное значение новому DateTimeзначению разными способами:

  • Метод расширения

Метод расширения DateTime

    public static DateTime ChangeTime(this DateTime dateTime, int hours, int minutes, int seconds = default, int milliseconds = default)
    {
        return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, hours, minutes, seconds, milliseconds, dateTime.Kind);
    }

затем с помощью ChangeTime:

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.ChangeTime(12, 20, 10);
  • используя методы Add

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.Date.AddHours(12).AddMinutes(20).AddSeconds(10);
  • используя Timespan

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.Date.Add(new TimeSpan(12, 20, 10));
  • используя начальное значение

    DateTime datetime = DateTime.Now;
    datetime = new DateTime(datetime.Year, datetime.Month, datetime.Day, 12, 20, 10);
Реза Дженаби
источник
0

Что не так с методом DateTime.AddSeconds, где вы можете добавлять или вычитать секунды?

Крис Ричнер
источник
Не только это, но это не звучит так, как будто все равно отвечает на вопрос. Я подозреваю, что OP хочет DateTime с той же датой, но с определенным временем - что было бы относительно трудно сделать, просто используя AddSeconds.
Джон Скит
0
  DateTime s;
//s = datevalue
                s = s.AddMilliseconds(10);
                s = s.AddMinutes(10);
                s = s.AddSeconds(10);
                s = s.AddHours(10);

Вы можете добавить + ve / -ve значения в параметре.

s.Add(new TimeSpan(1, 1, 1));
Саар
источник
@Jon: я прокомментировал строку. пользователю необходимо присвоить какое-то значение перед использованием этого кода.
Саар
@Saar: Что еще более важно, вы теперь добавили назначения обратно в s (за исключением вызова s.Add (...)).
Джон Скит
@Jon: я усвоил урок. Спасибо за вашу доброту и время. Я действительно это имею в виду.
Саар
0

Разве это не решает ваши проблемы?

Dateime dt = DateTime.Now;
dt = dt.AddSeconds(10);
Навид Батт
источник
0

Я предпочитаю это:

DateTime s = //get some datetime;
s = new DateTime(s.Year, s.Month,s.Day,s.Hour,s.Minute,0);
Эндрю
источник
0
 Using an extencion to DateTime:  

        public enum eTimeFragment
        {
            hours,
            minutes,
            seconds,
            milliseconds
        }
        public static DateTime ClearTimeFrom(this DateTime dateToClear, eTimeFragment etf)
        {
            DateTime dtRet = dateToClear;
            switch (etf)
            {
                case eTimeFragment.hours:
                    dtRet = dateToClear.Date;
                    break;
                case eTimeFragment.minutes:
                    dtRet = dateToClear.AddMinutes(dateToClear.Minute * -1);
                    dtRet = dtRet.ClearTimeFrom(eTimeFragment.seconds);
                    break;
                case eTimeFragment.seconds:
                    dtRet = dateToClear.AddSeconds(dateToClear.Second * -1);
                    dtRet = dtRet.ClearTimeFrom(eTimeFragment.milliseconds);
                    break;
                case eTimeFragment.milliseconds:
                    dtRet = dateToClear.AddMilliseconds(dateToClear.Millisecond * -1);
                    break;
            }
            return dtRet;

        }

Используйте как это:

Console.WriteLine (DateTime.Now.ClearTimeFrom (eTimeFragment.hours))

это должно вернуть: 2016-06-06 00: 00: 00.000

Рикардо Фигейредо
источник
-1

Лучшее решение:

currdate.AddMilliseconds(currdate.Millisecond * -1).AddSeconds(currdate.Second * -1).AddMinutes(currdate.Minute * -1).AddHours(currdate.Hour * -1);
Махеш Алвани
источник
1
Сначала я думал, что это неправильно, но это имеет смысл если вы присваиваете результат объекту DateTime. Это не лучшее решение, хотя. Это требует, чтобы вы знали текущую часть времени, чтобы сделать правильные вычисления, при этом беря часть даты даты и добавляя там лучшее.
ThunderGr
1
Определенно не "лучший". Далеко не читабельно и с повторным использованием магического числа.
BartoszKP
-1

Попробуй это

var NewDate = Convert.ToDateTime(DateTime.Now.ToString("dd/MMM/yyyy")+" "+"10:15 PM")/*Add your time here*/;
Vicky
источник
-5

это гетто, но оно работает :)

DateTime dt = DateTime.Now; //get a DateTime variable for the example
string newSecondsValue = "00";
dt = Convert.ToDateTime(dt.ToString("MM/dd/yyyy hh:mm:" + newSecondsValue));
naspinski
источник
Другой способ гетто, но немного чище, - просто поиграть с секундами. например, dt.AddSeconds(0-dt.Seconds).AddSeconds(newSecondsValue)но не рекомендовал бы это.
Майк