¿Cómo cambiar la hora en DateTime?

353

¿Cómo puedo cambiar solo el tiempo en mi DateTimevariable "s"?

DateTime s = some datetime;
Santhosh
fuente

Respuestas:

598

No puede cambiar un valor de DateTime, es inmutable. Sin embargo, puede cambiar la variable para que tenga un nuevo valor. La forma más fácil de hacerlo para cambiar solo la hora es crear un TimeSpan con la hora relevante y usar la propiedad DateTime.Date:

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

s ahora será la misma fecha, pero a las 10:30 a.m.

Tenga en cuenta que DateTimeno tiene en cuenta las transiciones de horario de verano, lo que representa el tiempo gregoriano "ingenuo" en ambas direcciones (consulte la sección Comentarios en los DateTimedocumentos ). Las únicas excepciones son .Nowy.Today : recuperan la hora actual del sistema que refleja estos eventos a medida que ocurren.

Este es el tipo de cosas que me motivaron a comenzar el proyecto Noda Time , que ahora está listo para la producción. Su ZonedDateTimetipo se hace "consciente" al vincularlo a una tzentrada de la base de datos .

Jon Skeet
fuente
11
s.Date.Add (nuevo TimeSpan (0, 0, 0)) también debería funcionar. Usándolo para anular el tiempo cuando se verifica entre días.
Yogurt The Wise
8
@ user295734: ¿Por qué llamarías Addproporcionando un intervalo de tiempo cero? Tu expresión es equivalente a s.Date, pero más larga ...
Jon Skeet
Olvidé corregirlo, me di cuenta después de ponerlo en el código, para ponerlo a cero (lo que estaba buscando originalmente). Pero solo estaba tratando de mostrar cómo establecer un tiempo en una línea, si no establecerlo en 0.
Yogurt The Wise
3
Si tiene 2 DateTimes, (uno para la fecha y otro para la hora) puede hacer esto:var result = date.Date + time.TimeOfDay;
Zachary Yates
2
@ZacharyYates: Sí, aunque diría que en ese momento su modelo está roto para empezar, y timeno debería ser un DateTime. (Yo usaría Noda Time, por supuesto, pero ...)
Jon Skeet
100

Muy bien, estoy buceando con mi sugerencia, un método de extensión:

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

Luego llame:

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

Es importante tener en cuenta que esta extensión devuelve un nuevo objeto de fecha, por lo que no puede hacer esto:

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

Pero puedes hacer esto:

DateTime myDate = DateTime.Now;
myDate = myDate.ChangeTime(10,10,10,0);
joshcomley
fuente
66
Esto es esencialmente lo mismo que Datetime.Today.Add(time.TimeOfDay). Esto se debe a que, internamente, el constructor no realiza correcciones basadas en el calendario, excepto la contabilidad de un año bisiesto para la parte de la fecha. Es decir, DateTimees una implementación "ingenua" en términos del datetimemódulo de Python .
ivan_pozdeev
68
s = s.Date.AddHours(x).AddMinutes(y).AddSeconds(z);

De esta manera conserva su fecha, mientras inserta una nueva parte de horas, minutos y segundos a su gusto.

Webleeuw
fuente
@Webleeuw Por supuesto, una posibilidad remota de una ArgumentOutOfRangeException dependiendo de los valores agregados. Aquí hay un rompecabezas de Pex que demuestra esto.
Lifebalance
Y dependiendo del caso de uso, también puede hacerlo .AddMilliseconds()si es necesario.
Broots Waymb
41

un trazador de líneas

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

devolvería la fecha de hoy con una hora de 4:30:00, reemplazaría DateTime.Now con cualquier objeto de fecha

Carl Woodhouse
fuente
22

DateTime es un tipo inmutable, por lo que no puede cambiar .

Sin embargo, puede crear una nueva instancia de DateTime basada en su instancia anterior. En su caso, parece que necesita la propiedad Date, y luego puede agregar un TimeSpan que representa la hora del día.

Algo como esto:

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

Si ya tiene el tiempo almacenado en otro DateTimeobjeto, puede usar el 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);

La TimeOfDaypropiedad es un TimeSpanobjeto y se puede pasar al Addmétodo. Y como usamos la Datepropiedad de la dateToUsevariable, obtenemos solo la fecha y agregamos el intervalo de tiempo.

ShaneA
fuente
16

La solución más simple:

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

Y si necesita un formato de fecha y hora específico:

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

Ejecutado: Hoy = 9/04/15 00:00:00

philip
fuente
8

Ocurrió con esta publicación cuando estaba buscando la misma funcionalidad que posiblemente podría hacer lo que el chico quería. Tome la fecha original y reemplace la parte de tiempo

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

Como DateTimees inmutable, se debe crear una nueva instancia cuando se necesita cambiar un componente de fecha. Desafortunadamente, no hay una funcionalidad incorporada para configurar componentes individuales de una DateTimeinstancia.

Usando los siguientes métodos de extensión

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

puedes configurar DateTimecomponentes individuales como

var now = DateTime.Now;

now.SetSecond(0);
solidsparrow
fuente
3

Si tiene un DateTime como 2014/02/05 18:19:51 y solo quiere 2014/02/05, puede hacer eso:

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

Agregar. Fecha a su fecha lo establece a medianoche (00:00).

MyDate.Date

Nota El SQL equivalente esCONVERT(DATETIME, CONVERT(DATE, @MyDate))

Lo que hace que este método sea tan bueno es que es rápido de escribir y fácil de leer. Una ventaja es que no hay conversión de cadenas.

Es decir, para establecer la fecha de hoy a las 23:30, use:

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

Por supuesto, puede reemplazar DateTime.Now o MyDate con cualquier fecha que elija.

WonderWorker
fuente
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
fuente
2

Use Date.Addy agregue un New TimeSpancon la nueva hora que desea agregar

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

Cuando construya su DateTimeobjeto, use un constructor que le permita especificar el tiempo:

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

Si ya tiene un DateTimeobjeto y desea cambiar la hora, puede agregar minutos, horas o segundos DateTimeusando 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 cómo tenemos que "guardar" el resultado de cada llamada de método a la myDateTimevariable. Esto se debe a que DateTimees inmutable, y sus métodos simplemente crean nuevas instancias con las horas / minutos / segundos adicionales agregados.

Si necesita agregar horas y minutos (y / o segundos) y al mismo tiempo, puede simplificar el código agregando TimeSpana al original DateTimeen su lugar:

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

Si desea establecer horas / minutos / segundos absolutos, en lugar de agregar a los valores existentes, puede usar el DateTimeconstructor mencionado anteriormente y reutilizar los valores para año / mes / día de antes:

myDateTime = new DateTime(myDateTime.Year, myDateTime.Month, myDateTime.Day,
                          20, 33, 19)                     // 2000-01-01 20:33:19
Jørn Schou-Rode
fuente
Sumar y restar usando los métodos AddXXX
Chris Richner
1

Aquí hay un método que podría usar para hacerlo por usted, úselo de esta manera

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

Aquí está el método, probablemente haya una mejor manera, pero acabo de prepararlo:

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

Acabo de encontrar esta publicación porque tuve un problema similar por el cual quería establecer la hora para un objeto de Entity Framework en MVC que obtiene la fecha de una vista (selector de fecha), por lo que el componente de hora es 00:00:00 pero necesito Es la hora actual. En base a las respuestas en esta publicación, se me ocurrió:

myEntity.FromDate += DateTime.Now.TimeOfDay;
Robar
fuente
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
fuente
1

Puede asignar un valor inicial a un nuevo DateTimevalor de muchas maneras diferentes:

  • Método de extensión

Método de extensión 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);
    }

luego usando ChangeTime:

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.ChangeTime(12, 20, 10);
  • utilizando los métodos Agregar

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.Date.AddHours(12).AddMinutes(20).AddSeconds(10);
  • usando el intervalo de tiempo

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

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

¿Qué tiene de malo el método DateTime.AddSeconds donde puede agregar o restar segundos?

Chris Richner
fuente
No solo eso, sino que no parece que responda la pregunta de todos modos. Sospecho que el OP quiere un DateTime con la misma fecha pero una hora específica, lo que sería relativamente difícil de hacer solo con AddSeconds.
Jon Skeet el
0
  DateTime s;
//s = datevalue
                s = s.AddMilliseconds(10);
                s = s.AddMinutes(10);
                s = s.AddSeconds(10);
                s = s.AddHours(10);

podría agregar valores + ve / -ve en el parámetro.

s.Add(new TimeSpan(1, 1, 1));
Sarre
fuente
@ Jon: comenté la línea. el usuario debe asignar algún valor antes de usar este código.
Saar
@Saar: lo que es más importante, ahora ha agregado las asignaciones a s (excepto la llamada a s.Add (...)).
Jon Skeet el
@ Jon: Aprendí mi lección. Gracias por su amabilidad y tiempo. Lo digo en serio.
Saar
0

¿Eso no soluciona tus problemas?

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

Prefiero esto:

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

        }

Usar así:

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

esto tiene que volver: 2016-06-06 00: 00: 00.000

Ricardo Figueiredo
fuente
-1

La mejor solución es:

currdate.AddMilliseconds(currdate.Millisecond * -1).AddSeconds(currdate.Second * -1).AddMinutes(currdate.Minute * -1).AddHours(currdate.Hour * -1);
Mahesh Alwani
fuente
1
Al principio pensé que esto estaba mal, pero tiene sentido si asigna el resultado a un objeto DateTime. Sin embargo, no es la mejor solución. Requiere que conozca la porción de tiempo actual para hacer los cálculos correctos, mientras toma la porción de fecha de la fecha y agrega que es lo mejor.
ThunderGr
1
Definitivamente no es el "mejor". Lejos de ser legible y con el uso repetitivo de un número mágico.
BartoszKP
-1

Prueba este

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

Aquí hay una manera de gueto, pero 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
fuente
Otra forma de gueto pero un poco más limpia sería jugar con los segundos. por ejemplo, dt.AddSeconds(0-dt.Seconds).AddSeconds(newSecondsValue)pero no lo recomendaría.
mike