One of the big reasons to use dotnetcore is to be able to run on Linux. Please consider adding functions to output datetime to epoch format which is the standard on Linux environments. These suggestions may be a little off but they seem to make sense to me.
Add a UnixTime DateTimeKind enum value
https://msdn.microsoft.com/en-us/library/shx7s921(v=vs.110).aspx
DateTimeOffset can output in unix time using a special function already
https://msdn.microsoft.com/en-us/library/system.datetimeoffset.tounixtimeseconds(v=vs.110).aspx
But it has no constructor allowing you to initialize a DateTimeOffset from an int64 and DateTimeKind enum. Consider adding this
https://msdn.microsoft.com/en-us/library/system.datetimeoffset(v=vs.110).aspx
DateTime has a constuctor taking int64 and DateTimeKind, but the int64 represents ticks instead of seconds. Consider setting the behavior for DateTime(int64, DateTimeKind (of UnixTime)) to initialize a DateTime using int64 as seconds instead of ticks, or add a FromUnixTime(int64 seconds) method if you don't want to confuse the payload of the int64 parameter.
https://msdn.microsoft.com/en-us/library/w0d47c9c(v=vs.110).aspx.
Consider adding a ToUnixTime method to the DateTime structure.
Consider adding support for an "e" string in ToString, for epoch format, https://msdn.microsoft.com/en-us/library/system.datetimeoffset(v=vs.110).aspx
Add a UnixTime DateTimeKind enum value
I don't think this is good idea. DateTimeKind is already confusing, adding UnixTime to it will increase this confusion. also if we added UnixTime, what this means, it is UTC time or local time? we recommend to use DateTimeOffset if you want to avoid the confusion of DateTimeKind.
I'll look at the rest of your suggestions but I would like to see what exactly the scenario that you are running to cannot achieve it today. writing some code examples will be very helpful here.
That's the problem - there are hundreds of sets of code people have written all over the net solving 'how do you convert to unix time in .net'. I've found a couple different implementations of functions for it in my company's codebase, along with inline calls like - new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds. Google 'how do you convert to unix time in .net' and you get 354,000 results :) http://stackoverflow.com/questions/249760/how-to-convert-a-unix-timestamp-to-datetime-and-vice-versa - I forgot about Java timestamps too
Use cases I've needed this (we're not in .net core yet):
Use cases coming up:
DateTime IS confusing. But at least in my case it's the local and unspecified times that are the confusing parts. Unix time and java time are always in UTC, so their values would always match DateTimeKind.UTC when converted back and forth.
We don't have any problem doing the conversion. We do it lots of ways already unfortunately, private methods defined in a single class, public static methods, extension methods. I'm sure many shops are similar. It just seems to make sense to have _native_ support for the native time format when running c# on linux. Local time as a concept doesn't make much sense on linux.
@brian-white thanks for your quick response. my point was to avoid playing with the DateTimeKind but we can provide some helpers to easily create Unix DateTime. Something like DateTime.LinuxEpoch, GetLinuxDateTime(int64)...etc.
so I am not objecting the idea of the support but I am objecting to miss up with DateTimeKind :-)
That's fine with me. I had specific suggestions but my real goal is just that there is some 'official' way of doing the conversion to avoid people copy/pasting code from stackoverflow to solve it.
I'm curious... what would be the behavior of DateTimeKind.Local in c# on linux where local is actually unix time? Would it behave like UTC in that case?
I'm curious... what would be the behavior of DateTimeKind.Local in c# on linux where local is actually unix time? Would it behave like UTC in that case?
The behavior on Linux will be as the behavior on Windows. I mean it wil be the time on the locale time zone of the system. fo rexample, if you call DateTime.Now, we get the system time in UTC and then convert it to the local time using the system time zone setting.
Agreed about DateTimeKind. Leave it alone. Besides, it wouldn't be possible to add another kind, as we only have two bits to store it in the DateTime structure, and there are already four possible values (the three in the enumeration, and the fourth "hidden" kind).
We actually already do have FromUnixTimeMilliseconds and FromUnixTimeSeconds on the DateTimeOffset type. They aren't on DateTime at the moment, but you can easily do:
DateTime dt = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).UtcDateTime;
// or
DateTime dt = DateTimeOffset.FromUnixTimeSeconds(timestamp).UtcDateTime;
Adding these to DateTime is certainly _possible_, but IMHO it shouldn't be done because it it would further encourage use of DateTime for a scenario that more closely matches DateTimeOffset. I could see people easily making a mistake of comparing a DateTime generated in this way with a local time, such from as DateTime.Now. At least if they have to go out of their way to use DateTimeOffset, then there's an implied higher degree of understanding.
The same argument can be made for using the code from StackOverflow. In fact, if you look further down in that post, there's already a good answer showing the use of this technique.
Lastly, I'll add that composing either a DateTimeOffset or a DateTime using both a Unix Timestamp and a DateTimeKind isn't appropriate. A Unix Timestamp is _always_ in terms of UTC, and thus the resulting DateTimeOffset should always have a zero offset (unless it's subsequently adjusted). If DateTime were to have these methods, the result would _always_ have DateTimeKind.Utc.
I agree with @mj1856 regarding we need to promote DateTimeOffset and avoid using DateTime in such scenarios.
@brian-white looks the concerned scenarios already addressed by using DateTimeOffset. do you think there is any missing scenario need to be addressed here considering asking people to use DateTimeOffset?
I am closing this issue but please feel free to re-open if you have any follow up related issue. thanks.
What is the vision for these two different constructs for dealing with datetime? I don't get why they'd have significantly different features. DateTimeOffset was just DateTime with the +/- hours from UTC, now it's the 'cool' struct and DateTime is the 'lame' one. But 95% of legacy code only uses the lame one. I don't believe the sql server datatypes diverge in such a way.
In other words, rather than encourage
DateTime dt = DateTimeOffset.FromUnixTimeSeconds(timestamp).UtcDateTime;
Do you really want to encourage just using the offset structure?
DateTimeOff dt = DateTimeOffset.FromUnixTimeSeconds(timestamp);
that is right, we encourage to use the DateTimeOffset structure as possible to avoid the confusion regarding the local, UTC and unspecified type.
We still support DateTime because it is used widely by the applications and we cannot obsolete it. and this is the point that @mj1856 raised which is adding more support to DateTime will appear as we encourage people to use it.
To clarify the vision in entirety:
DateTime with DateTimeKind.UtcDateTimeOffset with an offset of +00:00DateTimeOffset.UtcNow instead of DateTime.UtcNowDateTime with DateTimeKind.LocalDateTimeOffset with the correct applicable local offsetDateTimeOffset.Now instead of DateTime.NowDateTime with DateTimeKind.Unspecified, representing a date and a timeDateTime.ParseExact("2016-12-31 01:23:45", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)DateTime with DateTimeKind.Unspecified, representing a date onlyDateTime with DateTimeKind.Unspecified and the time at midnight. Be careful to omit time during serialization, and avoid time math such as adding an hour.Date type from the _System.Time_ nuget package in corefxlab.DateTime with DateTimeKind.Unspecified, representing a time-of-day onlyDateTime with DateTimeKind.Unspecified, ignoring the date portion. Substitute TimeSpan when necessary, such as storing in SQL Server, but watch out for differences in parsing behavior between TimeSpan and DateTime. Be careful to omit the date during serialization, and avoid date math such as adding a month.TimeOfDay type from the _System.Time_ nuget package in corefxlab.TimeSpan representing a time-of-dayTimeOfDay.TimeSpan representing elapsed timePlease add function From/To UnixTime into DateTime like in DateTimeOffset too
@Thaina please read @mj1856 comments on this issue why we don't prefer adding these to DateTime. Without adding these APIs to DateTime, you can still achieve the same functionality using the DateTimeOffset. If you really want it, you may consider writing extension methods for DateTime which can be implemented using DateTimeOffset.
If one were to add them...
DateTime.FromUnixTime... would have to always result in a DateTime with DateTimeKind.UtcdateTimeInstance.ToUnixTime... would have to throw an exception if the kind was DateTimeKind.Unspecified, and do a ToUniversalTime internally if the kind was DateTimeKind.Local.Given those edge cases, especially the surprise of a possible exception, it seems best IMHO to keep them on DateTimeOffset.
I'd just be happy to have a DateTime.UnixEpoch readonly field so I don't have to use new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) anymore.
@TylerBrinkley please go ahead and log a new API proposal for exposing DateTime.UnixEpoc and we can proceed with that. I think it is good to have it.
@tarekgh just created the proposal dotnet/corefx#24449 to add DateTime.UnixEpoch and DateTimeOffset.UnixEpoch.
I'll revise my previous comment. As long as the behaviors I described are implemented, I'm ok with these on DateTime. The risk that they pose is the same that DateTime already has, which is that subtracting two DateTime values ignores the Kind. Coming from a Unix epoch doesn't necessarily exacerbate this issue, any more than coming from any other UTC-based input does. If anything, it does one better in that we can be sure that DateTimeKind.Utc is set correctly.
Most helpful comment
I'd just be happy to have a
DateTime.UnixEpochreadonly field so I don't have to usenew DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)anymore.