question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DateTime vs DateTimeOffset vs long (ticks) for timestamps

See original GitHub issue

We have to decide whether we should use DateTime, DateTimeOffset or long (ticks) for timestamps. Unfortunately, it seems like all of them have certain disadvantages…

Interesting articles:

Some important quotes:

The DateTime structure is suitable for applications that do the following:

  • …, Work with UTC dates and times only, …
  • When saving or sharing DateTime data, UTC should be used and the DateTime value’s Kind property should be set to DateTimeKind.Utc

The DateTimeOffset type includes all of the functionality of the DateTime type along with time zone awareness. This makes it is suitable for applications that do the following:

  • Uniquely and unambiguously identify a single point in time. The DateTimeOffset type can be used to unambiguously define the meaning of “now”, to log transaction times, to log the times of system or application events, and to record file creation and modification times.
  • Note: These uses for DateTimeOffset values are much more common than those for DateTime values. As a result, DateTimeOffset should be considered the default date and time type for application development.

Converting:

For UTC and local DateTime values, the Offset property of the resulting DateTimeOffset value accurately reflects the UTC or local time zone offset.

However, for DateTime values whose Kind property is DateTimeKind.Unspecified, these two conversion methods produce a DateTimeOffset value whose offset is that of the local time zone.

Ifyour application requires that converted DateTime values unambiguously identify a single point in time, you should consider using the DateTimeOffset.UtcDateTime property to handle all DateTimeOffset to DateTime conversions.


This means, DateTime would be possible if we would only use UTC. However, for some reason many developers don’t use DateTime.UtcNow and DateTime.Now properly. While the former correctly returns a UTC timestamp, the latter returns a timestamp for the current timezone on which the host is running - and this of course is wrong for server scenarios.

Since it’s not guaranteed that everybody uses UtcNow, if we would use DateTime, every trace implementation would have to make sure that it either always calls ToUniversalTime() (or only if Kind is “Local”). there’s also DateTimeKind.Unspecified which seems to be handled similar to local - this is the kind you get when you manually create a DateTime object.

DateTimeOffset seems to be more explicit about all of this, however it still uses the local server time zone when you pass a date with kind=Unspecified.

By using DateTime or DateTimeOffset we would need to define some recommendations - e.g. Users should always use UTC, tracer implementations should convert kind=local to UTC, tracer implementations should throw an exception if kind=Unspecified, …


Using long ticks would be an alternative which maybe would make it a bit more obvious for users that they can’t just pass a regular DateTime.Now and instead have to think about the right thing to do. However, I guess you might still run into the same issues if you use DateTime.Now.Ticks or new DateTime(...).Ticks with an unspecified kind. I haven’t yet tested this though.

Other drawbacks of using ticks are that the trace implementations now can’t do any validation and it’s not obvious for users and trace implementations, whether the ticks are UNIX epoch ticks or Windows ticks.

Your opinions?

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:9 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
bhscommented, Aug 29, 2016

@cwe1ss @yurishkuro

While I think it’s fine to use the idiomatic time function per-platform, I feel somewhat strongly that timezones should be avoided in monitoring ingest APIs, except when human-user-facing frontends are involved. I.e., whatever time type we use should support something like epoch microseconds.

0reactions
dawallincommented, Sep 7, 2016

@cwe1ss I have no strong opinion, I have no experience with DateTimeOffset, and as you say, if we choose DateTime, we can change later without breaking the client.
I did some more benchmarks, and the really slow operations are DateTime.Now and .ToUniversalTime() on a DateTime with LocalTime. It shows that you should really try to work with UTC instead of local time.

Read more comments on GitHub >

github_iconTop Results From Across the Web

DateTime vs DateTimeOffset
DateTimeOffset is a representation of instantaneous time (also known as absolute time). By that, I mean a moment in time that is universal ......
Read more >
Compare types related to date and time
The DateTimeOffset structure represents a date and time value, together with an offset that indicates how much that value differs from UTC.
Read more >
4 Common Datetime Mistakes in C# And How to Avoid Them
In C#, Datetime is one of the easiest things to get wrong. Learn about the 4 most common mistakes (plus a bonus mistake)...
Read more >
Date and Time Handling
UTC DateTime is written as timestamp with time zone , Local/Unspecified DateTimes are written as timestamp without time zone . In versions prior...
Read more >
Google.Protobuf.WellKnownTypes.Timestamp
The timestamp contains invalid values; either it is incorrectly normalized or is outside the valid range. Returns. This timestamp as a DateTimeOffset ....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found