我DateTime
在C#中使用a 来显示时间.在构建时间时,每个人都使用什么日期部分?
例如,以下内容无效,因为没有零日或零日:
// 4:37:58 PM DateTime time = new DateTime(0, 0, 0, 16, 47, 58);
我使用COM的零日期吗?
// 4:37:58 PM DateTime time = new DateTime(1899, 12, 30, 16, 47, 58);
或者也许是SQL Server的?
//4:37:58 PM DateTime time = new DateTime(1900, 1, 1, 16, 47, 58);
我意识到这是随意的,因为我会忽略代码中的日期部分,但是能够使用它仍然是很好的:
DateTime duration = time2 - time1;
我想我喜欢MinValue
DateTime time = DateTime.MinValue.Date.Add(new TimeSpan(16, 47, 58));
注意:我不能使用a TimeSpan
,因为它不会存储当天的时间.我知道的原因是因为没有办法将其内容显示为时间.
也就是说,TimeSpan
记录一段时间,而不是一天中的时间,例如:
TimeSpan t = new TimeSpan(16, 47, 58); t.ToString();
以小时:分钟:秒的格式返回一段时间,例如:
16:47:58
而不是时间:
4:47:58 PM (United States) 04:47:58 nm (South Africa) 4:47:58.MD (Albania) 16:47:58 (Algeria) 04:47:58 ? (Bahrain) PM 4:47:58 (Singapore) ?? 04:47:58 (Taiwan) 04:47:58 PM (Belize) 4:47:58 p.m. (New Zealand) 4:47:58 ?? (Greece) 16.47.58 (Italy) ?? 4:47:58 (Korea) 04:47:58 ?.? (Iran) ??? 04:47:58 (India) 04:47:58 p.m. (Argentina) etc
换句话说,时间跨度和时间之间存在差异.并且还意识到,这TimeSpan
并没有提供将时间跨度转换为一天中的时间的机制 - 这是有原因的.
那么DateTime.MinValue呢?
让我们帮助那些想要时间结构的人:
////// Time structure /// public struct Time : IComparable { private int minuteOfDay; public static Time Midnight = "0:00"; private static int MIN_OF_DAY = 60 * 24; public Time(int minuteOfDay) { if (minuteOfDay >= (60 * 24) || minuteOfDay < 0) throw new ArgumentException("Must be in the range 0-1439", "minuteOfDay"); this.minuteOfDay = minuteOfDay; } public Time(int hour, int minutes) { if (hour < 0 || hour > 23) throw new ArgumentException("Must be in the range 0-23", "hour"); if (minutes < 0 || minutes > 59) throw new ArgumentException("Must be in the range 0-59", "minutes"); minuteOfDay = (hour * 60) + minutes; } #region Operators public static implicit operator Time(string s) { var parts = s.Split(':'); if (parts.Length != 2) throw new ArgumentException("Time must be specified on the form tt:mm"); return new Time(int.Parse(parts[0]), int.Parse(parts[1])); } public static bool operator >(Time t1, Time t2) { return t1.MinuteOfDay > t2.MinuteOfDay; } public static bool operator <(Time t1, Time t2) { return t1.MinuteOfDay < t2.MinuteOfDay; } public static bool operator >=(Time t1, Time t2) { return t1.MinuteOfDay >= t2.MinuteOfDay; } public static bool operator <=(Time t1, Time t2) { return t1.MinuteOfDay <= t2.MinuteOfDay; } public static bool operator ==(Time t1, Time t2) { return t1.GetHashCode() == t2.GetHashCode(); } public static bool operator !=(Time t1, Time t2) { return t1.GetHashCode() != t2.GetHashCode(); } /// Time /// Minutes that remain to /// Time conferred minutes public static Time operator +(Time t, int min) { if (t.minuteOfDay + min < (24 * 60)) { t.minuteOfDay += min; return t; } else { t.minuteOfDay = (t.minuteOfDay + min) % MIN_OF_DAY; return t; } } public static Time operator -(Time t, int min) { if (t.minuteOfDay - min > -1) { t.minuteOfDay -= min; return t; } else { t.minuteOfDay = MIN_OF_DAY + (t.minuteOfDay - min); return t; } } public static TimeSpan operator -(Time t1, Time t2) { return TimeSpan.FromMinutes(Time.Span(t2, t1)); } #endregion public int Hour { get { return (int)(minuteOfDay / 60); } } public int Minutes { get { return minuteOfDay % 60; } } public int MinuteOfDay { get { return minuteOfDay; } } public Time AddHours(int hours) { return this + (hours * 60); } public int CompareTo(Time other) { return this.minuteOfDay.CompareTo(other.minuteOfDay); } #region Overrides public override int GetHashCode() { return minuteOfDay.GetHashCode(); } public override string ToString() { return string.Format("{0}:{1:00}", Hour, Minutes); } #endregion /// /// Safe enumerering - whatever interval applied max days /// /// Start time /// Spring in minutes /// public static IEnumerable Range(Time start, int step) { return Range(start, start, step); } /// /// Safe enumeration - whatever interval applied max days /// public static IEnumerable Range(Time start, Time stop, int step) { int offset = start.MinuteOfDay; for (var i = 0; i < Time.Span(start, stop); i += step) { yield return Time.Midnight + (i + offset); } } /// /// Calculates the number of minutes between t1 and t2 /// public static int Span(Time t1, Time t2) { if (t1 < t2) // same day return t2.MinuteOfDay - t1.MinuteOfDay; else // over midnight return MIN_OF_DAY - t1.MinuteOfDay + t2.MinuteOfDay; } }
TimeSpan当然可以存储一天中的时间 - 您只需要将该值视为自午夜以来经过的时间量,基本上与我们读取时钟的方式相同.
我个人创建一个Time
struct
包含DateTime
实例的自定义,它具有类似的属性,构造函数等,但不会暴露天/月/等.只需将所有公共访问者传递给包含的实例即可.然后你可以简单地将epoch作为一个private static readonly DateTime
字段,并且你选择什么值并不重要,因为它整齐地包含在你的自定义结构中.在其余的代码中可以简单地写:
var time = new Time(16, 47, 58);