-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deconstruct for DateTime, DateTimeOffset, DateOnly, and TimeOnly #24601
Comments
I would be happy to get a year , month , day at the same time but won't it make confusion between (hour, minute, second) ? Isn't enough to set GetDatePart public? |
@aobatact You can have Deconstuct overloads for example you can add
but if you only care for the TimeOfDay parts then an additional method is needed such as
and use it as
|
I know that I can have ovreloads to it. My question is how the user know what values are deconstructed. As for other types that can Deconstruct like ValueTuple, Tuple, KeyValuePair, etc... , it is obvious which and what order they are deconsructed (they are deconstructing all the fields), but why can we say that deconstruct with three values means deconstruct to year, month, day ? Why not hour, minute, second ? |
Because you do know that DateTime doesn't have a constructor with 3 arguments that are hour,minute,seconds but only one that is year,month,day. The Deconstructor overloads should follow the signature of a public constructor if that's possible |
Well , that's right. I wonder why I didn't come up with a constructor. |
I just did this on my own in my project, I'd like to point out that this also helps with perf: BenchmarkDotNet=v0.10.12, OS=Windows 10 Redstone 3 [1709, Fall Creators Update] (10.0.16299.192)
I was actually about to open an issue about adding deconstruct in this form when I saw that it's already here... Also, in my personal view, the There would be very little performance impact for users only needing the Naturally |
Could you please share code for your microbenchmark? |
The results of the benchmark are expected, since the BaseLine calls the GetDatePart |
If we were limited to only one I'd say the opposite, that we should have the fuller deconstruction since callers can choose to ignore what they don't need and it's the more flexible. Luckily, we're not limited to only one. |
@jkotas: https://github.com/damageboy/datetime-deconstruct @panost right... I also have a |
* Mark methods specially handled in JitInterface Intrinsic For CPAOT compiler's sake. Signed-off-by: dotnet-bot <[email protected]>
* Mark methods specially handled in JitInterface Intrinsic For CPAOT compiler's sake. Signed-off-by: dotnet-bot <[email protected]>
Moving this to 6.0 as it's not going to meet the deadline for 5.0. @panost are you still interested in this issue? |
This comment has been minimized.
This comment has been minimized.
Be sure to also check for DateOnly/TimeOnly: #49036 |
@KoalaBear84 This issue (DateOnly/TimeOnly) is closed, I can't comment there @ericstj Sorry I didn't read your question a year ago. Yes it will be nice to be added. The code is in this method . Also, it will be nice to be shared with DateOnly (through a common static method accepting dayNumber?) |
@tarekgh @mattjohnsonpint: thoughts on this issue? |
Related: #19397 which added Deconstruct for |
The ask is reasonable here mainly for writing less code getting the various parts of the date and time. And as pointed before it will be more optimized compared to requesting every part separately. We need to look more carefully at the proposal to ensure right signatures. I would keep this for the next release though. |
I agree with Tarek. We should think more carefully about the method signatures. FWIW, This was also dropped as feedback in comments on my blog post about DateOnly. |
The main reason for having a Deconstruct for DateTime/DateOnly is that calling Year, Month and Day in three different calls is very inefficient. There's a lot of repeated work. I agree that a deconstructor for DateTime could be confusing, but that's not the case with DateOnly. |
DateTime already has a constructor with the exact same arguments |
It will be not obvious the deconstructor will always match the constructor parameters. I can see users can easily try to get the time parts only and can run into such problem. Imagine someone calling DateTime.Now.TimeOfDay and then trying to deconstruct that. |
@panost good point. Why return offsetMinutes and not TimeSpan? constructors take TimeSpan and not offset minutes. |
... especially since, historically, there have been sub-minute offsets (usually when a timezone transitioned off a local-solar-noon zone). Although we don't have a way to get the seconds from |
@Clockwork-Muse in DateTimeOffset we don't allow sub-minutes offsets. https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs,956. My question is more about is it useful for users to get the value as TimeSpan or as minutes count. Also, having the constructors are taking TimeSpan is another factor I prefer Having TimeSpan. |
Thinking more, I am seeing it is better to deconstruct using TimeSpan. This will make it consistent with the constructor. Also, we have another issue #52081 which will expose @panost let me know what you think about that. |
I vote for deconstructors that take the most optimal path. I always imagine a use case of serializing (deconstructing) millions of DateTimeOffset fields. So offsetInMinutes is just a copy of the private field. If you want a TimeSpan Offset you can always use the already available Offset property But this is not a very strong opinion. If you leave the decosntructors as is (without time offset), it is also Ok with me, if #52081 is available. Adding TimeSpan you add one (or three?) unnecessary multiplications for each call |
Think about it more from the scenario point of view. When users really want to get the value as TimeSpan and when they need to get it as minutes count. In mainstream cases TimeSpan would be more useful. That is why I prefer to keep the TimeSpan. |
Yes I agree with that view, orthogonal design is a strong point, I mean keeping the arguments (and overloads) that the constructors have. |
I marked the issue ready for the design review. |
namespace System;
public readonly partial struct DateTime
{
public DateTime(DateOnly date, TimeOnly time);
public DateTime(DateOnly date, TimeOnly time, DateTimeKind kind);
public void Deconstruct(out DateOnly date, out TimeOnly time);
public void Deconstruct(out int year, out int month, out int day);
//public void Deconstruct(out int year, out int month, out int day, out int hour, out int minute, out int second);
//public void Deconstruct(out int year, out int month, out int day, out int hour, out int minute, out int second, out int millisecond, out int microsecond);
}
public readonly partial struct DateTimeOffset
{
public DateTimeOffset(DateOnly date, TimeOnly time, TimeSpan offset);
public void Deconstruct(out DateOnly date, out TimeOnly time, out TimeSpan offset);
// public void Deconstruct(out int year, out int month, out int day, out TimeSpan offset);
// public void Deconstruct(out int year, out int month, out int day, out int hour, out int minute, out int second, out TimeSpan offset);
// public void Deconstruct(out int year, out int month, out int day, out int hour, out int minute, out int second, out int millisecond, out int microsecond, out TimeSpan offset);
}
public readonly partial struct DateOnly
{
public void Deconstruct(out int year, out int month, out int day);
}
public readonly partial struct TimeOnly
{
public void Deconstruct(out int hour, out int minute);
public void Deconstruct(out int hour, out int minute, out int second);
public void Deconstruct(out int hour, out int minute, out int second, out int millisecond);
public void Deconstruct(out int hour, out int minute, out int second, out int millisecond, out int microsecond);
} |
Since I have already addressed some changes in the classes If that goes okay, I would be happy if someone of you assigns me. |
Thanks @deeprobin for willing to help with the implementation. |
When Though it should be fairly obvious what is wrong because of the types involved. And I don't have a better suggestion. |
@terrajobst I can't imagine a use case for public void Deconstruct(out DateOnly date, out TimeOnly time); I mean, where you will need both of them (date and time) other than in the two use cases I already gave for public void Deconstruct(out int year, out int month, out int day, out int hour, out int minute, out int second); also the ctors of DateTime from DateOnly, TimeOnly should include another overload with Calendar public DateTime(DateOnly date, TimeOnly time, Calendar calendar, DateTimeKind kind) |
You already gave the example for a scenario need the date and time parts. I can imagine other scenarios like scheduling calendars which will need to extract the date and time. We have avoided having a deconstruct which returns many outputs in this proposal. Also, talking logically, DateTime is really a Date and Time. deconstructing it to these parts makes a lot of sense.
Note, we have added the new constructors only because we added the deconstructors. If we find any scenario in the future that needs this constructor, we can consider adding it. |
Proposal
Allow retrieving the group of date and time parts in one call. This will help with performance and code writing/reading clarity.
API Proposal
Code Sample
Old description
From @panost on January 7, 2018 13:42
For example method https://github.com/dotnet/coreclr/blob/0efe34efa69dea7f9b94ddc8251810e0a264671c/src/mscorlib/shared/System/DateTime.cs#L847
could be made public and renamed to Deconstruct, so we can write
The same pattern can be applied to DateTimeOffset and TimeSpan
Copied from original issue: dotnet/coreclr#15776
The text was updated successfully, but these errors were encountered: