.NET Framework 没有本机 Time 数据类型来表示一天中的某个时间。您必须在以下三个选项之一之间做出决定:
选项 1
使用DateTime 类型,并忽略日期部分。为您的应用程序选择一个超出正常值范围的日期。我通常使用0001-01-01,可以方便地使用DateTime.MinValue。
如果您从字符串中解析时间,最简单的方法是使用DateTimeStyles.NoCurrentDateDefault 选项。如果没有这个选项,它将使用 今天的 日期而不是最小日期。
DateTime myTime = DateTime.Parse("12:34", CultureInfo.InvariantCulture,
DateTimeStyles.NoCurrentDateDefault);
// Result: 0001-01-01 12:34:00
当然,如果您喜欢使用今天的日期,也可以这样做。我只是认为这会混淆问题,因为您可能希望将其完全应用于其他日期。
请注意,一旦有了DateTime 值,您就可以使用.TimeOfDay 属性来获取时间部分,表示为TimeSpan,这会导致选项2...
选项 2
使用TimeSpan 类型,但在解释时要小心。了解TimeSpan 首先是一种表示经过的持续时间的类型,而不是一天中的某个时间。这意味着它可以存储超过 24 小时,并且它还可以存储 负 值来表示时间倒退。
当您将其用作一天中的时间时,您可能倾向于将其视为“自午夜以来经过的时间”。但是,这会给您带来麻烦,因为在当地时区有些日子不存在午夜。
例如,October 20th 2013 in Brazil 由于夏令时在凌晨 1:00 开始。因此,这一天的 TimeSpan 和 8:00 实际上从 1:00 开始只过去了 7 个小时,而不是从午夜开始过去了 8 个小时。
即使在美国,对于使用夏令时的地方,这个值也会产生误导。例如,November 3rd 2013 in Los Angeles 在 DST 回滚时有一个重复的小时。因此,这一天的 TimeSpan 和 8:00 实际上自午夜以来已经过去了 9 小时。
因此,如果您使用此选项,请注意将其视为与时钟匹配的代表时间值,而不是“自午夜以来经过的时间”。
您可以使用以下代码直接从字符串中获取它:
TimeSpan myTime = TimeSpan.Parse("12:34", CultureInfo.InvariantCulture);
选项 3
使用具有真正“时间”类型的库。您可以在 Noda Time 中找到它,它为在 .NET 中处理日期和时间提供了一个非常更好的 API。
表示“一天中的时间”的类型称为LocalTime,您可以从这样的字符串中获取一个:
var pattern = LocalTimePattern.CreateWithInvariantCulture("HH:mm");
LocalTime myTime = pattern.Parse("12:34").Value;
由于您的问题显示您正在使用time and attendance 数据,因此我强烈建议您使用Noda Time 来满足您的所有日期和时间需求。它会迫使你更多地思考你正在做的事情。在此过程中,您将避免内置日期/时间类型可能带来的陷阱。
如果您在数据库(例如 SQL 服务器)中存储 Time 类型,则在 .Net 中将转换为 TimeSpan。因此,如果您使用此选项,则需要将 LocalTime 转换为 TimeSpan,如下所示:
TimeSpan ts = new TimeSpan(myTime.TickOfDay);