Como alterar a hora no DateTime?

353

Como posso alterar apenas o tempo na minha DateTimevariável "s"?

DateTime s = some datetime;
Santhosh
fonte

Respostas:

598

Você não pode alterar um valor DateTime - é imutável. No entanto, você pode alterar a variável para ter um novo valor. A maneira mais fácil de fazer isso para alterar apenas a hora é criar um TimeSpan com a hora relevante e usar a propriedade DateTime.Date:

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

s agora será a mesma data, mas às 10h30.

Observe que DateTimedesconsidera as transições de horário de verão, representando o horário gregoriano "ingênuo" nas duas direções (consulte a seção Observações na DateTimedocumentação ). As únicas exceções são .Nowe .Today: eles recuperam a hora atual do sistema, que reflete esses eventos à medida que ocorrem.

Esse é o tipo de coisa que me motivou a iniciar o projeto Noda Time , que agora está pronto para produção. Seu ZonedDateTimetipo é "ciente" vinculando-o a uma tzentrada do banco de dados .

Jon Skeet
fonte
11
s.Date.Add (novo TimeSpan (0, 0, 0)) também deve funcionar. Usá-lo para anular o tempo ao verificar entre dias.
Iogurte The Wise
8
@ user295734: Por que você chamaria Addfornecer um período de tempo zero? Sua expressão é equivalente a s.Date, mas mais tempo ...
Jon Skeet
Esqueci de corrigi-lo, percebi depois que o coloquei no código, para definir como zero (o que eu estava procurando originalmente). Mas eu estava apenas tentando mostrar como obter um conjunto vez em uma linha, se não definir a 0.
Iogurte The Wise
3
Se você tem 2 DateTimes, (um para a data e uma para o tempo) você pode fazer isso:var result = date.Date + time.TimeOfDay;
Zachary Yates
2
@ZacharyYates: Sim, embora eu afirme que nesse momento seu modelo está quebrado para começar e timenão deve ser um DateTime. (Eu usaria Noda Tempo é claro, mas ...)
Jon Skeet
100

Tudo bem, eu estou mergulhando com a minha sugestão, um método de extensão:

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

Então ligue:

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

É importante observar que essa extensão retorna um novo objeto de data, portanto você não pode fazer isso:

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

Mas você pode fazer isso:

DateTime myDate = DateTime.Now;
myDate = myDate.ChangeTime(10,10,10,0);
Joshcomley
fonte
6
Isto é essencialmente o mesmo que Datetime.Today.Add(time.TimeOfDay). Isso ocorre porque internamente, o construtor não faz nenhuma correção baseada em calendário, exceto contabilizando um ano bissexto para a parte da data. Ou seja, DateTimeé uma implementação "ingênua" em termos de datetimemódulo do Python .
ivan_pozdeev
68
s = s.Date.AddHours(x).AddMinutes(y).AddSeconds(z);

Dessa forma, você preserva sua data, enquanto insere novas horas, minutos e segundos, ao seu gosto.

Webleeuw
fonte
@ Webleeuw Obviamente, uma possibilidade remota de uma ArgumentOutOfRangeException dependendo dos valores adicionados. Aqui está um quebra-cabeça de Pex que demonstra isso.
lifebalance
E, dependendo do caso de uso, também pode ser feito, .AddMilliseconds()se necessário.
Broots Waymb
40

um forro

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

traria de volta a data de hoje com um horário de 4:30:00, substitua DateTime.Now por qualquer objeto de data

Carl Woodhouse
fonte
22

DateTime é um tipo imutável, então você não pode mudar lo.

No entanto, você pode criar uma nova instância DateTime com base na sua instância anterior. No seu caso, parece que você precisa da propriedade Date e pode adicionar um TimeSpan que representa a hora do dia.

Algo assim:

var newDt = s.Date + TimeSpan.FromHours(2);
Mark Seemann
fonte
17

Se você já possui o tempo armazenado em outro DateTimeobjeto, pode usar o Addmétodo

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

A TimeOfDaypropriedade é um TimeSpanobjeto e pode ser passada para o Addmétodo E como usamos a Datepropriedade da dateToUsevariável, obtemos apenas a data e adicionamos o intervalo de tempo.

ShaneA
fonte
16

Solução mais simples:

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

E se você precisar de um formato específico de data e hora:

s = new DateTime(s.Year, s.Month, s.Day, 8, 36, 44).ToString("yyyy-MM-dd h:mm:ss");
Mr Rubix
fonte
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") ) ;

Executado: Hoje = 9/04/15 00:00:00

Philip
fonte
8

Aconteceu neste post como eu estava procurando a mesma funcionalidade que isso poderia fazer o que o cara queria. Pegue a data original e substitua a parte do tempo

DateTime dayOpen = DateTime.Parse(processDay.ToShortDateString() + " 05:00 AM");
BlackLarry
fonte
4

Como DateTimeé imutável, uma nova instância deve ser criada quando um componente de data precisar ser alterado. Infelizmente, não há funcionalidade incorporada para definir componentes individuais de umDateTime instância.

Usando os seguintes métodos de extensão

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

você pode definir DateTimecomponentes individuais como

var now = DateTime.Now;

now.SetSecond(0);
solidsparrow
fonte
3

Se você tem um DateTime como 2014/02/05 18:19:51 e deseja apenas 2014/02/05, pode fazer isso:

_yourDateTime = new DateTime(_yourDateTime.Year, _yourDateTime.Month, _yourDateTime.Day)
Cássio Alan Garcia
fonte
3

A adição de .Date à sua data define como meia-noite (00:00).

MyDate.Date

Nota O SQL equivalente éCONVERT(DATETIME, CONVERT(DATE, @MyDate))

O que torna esse método tão bom é que ele é rápido de digitar e fácil de ler. Um bônus é que não há conversão de strings.

Ou seja, para definir a data de hoje como 23:30, use:

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

É claro que você pode substituir DateTime.Now ou MyDate por qualquer data de sua escolha.

WonderWorker
fonte
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);
Sagar Rawal
fonte
2

Use Date.Adde adicione a New TimeSpancom a nova hora que você deseja adicionar

DateTime dt = DateTime.Now
dt.Date.Add(new TimeSpan(12,15,00))
Yonatan Tuchinsky
fonte
1

Ao construir seu DateTimeobjeto, use um construtor que permita especificar o tempo:

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

Se você já possui um DateTimeobjeto e deseja alterar a hora, pode adicionar minutos, horas ou segundos ao seu DateTimeuso de métodos simples:

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

Observe como precisamos "salvar" o resultado de cada chamada de método para a myDateTimevariável. Isso ocorre porque DateTimeé imutável e seus métodos simplesmente criam novas instâncias com as horas / minutos / segundos extras adicionados.

Se você precisar adicionar horas e minutos (e / ou segundos) e o mesmo horário, poderá simplificar o código adicionando um TimeSpanao original 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

Se você deseja definir horas / minutos / segundos absolutos, em vez de adicionar aos valores existentes, pode usar o DateTimeconstrutor mencionado acima e reutilizar valores para o ano / mês / dia anteriores:

myDateTime = new DateTime(myDateTime.Year, myDateTime.Month, myDateTime.Day,
                          20, 33, 19)                     // 2000-01-01 20:33:19
Jørn Schou-Rode
fonte
Adicione e subtraia usando os métodos AddXXX
Chris Richner
1

Aqui está um método que você pode usar para fazer isso por você, use-o assim

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

Aqui está o método, provavelmente existe uma maneira melhor, mas acabei de preparar isso:

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
fonte
1

Acabei de encontrar este post porque tive um problema semelhante no qual queria definir o horário para um objeto do Entity Framework no MVC que obtém a data de uma exibição (datepicker), portanto o componente de horário é 00:00:00, mas preciso é a hora atual. Com base nas respostas deste post, eu vim com:

myEntity.FromDate += DateTime.Now.TimeOfDay;
Roubar
fonte
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();
Pawel Cioch
fonte
1

Você pode atribuir um valor inicial a um novo DateTimevalor de várias maneiras diferentes:

  • Método de Extensão

Método de extensão 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);
    }

então usando ChangeTime:

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.ChangeTime(12, 20, 10);
  • usando os métodos Add

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.Date.AddHours(12).AddMinutes(20).AddSeconds(10);
  • usando o Timespan

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.Date.Add(new TimeSpan(12, 20, 10));
  • usando valor inicial

    DateTime datetime = DateTime.Now;
    datetime = new DateTime(datetime.Year, datetime.Month, datetime.Day, 12, 20, 10);
Reza Jenabi
fonte
0

O que há de errado com o método DateTime.AddSeconds, no qual você pode adicionar ou subtrair segundos?

Chris Richner
fonte
Não apenas isso, mas não parece que responda à pergunta de qualquer maneira. Eu suspeito que o OP quer um DateTime com a mesma data, mas com um horário específico - o que seria relativamente difícil de fazer apenas usando AddSeconds.
9139 Jon Skeet
0
  DateTime s;
//s = datevalue
                s = s.AddMilliseconds(10);
                s = s.AddMinutes(10);
                s = s.AddSeconds(10);
                s = s.AddHours(10);

você pode adicionar valores + ve / -ve no parâmetro

s.Add(new TimeSpan(1, 1, 1));
Saar
fonte
@ Jon: eu comentei a linha. o usuário precisa atribuir algum valor antes de usar esse código.
Saar
@ Saar: Mais importante, agora você adicionou as atribuições de volta a s (exceto a chamada para s.Add (...)).
9139 Jon Skeet
@ Jon: eu aprendi minha lição. Obrigado pela sua gentileza e tempo. Eu realmente quero dizer isso.
214 Saar Saar
0

Isso não resolve seus problemas?

Dateime dt = DateTime.Now;
dt = dt.AddSeconds(10);
Naveed Butt
fonte
0

Eu prefiro isso:

DateTime s = //get some datetime;
s = new DateTime(s.Year, s.Month,s.Day,s.Hour,s.Minute,0);
andrew
fonte
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;

        }

Use assim:

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

isso deve retornar: 2016-06-06 00: 00: 00.000

Ricardo Figueiredo
fonte
-1

A melhor solução é:

currdate.AddMilliseconds(currdate.Millisecond * -1).AddSeconds(currdate.Second * -1).AddMinutes(currdate.Minute * -1).AddHours(currdate.Hour * -1);
Mahesh Alwani
fonte
11
No começo, pensei que isso estivesse errado, mas faz sentido se você atribuir o resultado a um objeto DateTime. Porém, não é a melhor solução. É necessário que você conheça a parte da hora atual para fazer os cálculos corretos, enquanto pega a parte da data da data e adiciona a melhor.
ThunderGr
11
Definitivamente não é "melhor". Longe de ser legível e com o uso repetitivo de um número mágico.
precisa saber é o seguinte
-1

Tente este

var NewDate = Convert.ToDateTime(DateTime.Now.ToString("dd/MMM/yyyy")+" "+"10:15 PM")/*Add your time here*/;
vicky
fonte
-5

aqui é uma maneira do gueto, mas funciona :)

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
fonte
Outra maneira de gueto, mas um pouco mais limpa, seria apenas brincar com os segundos. por exemplo, dt.AddSeconds(0-dt.Seconds).AddSeconds(newSecondsValue)mas não recomendaria.
mike