在我们的C#项目中,我们需要表示一个没有时间的日期。我知道存在DateTime,但是它也包含一天中的某个时间。我想明确指出某些变量和方法参数是基于日期的。因此,我不能使用该DateTime.Date
属性
解决此问题的标准方法是什么?我当然不是第一个遇到这个问题的人吗?为什么Date
C#中没有课程?
是否有人使用struct以及在DateTime上使用一些扩展方法以及实现一些运算符(例如==和<,>)实现了一个不错的实现?
在我们的C#项目中,我们需要表示一个没有时间的日期。我知道存在DateTime,但是它也包含一天中的某个时间。我想明确指出某些变量和方法参数是基于日期的。因此,我不能使用该DateTime.Date
属性
解决此问题的标准方法是什么?我当然不是第一个遇到这个问题的人吗?为什么Date
C#中没有课程?
是否有人使用struct以及在DateTime上使用一些扩展方法以及实现一些运算符(例如==和<,>)实现了一个不错的实现?
Answers:
请允许我为这个经典问题添加更新:
乔恩·斯凯特(Jon Skeet)的Noda Time库现在已经相当成熟,并且具有称为的仅日期类型LocalDate
。(在这种情况下,本地是指某人的本地,而不一定是运行代码的计算机的本地。)
Date
通过corefxlab项目,建议将仅日期类型称为.NET Core 。您将在System.Time
包中找到它,以及TimeOfDay
类型和对现有类型的几种扩展方法。
我已经对这个问题进行了深入的研究,因此,我还将分享几种使用这些类型的必要性的原因:
仅日期和午夜日期之间存在逻辑上的差异。
并非每个本地日在每个时区都有一个午夜。示例:巴西的春季夏令时过渡将时钟从11:59:59移至01:00:00。
日期时间始终是指一天中的特定时间,而仅日期可能是指一天的开始,一天的结束或一天的整个范围。
如果未非常仔细地观察时区,则将时间附加到日期可能导致日期更改,因为值是从一个环境传递到另一个环境的。这通常发生在JavaScript中(其Date
对象实际上是一个日期和时间),但是也很容易在.NET中发生,或者在JavaScript和.NET之间传递数据时进行序列化。
DateTime
使用XML或JSON(及其他)进行序列化将始终包含时间,即使这并不重要。这非常令人困惑,尤其是考虑到出生日期和周年纪念日等与时间无关的事情。
从体系结构上讲,它DateTime
是DDD的 价值对象,但它在以下几种方面违反了“ 单一负责任原则”:
它设计为日期+时间类型,但通常仅用作日期(忽略时间)或仅用作日期时间(忽略日期)。(TimeSpan
通常也用于一天中的时间,但这是另一个主题。)
DateTimeKind
附加到.Kind
属性的值将单个类型分成三个类型。该Unspecified
类型实际上是结构的原始意图,应以这种方式使用。该Utc
种对齐专门与UTC值,和Local
那种对齐与环境的本地时区的价值。
带有单独的种类标记的问题在于,每次使用时DateTime
,都应检查.Kind
以确定采取哪种行为。框架方法都可以做到这一点,但是其他方法经常会忘记。这确实是违反SRP的,因为类型现在有两个不同的更改原因(值和种类)。
这两个导致API使用情况会编译,但通常是荒谬的,或者是由副作用引起的奇怪情况。考虑:
// nonsensical, caused by mixing types
DateTime dt = DateTime.Today - TimeSpan.FromHours(3); // when on today??
// strange edge cases, caused by impact of Kind
var london = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
var paris = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time");
var dt = new DateTime(2016, 3, 27, 2, 0, 0); // unspecified kind
var delta = paris.GetUtcOffset(dt) - london.GetUtcOffset(dt); // side effect!
Console.WriteLine(delta.TotalHours); // 0, when should be 1 !!!
总而言之,虽然a DateTime
只能用于日期,但只有在每个使用它的地方都非常小心地忽略时间,并且也非常小心不要尝试与UTC或其他时间相互转换时,才应使用a时区。
System.Time.Date
在.NET框架中使用:/
System.Time
像其他任何软件包一样拉入。它还不是“官方”的。
我怀疑没有专用的纯Date
类,因为您已经DateTime
可以使用它。有Date
会导致重复和混乱。
如果要使用标准方法,请查看DateTime.Date
属性,该属性仅给出a的日期部分,DateTime
其时间值设置为午夜12:00:00(00:00:00)。
我已经通过电子邮件发送给refsrcfeedback@microsoft.com,这就是他们的答案
Marcos,这不是问这类问题的好地方。尝试http://stackoverflow.com 简短的答案是,您需要一个模型来表示一个时间点,而DateTime做到了,这是实践中最有用的方案。人类使用两个概念(日期和时间)来标记时间点这一事实是任意的,并且对区分没有用。
仅在需要的地方解耦,不要仅仅为了盲目的做事。这样想:将DateTime分为Date和Time可以解决什么问题?您会遇到哪些现在没有的问题?提示:如果您查看整个.NET框架中的DateTime用法:http : //referencesource.microsoft.com/#mscorlib/system/datetime.cs#df6b1eba7461813b#references 您将看到大多数方法都从该方法返回的。如果没有类似DateTime的概念,则必须使用out参数或元组返回一对Date和Time。
HTH,基里尔·奥森科夫
在我的电子邮件中,我问是否是因为DateTime使用TimeZoneInfo来获取机器的时间-在Now propriety中。所以我要说这是因为“业务规则”太“耦合”了,他们向我承认了这一点。
SpaceTime
堂课!嘿,根据爱因斯坦的说法,时间和空间紧密相连,所以我们也不需要区分它们,对吗?(!!!!!!!!!!!)我有点新的C#,但我不得不说,这是从VB.NET来一个雷区在哪里,简单地说,date
,Today()
,now
,等没有DateTime
前缀的垃圾,无关于。(这些分号以及这种区分大小写的方法肯定令人讨厌!现在就开枪吧!)
Date
类型,结果必须是类型Date
-如果它是Date
类型,则结果应作为字符串而没有时间。例如,Delphi也将Date作为DateTime,但是typeinfo对于Date和DateTime是不同的。
我为需要简单日期的时间创建了一个简单的Date结构,而无需担心时间部分,时区,本地vs.utc等。
请允许我推测:也许是因为直到SQL Server 2008为止SQL中都没有Date数据类型,所以很难将其存储在SQL Server中?毕竟这是Microsoft产品吗?
谁知道为什么会这样。.NET框架中有许多错误的设计决策。但是,我认为这是一个很小的问题。您始终可以忽略时间部分,因此,即使某些代码确实决定让DateTime引用的不只是日期,所关心的代码也应该只查看日期部分。另外,您可以创建一个仅表示日期的新类型,并使用DateTime中的函数进行繁重的工作(计算)。
总有一个DateTime.Date
属性会切断的时间部分DateTime
。也许您可以将DateTime封装或包装在您自己的Date类型中。
关于这个问题,为什么呢,我想您不得不问Anders Heljsberg。
是的,System.DateTime也是密封的。我见过一些人通过创建自定义类来玩游戏,以获取前面的文章中提到的时间的字符串值,例如:
class CustomDate
{
public DateTime Date { get; set; }
public bool IsTimeOnly { get; private set; }
public CustomDate(bool isTimeOnly)
{
this.IsTimeOnly = isTimeOnly;
}
public string GetValue()
{
if (IsTimeOnly)
{
return Date.ToShortTimeString();
}
else
{
return Date.ToString();
}
}
}
这可能是不必要的,因为您可以轻松地从普通的旧DateTime类型中提取GetShortTimeString而无需新类
如果您使用Date或Today属性从DateTime对象中仅获取日期部分。
DateTime today = DateTime.Today;
DateTime yesterday = DateTime.Now.AddDays(-1).Date;
然后,仅将时间部分设置为午夜,您将获得日期部分。
DateTime
产生哪些具体问题?