2008-12-16 61 views
28

我在C#中使用DateTime来显示时间。构建时间时,每个人都使用哪个日期部分?C#日期时间:什么“日期”使用时,我只使用“时间”?

例如以下是无效的:

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

注意:我不能使用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没有提供将时间跨度转换为一天中某个时间的机制 - 这是有原因的。

+7

您说TimeSpan不存储一天的时间,但DateTime结构有一个名为TimeOfDay的属性,类型是TimeSpan。 – 2010-04-29 15:25:23

+0

请考虑编辑出问题的答案。 – 2016-10-25 16:37:50

回答

23

那么DateTime.MinValue呢?

+0

我喜欢那最好的,而不是硬编码的数字,但增加了MinValue日期的时间跨度。 – 2008-12-16 21:38:32

2

DateTime.Now.TimeOfDay怎么样,并使用TimeSpan

“因为那不存储一天的时间。” - 好吧,如果你认为自午夜以来的时间为TimeSpan,那就行了。

“持续时间”,例如,尖叫TimeSpan

+0

减去两个DateTime会生成一个TimeSpan。 – 2008-12-16 21:19:27

4

鉴于DateTime.TimeOfDay返回TimeSpan,我会使用它。

为什么你不能使用TimeSpan?我不明白你的意见,它不存储一天的时间。

6

TimeSpan当然可以存储一天中的时间 - 您只需将该值作为自午夜以来流逝的时间量来对待,这与我们读取时钟的方式基本相同。

+0

TimeSpan不存储一天的时间。更新了问题,向您说明原因。 – 2008-12-16 21:18:28

1

我建议DateTime.MinValue

3

要显示与当地的文化格式化的时间跨度,只需将其添加到像DateTime.Today日期。类似这样的:

(DateTime.Today + timeSpan).ToString();

由于您的值确实不代表日期,因此最好将其存储为TimeSpan,直到显示它为止。

1

您可以使用字符串文字创建新的DateTime。

字符串字面时间:当创建

DateTime t = new DateTime("01/05/2008T01:00:30"); 

在大多数情况下,:

DateTime t = new DateTime("01:00:30"); 

字符串字面日期:

DateTime t = new DateTime("01/05/2008"); // english format 
DateTime t = new DateTime("05.01.2008"); // german format 

对于日期和时间值的日期时间一个日期时间,我将它设置为DateTime.Now,如果它没有实际设置为其他任何东西。如果您手动实例化DateTime,则应该小心DateTimeKind设置正确,否则可能会导致意外。

5

个人而言,我想创建一个自定义Timestruct包含DateTime实例,并且具有相似的属性,构造等,但不暴露天/月/等等。只需让所有的公共访问者都能通过所包含的实例。然后,您可以简单地将该时代作为private static readonly DateTime字段,并且您选择的值无关紧要,因为它全部包含在自定义结构中。在你的代码的其余部分可以简单地写:

var time = new Time(16, 47, 58); 
0

使用TimeSpan,如果你有TimeZone问题使它成为UTC。

1

我可以建议在某些情况下自定义结构可以吗?它可以有一个Int32支持值(一天有86千万毫秒;这适合于一个Int32)。

有可能获得专用属性:

小时 分 秒 毫秒

你也可以重载运算符,如+, - 等。实现IEquatable,IComparable和其他可能的情况。重载等于,==。重载并覆盖ToString。

您还可以提供更多的方法来构建从DateTime或附加到日期时间等。

8

让我们帮忙谁想要一个时间结构的家伙:

/// <summary> 
/// Time structure 
/// </summary> 
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; 
    } 
} 
0

没有太大的差别比较公认的答案。只是为了实现这个想法。

public class TimeOfDay 
{ 
    public DateTime time; 
    public TimeOfDay(int Hour, int Minute, int Second) 
    { 
     time = DateTime.MinValue.Date.Add(new TimeSpan(Hour, Minute, Second)); 
    } 
}