วิธีการเปลี่ยนเวลาใน DateTime


353

ฉันจะเปลี่ยนเฉพาะเวลาในDateTimeตัวแปร "s" ของฉันได้อย่างไร

DateTime s = some datetime;

คำตอบ:


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)) ควรทำงานเช่นกัน ใช้เพื่อลบล้างเวลาในการตรวจสอบระหว่างวัน
โยเกิร์ต The Wise

8
@ user295734: เหตุใดคุณจึงโทรหาAddศูนย์โดยให้เวลาเป็นศูนย์ การแสดงออกของคุณเทียบเท่าs.Dateแต่นานกว่า ...
Jon Skeet

ลืมที่จะแก้ไขให้ถูกต้องรับรู้หลังจากที่ฉันใส่ไว้ในรหัสเพื่อตั้งค่าเป็นศูนย์ แต่ฉันแค่พยายามแสดงวิธีตั้งเวลาให้เป็นหนึ่งบรรทัดหากไม่ได้ตั้งไว้ที่ 0
โยเกิร์ต The Wise

3
หากคุณมี 2 DateTimeวิ (หนึ่งสำหรับวันที่และหนึ่งสำหรับเวลา) คุณสามารถทำสิ่งนี้:var result = date.Date + time.TimeOfDay;
Zachary Yates

2
@ZacharyYates: ใช่แม้ว่าฉันเถียงว่าที่จุดว่ารูปแบบของคุณเสียจะเริ่มต้นด้วยและไม่ควรจะเป็นtime DateTime(ฉันต้องการใช้ Noda Time แน่นอน แต่ ... )
Jon Skeet

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

6
Datetime.Today.Add(time.TimeOfDay)นี้เป็นหลักเช่นเดียวกับ นั่นเป็นเพราะภายในตัวสร้างไม่ได้ทำการแก้ไขตามปฏิทินใด ๆ ยกเว้นการบัญชีสำหรับปีอธิกสุรทินสำหรับส่วนวันที่ Ie DateTimeเป็นการใช้งานแบบ "ไร้เดียงสา" ในแง่ของdatetimeโมดูลของ Python
ivan_pozdeev

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

ด้วยวิธีนี้คุณจะรักษาวันที่ของคุณในขณะที่แทรกชั่วโมงนาทีและวินาทีใหม่ตามที่คุณต้องการ


@ Webleeuw แน่นอนความเป็นไปได้ระยะไกลของArgumentOutOfRangeExceptionขึ้นอยู่กับค่าที่เพิ่มเข้ามา นี่คือปริศนาPexที่แสดงสิ่งนี้
lifebalance

และขึ้นอยู่กับกรณีการใช้งานยังสามารถทำได้.AddMilliseconds()ถ้าจำเป็น
Broots Waymb

40

หนึ่งในสายการบิน

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

จะนำวันที่กลับมาในปัจจุบันด้วยเวลา 4:30:00 แทนที่ DateTime ขณะนี้มีวัตถุวันที่ใด ๆ


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ตัวแปรที่เราได้รับเพียงวันที่และเพิ่มช่วงเวลา


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

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

3

หากคุณมี DateTime เช่น 2014/02/05 18:19:51 และต้องการเพียง 2014/02/05 คุณสามารถทำได้:

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

3

การเพิ่ม. Date to date ของคุณตั้งค่าเป็นเที่ยงคืน (00:00)

MyDate.Date

หมายเหตุ SQL ที่เท่าเทียมกันคือCONVERT(DATETIME, CONVERT(DATE, @MyDate))

สิ่งที่ทำให้วิธีการนี้ดีมากคือมีทั้งแบบรวดเร็วและอ่านง่าย โบนัสคือไม่มีการแปลงจากสตริง

เช่นหากต้องการตั้งวันที่วันนี้เป็น 23:30 ให้ใช้:

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

แน่นอนคุณสามารถแทนที่ DateTime ตอนนี้หรือ MyDate ด้วยวันที่คุณเลือก


3

ที่จริงแล้วคุณไม่สามารถเปลี่ยนเวลาได้เมื่อสร้างแล้ว แต่คุณสามารถสร้างมันได้อย่างง่ายดายด้วย Constructor มากมาย: https://docs.microsoft.com/en-us/dotnet/api/system.datetime.-ctor?view=netframework-4.7.2

ตัวอย่างเช่นหากคุณต้องการสร้างวินาทีเปลี่ยนเวลา DateTime คุณสามารถทำสิ่งนี้:

DateTime now = DateTime.Now;
DateTime secondschanged = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, yourseconds);


2

ใช้Date.Addและเพิ่ม a 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

หากคุณต้องการตั้งค่าชั่วโมง / นาที / วินาทีแบบสัมบูรณ์แทนที่จะเพิ่มไปยังค่าที่มีอยู่คุณสามารถใช้DateTimeConstructor ดังกล่าวและนำค่าใหม่มาใช้สำหรับปี / เดือน / วันจากก่อนหน้านี้:

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

เพิ่มและลบโดยใช้วิธีใดวิธี AddXXX
คริส 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
        );
}

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

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);
  • ใช้วิธีการเพิ่ม

    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
Jon Skeet

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

@ จอน: ฉันแสดงความคิดเห็นบรรทัด ผู้ใช้จำเป็นต้องกำหนดค่าบางอย่างก่อนที่จะใช้รหัสนี้
Saar

@Saar: ที่สำคัญคุณได้ในขณะนี้ได้เพิ่มการมอบหมายงานกลับไป s (ยกเว้นการเรียกร้องให้ s.Add ( ... ))
Jon Skeet

@ จอน: ฉันเรียนรู้บทเรียนของฉัน ขอบคุณสำหรับความมีน้ำใจและเวลาของคุณ ฉันหมายถึงมันจริงๆ
Saar



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


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

อีกวิธีหนึ่งสลัม แต่ทำความสะอาดเล็กน้อยจะเพียงแค่เล่นกับวินาที เช่นdt.AddSeconds(0-dt.Seconds).AddSeconds(newSecondsValue)แต่ไม่แนะนำ
ไมค์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.