如何在DateTime中修改时间?

456

我怎样才能仅更改DateTime变量“s”中的时间部分?

DateTime s = some datetime;
29个回答

736

你不能改变一个 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数据库条目而变得“可感知”。


13
s.Date.Add(new TimeSpan(0, 0, 0))也可以使用。在检查两天之间的时间时,可以使用它来将时间设置为零。 - Yogurt The Wise
13
为什么要传入零时间跨度来调用 Add 方法?你的表达式相当于 s.Date,但更冗长。 - Jon Skeet
忘记纠正了,在我把它放进代码后才意识到,用于将其设置为零(最初我正在寻找的内容)。但我只是想展示如何在一行中设置时间,如果不设置为0。 - Yogurt The Wise
4
如果你有两个 DateTime 对象(一个表示日期,另一个表示时间),你可以这样做:var result = date.Date + time.TimeOfDay; - Zachary Yates
2
@ZacharyYates:是的,尽管我认为在那个时候你的模型本来就有问题,而且“时间”不应该是“DateTime”。(当然,我会使用Noda Time,但是...) - Jon Skeet
1
@JonSkeet 同意。只是指出一下,如果有人必须使用无法更改的模型进行工作(就像我今天早些时候所做的那样)。 - Zachary Yates

137

好的,我要开始给出我的建议了,一个扩展方法:

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

7
这与Datetime.Today.Add(time.TimeOfDay)本质上是相同的。这是因为在内部,构造函数除了为日期部分考虑闰年之外,并不进行任何基于日历的修正。也就是说,DateTime是一个类似于Python的datetime模块中的“天真”实现。 - ivan_pozdeev

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

通过这种方式,您可以保留日期,并插入您想要的新小时、分钟和秒钟部分。


@Webleeuw 当然,根据添加的值,可能会出现ArgumentOutOfRangeException的遥远可能性。这里有一个Pex谜题可以证明这一点。 - lifebalance
根据使用情况,如果需要的话还可以使用.AddMilliseconds() - Broots Waymb
@lifebalance,Pex链接已经失效了,您能详细说明一下问题吗? - Benni

56
一个简短的句子。
var date = DateTime.Now.Date.Add(new TimeSpan(4, 30, 0));

将会返回今天日期的时间为4:30:00,用任何日期对象替换DateTime.Now


26

DateTime是一个不可变类型,因此您无法更改它。

但是,您可以创建一个基于先前实例的新DateTime实例。在您的情况下,似乎需要使用Date属性,然后添加表示一天中时间的TimeSpan。

类似于这样:

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

22

如果你已经将时间存储在另一个 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 方法。由于我们使用 dateToUse 变量的 Date 属性,因此我们只获取日期并添加时间跨度。


21

最简单的解决方案:

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

18

您可以以许多不同的方式为新的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);
  • 使用Add方法

DateTime datetime = DateTime.Now; //Your DateTime
datetime = datetime.Date.AddHours(12).AddMinutes(20).AddSeconds(10);
  • 使用时间跨度

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

  • 不错的扩展方法 - Sras
    我原本想说“不错的changetime()例子 :)”,但是我找不到DateTime有ChangeTime方法:(哦,我明白了,你提供了自己的!好吧,可以理解 :) 很遗憾Microsoft没有提供设置时间的函数。 - Zeek2

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

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接