Come cambiare l'ora in DateTime?


353

Come posso cambiare solo il tempo nel mio DateTime variabile "s"?

DateTime s = some datetime;

Risposte:


598

Non è possibile modificare un valore DateTime: è immutabile. Tuttavia, è possibile modificare la variabile per avere un nuovo valore. Il modo più semplice per farlo per cambiare l'ora è creare un TimeSpan con l'ora pertinente e usare la proprietà DateTime.Date:

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

s sarà ora la stessa data, ma alle 10.30.

Si noti che DateTimeignora le transizioni dell'ora legale, che rappresentano l'ora gregoriana "ingenua" in entrambe le direzioni (vedere la sezione Osservazioni nella DateTimedocumentazione ). Le uniche eccezioni sono.Now e .Today: recuperano l'ora di sistema corrente che riflette questi eventi nel momento in cui si verificano.

Questo è il tipo di cosa che mi ha motivato ad avviare il progetto Noda Time , che ora è pronto per la produzione. Il suo ZonedDateTimetipo viene reso "consapevole" collegandolo a una tzvoce del database .


11
s.Date.Add (new TimeSpan (0, 0, 0)) dovrebbe funzionare anche. Usandolo per annullare il timeout durante il controllo tra giorni.
Yogurt The Wise

8
@ user295734: Perché chiameresti Addfornendo un periodo zero? La tua espressione è equivalente s.Date, ma più lunga ...
Jon Skeet

Ho dimenticato di correggerlo, me ne sono reso conto dopo averlo inserito nel codice, per impostare su zero (quello che stavo cercando originariamente). Ma stavo solo cercando di mostrare come impostare un tempo su una riga, se non impostato su 0.
Yogurt The Wise

3
Se hai 2 DateTimes (uno per la data e uno per l'ora) puoi farlo:var result = date.Date + time.TimeOfDay;
Zachary Yates,

2
@ZacharyYates: Sì, anche se direi che a quel punto il tuo modello è rotto per cominciare, e timenon dovrebbe essere un DateTime. (Userei Noda Time ovviamente, ma ...)
Jon Skeet,

100

Bene, mi sto tuffando con il mio suggerimento, un metodo di estensione:

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

Quindi chiama:

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

È importante notare che questa estensione restituisce un nuovo oggetto data, quindi non puoi farlo:

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

Ma puoi farlo:

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

6
Questo è essenzialmente lo stesso di Datetime.Today.Add(time.TimeOfDay). Questo perché internamente, il costruttore non esegue correzioni basate sul calendario tranne che contabilizzando un anno bisestile per la parte della data. Vale a dire DateTimeun'implementazione "ingenua" in termini di datetimemodulo di Python .
ivan_pozdeev,

68
s = s.Date.AddHours(x).AddMinutes(y).AddSeconds(z);

In questo modo conservi la tua data, mentre inserisci una nuova parte di ore, minuti e secondi a tuo piacimento.


@Webleeuw Ovviamente, una remota possibilità di un ArgumentOutOfRangeException a seconda dei valori aggiunti. Ecco un puzzle Pex che lo dimostra.
lifebalance

E a seconda del caso d'uso, può anche fare .AddMilliseconds()se necessario.
Broots Waymb,

41

una fodera

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

riporterebbe la data odierna con un tempo di 4:30:00, sostituire DateTime.Oow con qualsiasi oggetto data


22

DateTime è un tipo immutabile, quindi non è possibile modificarlo .

Tuttavia, è possibile creare una nuova istanza DateTime in base all'istanza precedente. Nel tuo caso, sembra che tu abbia bisogno della proprietà Date e puoi quindi aggiungere un TimeSpan che rappresenta l'ora del giorno.

Qualcosa come questo:

var newDt = s.Date + TimeSpan.FromHours(2);

17

Se il tempo è già memorizzato in un altro DateTimeoggetto, è possibile utilizzare il Addmetodo

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

La TimeOfDayproprietà è un TimeSpanoggetto e può essere passata al Addmetodo. E poiché utilizziamo la Dateproprietà della dateToUsevariabile otteniamo solo la data e aggiungiamo l'intervallo di tempo.


16

La soluzione più semplice:

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 hai bisogno di un formato data e ora specifico:

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

Eseguito: oggi = 9/04/15 00:00:00


8

È successo in questo post mentre cercavo la stessa funzionalità che poteva fare quello che voleva il ragazzo. Prendi la data originale e sostituisci la parte temporale

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

4

Da DateTime è immutabile, è necessario creare una nuova istanza quando è necessario modificare un componente data. Sfortunatamente, non esiste alcuna funzionalità integrata per impostare i singoli componenti di aDateTime un'istanza.

Utilizzando i seguenti metodi di estensione

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

è possibile impostare singoli DateTimecomponenti come

var now = DateTime.Now;

now.SetSecond(0);

3

Se hai un DateTime del 2014/02/05 alle 18:19:51 e vuoi solo il 2014/02/05, puoi farlo:

_yourDateTime = new DateTime(_yourDateTime.Year, _yourDateTime.Month, _yourDateTime.Day)

3

L'aggiunta di .Date alla data lo imposta a mezzanotte (00:00).

MyDate.Date

Nota Il codice SQL equivavalente èCONVERT(DATETIME, CONVERT(DATE, @MyDate))

Ciò che rende questo metodo così buono è che è sia veloce da scrivere sia da leggere. Un bonus è che non c'è conversione dalle stringhe.

Vale a dire Per impostare la data di oggi alle 23:30, utilizzare:

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

Ovviamente puoi sostituire DateTime.Now o MyDate con qualsiasi data a tua scelta.



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

Utilizzare Date.Adde aggiungere a New TimeSpancon il nuovo orario che si desidera aggiungere

DateTime dt = DateTime.Now
dt.Date.Add(new TimeSpan(12,15,00))

1

Quando costruisci il tuo DateTimeoggetto, usa un costruttore che ti consenta di specificare l'ora:

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

Se hai già un DateTimeoggetto e desideri cambiare l'ora, puoi aggiungere minuti, ore o secondi al tuo DateTimeusando semplici metodi:

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

Nota come dobbiamo "salvare" il risultato di ogni chiamata di metodo alla myDateTimevariabile. Questo perché DateTimeimmutabile e i suoi metodi creano semplicemente nuove istanze con l'aggiunta di ore / minuti / secondi aggiuntivi.

Se devi aggiungere sia le ore che i minuti (e / o secondi) e allo stesso tempo, puoi semplificare il codice aggiungendo invece un TimeSpanoriginale 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 si desidera impostare ore / minuti / secondi assoluti, piuttosto che aggiungere ai valori esistenti, è possibile utilizzare il DateTimecostruttore sopra menzionato e riutilizzare i valori per anno / mese / giorno precedenti:

myDateTime = new DateTime(myDateTime.Year, myDateTime.Month, myDateTime.Day,
                          20, 33, 19)                     // 2000-01-01 20:33:19

Aggiungi e sottrai utilizzando i metodi AddXXX
Chris Richner,

1

Ecco un metodo che potresti usare per farlo per te, usalo in questo modo

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

Ecco il metodo, probabilmente c'è un modo migliore, ma l'ho appena montato:

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

1

Mi sono appena imbattuto in questo post perché avevo un problema simile in base al quale volevo impostare l'ora per un oggetto Entity Framework in MVC che ottiene la data da una vista (datepicker), quindi la componente temporale è 00:00:00 ma ho bisogno essere l'ora corrente. Sulla base delle risposte in questo post ho pensato a:

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

1

È possibile assegnare un valore iniziale a un nuovo DateTimevalore in molti modi diversi:

  • Metodo di estensione

Metodo di estensione 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);
    }

quindi utilizzando ChangeTime:

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.ChangeTime(12, 20, 10);
  • usando i metodi Aggiungi

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

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

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

0

Cosa c'è di sbagliato nel metodo DateTime.AddSeconds in cui è possibile aggiungere o sottrarre secondi?


Non solo, ma non sembra che risponda comunque alla domanda. Ho il sospetto che l'OP voglia un DateTime con la stessa data ma un orario specifico - che sarebbe relativamente difficile da fare solo usando AddSeconds.
Jon Skeet,

0
  DateTime s;
//s = datevalue
                s = s.AddMilliseconds(10);
                s = s.AddMinutes(10);
                s = s.AddSeconds(10);
                s = s.AddHours(10);

potresti aggiungere i valori + ve / -ve nel parametro.

s.Add(new TimeSpan(1, 1, 1));

@Jon: ho commentato la riga. l'utente deve assegnare un valore prima di utilizzare questo codice.
Saar

@Saar: Ancora più importante, ora hai aggiunto i compiti a s (ad eccezione della chiamata a s.Add (...)).
Jon Skeet,

@Jon: ho imparato la mia lezione. Grazie per la tua gentilezza e tempo. Dico davvero.
Saar

0

Non risolve i tuoi problemi ??

Dateime dt = DateTime.Now;
dt = dt.AddSeconds(10);

0

Preferisco questo:

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;

        }

Usa così:

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

questo deve tornare: 06/06/2016 00: 00: 00.000


-1

La migliore soluzione è:

currdate.AddMilliseconds(currdate.Millisecond * -1).AddSeconds(currdate.Second * -1).AddMinutes(currdate.Minute * -1).AddHours(currdate.Hour * -1);

1
All'inizio ho pensato che fosse sbagliato, ma ha senso se assegni il risultato a un oggetto DateTime. Tuttavia non è la soluzione migliore. Richiede di conoscere la parte Ora corrente al fine di effettuare i calcoli corretti, prendendo la parte Data della data e aggiungendola è la migliore.
ThunderGr

1
Sicuramente non "migliore". Lungi dall'essere leggibile e con l'uso ripetitivo di un numero magico.
BartoszKP,

-1

Prova questo

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

-5

ecco un modo ghetto, ma funziona :)

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

Un altro modo di ghetto, ma un po 'più pulito, sarebbe solo giocare con i secondi. ad es. dt.AddSeconds(0-dt.Seconds).AddSeconds(newSecondsValue)ma non lo consiglierei.
mike,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.