Jak zmienić czas w DateTime?

353

Jak mogę zmienić tylko czas w mojej DateTimezmiennej „s”?

DateTime s = some datetime;
Santhosh
źródło

Odpowiedzi:

598

Nie można zmienić wartości DateTime - jest ona niezmienna. Można jednak zmienić zmienną, aby miała nową wartość. Najłatwiejszym sposobem na zmianę tego czasu jest utworzenie TimeSpan z odpowiednim czasem i użycie właściwości DateTime.Date:

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

s będzie teraz tego samego dnia, ale o 10:30.

Zwróć uwagę, że DateTimepomija zmiany czasu letniego, reprezentując „naiwny” czas gregoriański w obu kierunkach (patrz sekcja Uwagi w DateTimedokumentacji ). Jedynymi wyjątkami są : .Nowi .Todaypobierają bieżący czas systemowy, który odzwierciedla te zdarzenia w momencie ich wystąpienia.

Właśnie to zmotywowało mnie do rozpoczęcia projektu Noda Time , który jest teraz gotowy do produkcji. Jego ZonedDateTimetyp jest „świadomy” poprzez połączenie go z tzpozycją bazy danych .

Jon Skeet
źródło
11
s.Date.Add (new TimeSpan (0, 0, 0)) powinien również działać. Używanie go do zerowania czasu podczas sprawdzania między dniami.
Jogurt Mądry
8
@ user295734: Dlaczego miałbyś dzwonić Addpodając zerowy przedział czasu? Twoje wyrażenie jest równoważne s.Date, ale dłuższe ...
Jon Skeet
Zapomniałem go poprawić, uświadomiłem sobie po tym, jak umieściłem go w kodzie, dla ustawienia na zero (czego pierwotnie szukałem). Ale ja tylko próbowałem pokazać, jak uzyskać czas ustawiony w jednej linii, jeśli nie ustawiony na 0.
Jogurt The Wise
3
Jeśli masz 2 DateTimes (jeden na randkę, a drugi na czas), możesz to zrobić:var result = date.Date + time.TimeOfDay;
Zachary Yates,
2
@ZacharyYates: Tak, choć twierdzę, że w tym momencie twój model jest zepsuty i timenie powinien byćDateTime . (Oczywiście użyłbym Nody Time, ale ...)
Jon Skeet
100

Dobra, nurkuję z moją sugestią, metodą przedłużenia:

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

Wtedy zadzwoń:

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

Należy zauważyć, że to rozszerzenie zwraca nowy obiekt daty, więc nie można tego zrobić:

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

Ale możesz to zrobić:

DateTime myDate = DateTime.Now;
myDate = myDate.ChangeTime(10,10,10,0);
joshcomley
źródło
6
Jest to zasadniczo to samo co Datetime.Today.Add(time.TimeOfDay). Jest tak, ponieważ wewnętrznie konstruktor nie dokonuje żadnych korekt opartych na kalendarzu, z wyjątkiem rozliczenia roku przestępnego dla części daty. Tj. DateTimeJest „naiwną” implementacją pod względem datetimemodułu Pythona .
ivan_pozdeev
68
s = s.Date.AddHours(x).AddMinutes(y).AddSeconds(z);

W ten sposób zachowujesz swoją datę, a jednocześnie wstawiasz nowe godziny, minuty i sekundy według własnych upodobań.

Webleeuw
źródło
@Webleeuw Oczywiście zdalna możliwość wyjątku ArgumentOutOfRangeException w zależności od dodanych wartości. Oto puzzle Pex, które to pokazują.
lifebalance
I w zależności od przypadku użycia, może również zrobić w .AddMilliseconds()razie potrzeby.
Broots Waymb
40

jedna wkładka

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

przywróci dzisiejszą datę o godzinie 4:30:00, zastąpię DateTime.Now dowolnym obiektem daty

Carl Woodhouse
źródło
22

DateTime jest niezmiennym typem, więc nie możesz go zmienić .

Można jednak utworzyć nową instancję DateTime na podstawie poprzedniej instancji. W twoim przypadku wygląda na to, że potrzebujesz właściwości Date, a następnie możesz dodać TimeSpan reprezentujący porę dnia.

Coś takiego:

var newDt = s.Date + TimeSpan.FromHours(2);
Mark Seemann
źródło
17

Jeśli masz już czas przechowywany w innym DateTimeobiekcie, możesz użyć tej Addmetody.

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

TimeOfDayNieruchomość jest TimeSpanprzedmiotem i może zostać przekazany do Addmetody. A ponieważ korzystamy z Datewłaściwości dateToUsezmiennej, otrzymujemy tylko datę i dodajemy przedział czasu.

ShaneA
źródło
16

Najprostsze rozwiązanie:

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

A jeśli potrzebujesz określonego formatu daty i godziny:

s = new DateTime(s.Year, s.Month, s.Day, 8, 36, 44).ToString("yyyy-MM-dd h:mm:ss");
Pan Rubix
źródło
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") ) ;

Wykonano: dzisiaj = 9/04/15 00:00:00

Philip
źródło
8

Stało się to w tym poście, gdy szukałem tej samej funkcjonalności, która mogłaby zrobić to, czego chciał facet. Weź pierwotną datę i zastąp część czasu

DateTime dayOpen = DateTime.Parse(processDay.ToShortDateString() + " 05:00 AM");
BlackLarry
źródło
4

Ponieważ DateTimejest to niezmienne, należy utworzyć nową instancję, gdy należy zmienić komponent daty. Niestety nie ma wbudowanej funkcjonalności do ustawiania poszczególnych komponentówDateTime instancji.

Korzystanie z następujących metod rozszerzenia

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

możesz ustawić poszczególne DateTimeelementy, takie jak

var now = DateTime.Now;

now.SetSecond(0);
wróbel
źródło
3

Jeśli masz DateTime, taki jak 2014/02/05 18:19:51 i chcesz tylko 2014/02/05, możesz to zrobić:

_yourDateTime = new DateTime(_yourDateTime.Year, _yourDateTime.Month, _yourDateTime.Day)
Cássio Alan Garcia
źródło
3

Dodanie .Date do daty ustawia ją na północ (00:00).

MyDate.Date

Uwaga Równoważny SQL toCONVERT(DATETIME, CONVERT(DATE, @MyDate))

Tym, co czyni tę metodę tak dobrą, jest to, że można ją szybko pisać i jest łatwa do odczytania. Bonusem jest to, że nie ma konwersji z ciągów.

To znaczy Aby ustawić dzisiejszą datę na 23:30, użyj:

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

Możesz oczywiście zastąpić DateTime.Now lub MyDate dowolną wybraną datą.

WonderWorker
źródło
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
źródło
2

Użyj Date.Addi dodaj New TimeSpannowy czas, który chcesz dodać

DateTime dt = DateTime.Now
dt.Date.Add(new TimeSpan(12,15,00))
Yonatan Tuchinsky
źródło
1

Podczas konstruowania DateTimeobiektu użyj konstruktora, który pozwala określić czas:

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

Jeśli masz już DateTimeobiekt i chcesz zmienić czas, możesz dodać minuty, godziny lub sekundy DateTimeza pomocą prostych metod:

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

Zauważ, jak musimy „zapisać” wynik każdego wywołania metody do myDateTimezmiennej. Wynika to z faktu, że DateTimejest niezmienny, a jego metody po prostu tworzą nowe wystąpienia z dodanymi dodatkowymi godzinami / minutami / sekundami.

Jeśli chcesz dodać godziny i minuty (i / lub sekundy) i jednocześnie, możesz uprościć kod, dodając TimeSpanDateTime zamiast tego oryginał :

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

Jeśli chcesz ustawić bezwzględne godziny / minuty / sekundy, zamiast dodawać do istniejących wartości, możesz użyć wyżej wspomnianego DateTimekonstruktora i ponownie użyć wartości dla roku / miesiąca / dnia wcześniej:

myDateTime = new DateTime(myDateTime.Year, myDateTime.Month, myDateTime.Day,
                          20, 33, 19)                     // 2000-01-01 20:33:19
Jørn Schou-Rode
źródło
Dodawaj i odejmuj za pomocą metod AddXXX
Chris Richner,
1

Oto metoda, której możesz użyć, aby zrobić to za Ciebie, użyj jej w ten sposób

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

Oto metoda, prawdopodobnie jest lepszy sposób, ale właśnie to wymyśliłem:

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
źródło
1

Właśnie natrafiłem na ten post, ponieważ miałem podobny problem, w którym chciałem ustawić czas dla obiektu Entity Framework w MVC, który pobiera datę z widoku (datepicker), więc komponent czasu to 00:00:00, ale potrzebuję to aktualny czas. Na podstawie odpowiedzi w tym poście wymyśliłem:

myEntity.FromDate += DateTime.Now.TimeOfDay;
Obrabować
źródło
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();
Paweł Cioch
źródło
1

Możesz przypisać wartość początkową do nowej DateTimewartości na wiele różnych sposobów:

  • Metoda przedłużenia

Metoda przedłużenia 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);
    }

następnie używając ChangeTime:

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.ChangeTime(12, 20, 10);
  • za pomocą metod Dodaj

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.Date.AddHours(12).AddMinutes(20).AddSeconds(10);
  • za pomocą przedziału czasu

    DateTime datetime = DateTime.Now; //Your DateTime
    datetime = datetime.Date.Add(new TimeSpan(12, 20, 10));
  • przy użyciu wartości początkowej

    DateTime datetime = DateTime.Now;
    datetime = new DateTime(datetime.Year, datetime.Month, datetime.Day, 12, 20, 10);
Reza Jenabi
źródło
0

Co jest złego w metodzie DateTime.AddSeconds, w której można dodawać lub odejmować sekundy?

Chris Richner
źródło
Nie tylko to, ale i tak nie brzmi to tak, jakby odpowiadało na pytanie. Podejrzewam, że OP chce DateTime z tą samą datą, ale o określonej godzinie - co byłoby stosunkowo trudne do wykonania przy użyciu AddSeconds.
Jon Skeet,
0
  DateTime s;
//s = datevalue
                s = s.AddMilliseconds(10);
                s = s.AddMinutes(10);
                s = s.AddSeconds(10);
                s = s.AddHours(10);

możesz dodać wartości + ve / -ve w parametrze.

s.Add(new TimeSpan(1, 1, 1));
Saar
źródło
@Jon: Skomentowałem linię. użytkownik musi przypisać pewną wartość przed użyciem tego kodu.
Saar,
@ Saar: Co ważniejsze, teraz dodałeś przypisania z powrotem do s (z wyjątkiem połączenia z s.Add (...)).
Jon Skeet,
@Jon: Nauczyłem się mojej lekcji. Dziękuję za życzliwość i czas. Naprawdę to mam na myśli.
Saar,
0

Czy to nie rozwiązuje twoich problemów?

Dateime dt = DateTime.Now;
dt = dt.AddSeconds(10);
Naveed Butt
źródło
0

Wolę to:

DateTime s = //get some datetime;
s = new DateTime(s.Year, s.Month,s.Day,s.Hour,s.Minute,0);
Andrzej
źródło
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;

        }

Użyj w ten sposób:

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

to musi zwrócić: 2016-06-06 00: 00: 00.000

Ricardo Figueiredo
źródło
-1

Najlepszym rozwiązaniem jest:

currdate.AddMilliseconds(currdate.Millisecond * -1).AddSeconds(currdate.Second * -1).AddMinutes(currdate.Minute * -1).AddHours(currdate.Hour * -1);
Mahesh Alwani
źródło
1
Na początku myślałem, że to źle, ale ma sens, jeśli przypiszesz wynik do obiektu DateTime. Nie jest to jednak najlepsze rozwiązanie. Wymaga znajomości aktualnej części czasu w celu wykonania poprawnych obliczeń, przy uwzględnieniu części daty i dodaniu najlepszej.
ThunderGr
1
Zdecydowanie nie „najlepszy”. Dalekie od czytelnego i powtarzalnego używania magicznej liczby.
BartoszKP,
-1

Spróbuj tego

var NewDate = Convert.ToDateTime(DateTime.Now.ToString("dd/MMM/yyyy")+" "+"10:15 PM")/*Add your time here*/;
Vicky
źródło
-5

tutaj jest getto, ale działa :)

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
źródło
Innym sposobem getta, ale nieco czystszym, byłoby po prostu grać sekundami. np. dt.AddSeconds(0-dt.Seconds).AddSeconds(newSecondsValue)ale nie poleciłbym tego.
mike