简体   繁体   中英

What's best practice to represent a Time object in C#?

I have a Time column in a database table. The date is not important, we just want a time in the day. What type would be best to represent it in C#? I was going to use a DateTime, but I don't like the idea of having a date.

While the other answers are mostly correct that a TimeSpan is the only built-in type that will work, it's important to realize that there are distinct differences between an "elapsed measurement of time" and a "time of day".

  • The most obvious difference is that a time of day must be less than 24 hours. A TimeSpan object can cover much more than that.

  • Another difference is that a TimeSpan type can be negative . This represents moving backwards in time. A negative value would be meaningless as a time-of-day.

  • And finally, a time-of-day includes any concept of daylight saving time that might apply to the time zone in which it was taken. So you can't think of it as "elapsed time since midnight".

    • If it's the day of the spring-forward DST transition (in the USA), then a value of 4:00 has only elapsed 3 hours since midnight.
    • If it's the day of the fall-back DST transition (in the USA), then a value of 4:00 has actually elapsed 5 hours since midnight.
    • And since DST is different all over the world, it's entirely possible that midnight doesn't even exist, or exists twice. This happens in places like Brazil, and others.

So if you use TimeSpan as a time-of-day, you need to be aware of these issues. .NET doesn't have a built-in type for a time-of-day, so this is an acceptable compromise , even though it's in violation of it's own design.

Even the .NET Framework itself makes this compromise. For example:

  • The DateTime class has a TimeOfDay property that returns a TimeSpan .
  • If you have time type in SQL Server, it will be a TimeSpan when returned through the .NET SQL Client.

The MSDN Reference Documentation has this to say about the TimeSpan type:

The TimeSpan structure can also be used to represent the time of day, but only if the time is unrelated to a particular date. Otherwise, the DateTime or DateTimeOffset structure should be used instead.

That is basically another way of saying what I covered in my third point above about DST.

However, if you are not interested in making compromises in your design and would like a real time-of-day type, then take a look at the Noda Time library.

  • There is the LocalTime type, which represents a time of day. This is the direct answer to the question that was asked.
  • There is a Duration type, which represents an elapsed measure of time.
  • There is also a Period type, which represents a positional movement on a calendar - which is something else that TimeSpan can't do. For example, "3 years and 5 months" would be a Period value.
  • There is also an Offset type, which is similar to a Duration , but is used as an offset from UTC for time zones. It has a range limited to that purpose.

While some could say that TimeSpan is more versatile since it can handle all of these, the truth is that it allows you to get into trouble. By separating the types, you get safety and consistency.

Alternatively, you may consider the System.Time package available from Microsoft as part of CoreFX Lab . This package contains implementations of a time-only type called Time , and a date-only type called Date . You will need to use the dotnet-corefxlab MyGet feed to import this package.

您可以使用TimeSpan结构来表示.NET中的时间。

Jon Skeet's been working on something called Noda Time , maybe this will help.

Skeet's post on why it may be right for you: What's Wrong with DateTime Anyway?

You could try something like this

TimeSpan ts = DateTime.Now.TimeOfDay

Where you are applying the time property of the DateTime object and just use that.

使用Timespan表示从午夜到时间的时间跨度。

I would use a TimeSpan to represent this, with the TimeSpan being the span of time since midnight. This correlates to DateTime's TimeOfDay property in the framework.

We actually rolled our own Time class. The issue we ran into is TimeSpan has no knowledge of timezone offsets which we still needed. So We created a TimeSpanOffset class. Kind of analogous to the DateTimeOffset class. If timezone is not important than I would definitely stick with the TimeSpan.

鉴于此问题是我刚刚进行的 Google 搜索中的最高结果,可能值得一提的是,在 .NET 6 即将发布(目前定于 2021 年 11 月 9 日)之后,该问题的正确答案可能是新的TimeOnly结构

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM