[CSHARP-3717] Add DateOnly/TimeOnly support Created: 24/Jun/21 Updated: 11/Jan/24 |
|
| Status: | Backlog |
| Project: | C# Driver |
| Component/s: | BSON |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | New Feature | Priority: | Major - P3 |
| Reporter: | Manuel Gysin | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 7 |
| Labels: | net6 | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
||||||||
| Issue Links: |
|
||||||||
| Epic Link: | Implement 3.0 release | ||||||||
| Quarter: | FY24Q4 | ||||||||
| Documentation Changes Summary: | 1. What would you like to communicate to the user about this feature? |
||||||||
| Description |
|
Add support the data type DateOnly in the upcoming .net 6 release. Date, Time, and Time Zone Enhancements in .NET 6 DateOnly and TimeOnly should be added to DefaultFrameworkAllowedTypes.AllowedTypes. |
| Comments |
| Comment by Justin Leaming [ 11/Jan/24 ] | ||||||||||||||||||||||||||||||||||||||||||
|
james.kovacs@mongodb.com thank you for the quick reply. I believe the solution to [BsonDateTimeOptions(DateOnly = true)] is used for a DateTime and our code is using a DateOnly. In the meantime our resolution for this was to circumvent the forced UTC in BsonUtils.ToDateTimeFromMillisecondsSinceEpoch and process milliseconds ourselves. Here is what we did for anyone else facing this issue
| ||||||||||||||||||||||||||||||||||||||||||
| Comment by James Kovacs [ 10/Jan/24 ] | ||||||||||||||||||||||||||||||||||||||||||
|
DateTime in .NET defaults to DateTimeKind.Local. The driver maps DateTime to BsonDateTime in the database, which is always stored in UTC. Since the DateTime is local, the driver converts it to UTC before storing it in the database and performs the opposite conversion of UTC to local when deserializing. To avoid this automatic conversion between local and UTC, you can always work with dates as UTC using DateTime.UtcNow and similar. Alternatively you can add the [BsonDateTimeOptions(DateOnly = true)] attribute to your DateTime properties and ensure that DateTime.TimeOfDay is TimeSpan.Zero. The driver will then ignore the DateTimeKind and store the dates as a UTC date with a time component of 12:00:00AM. For example storing DateTime.Today (which is 2024-01-10 12:00:00AM (Local)) is stored in the database as 2024-01-10 12:00:00AM (UTC). Hope that helps in your application until the driver supports DateOnly natively. Sincerely, | ||||||||||||||||||||||||||||||||||||||||||
| Comment by Justin Leaming [ 10/Jan/24 ] | ||||||||||||||||||||||||||||||||||||||||||
|
I believe the problem comes down to this
The serialization to adds the systems time of day, even though the datetime is set to midnight. This means when querying for data by a date only value, if your system is at a different time zone than when the data was added the query will fail. The problem when we encountered this is when our time zone changed from UTC-6 to UTC-7, suddenly our data queries stopped working.[ | ||||||||||||||||||||||||||||||||||||||||||
| Comment by James Kovacs [ 21/Dec/23 ] | ||||||||||||||||||||||||||||||||||||||||||
|
Hi, hakon.ingvaldsen@sonat.no, Thank you for your feedback. Our team is working on a new major release that will introduce support for newer TFMs allowing us to support DateOnly, TimeOnly, and other more recent data types. Regarding your comment about these newer types not working with LINQ, please elaborate. I registered the DateOnlySerializer that I demonstrated in my earlier comment and it was serialized correctly by LINQ to a BsonDateTime when querying. If you can provide the failing code snippet, we can determine why it is not working as expected in your use case. Sincerely, | ||||||||||||||||||||||||||||||||||||||||||
| Comment by Håkon Ingvaldsen [ 21/Dec/23 ] | ||||||||||||||||||||||||||||||||||||||||||
|
Its been a few years now, DateOnly and TimeOnly is still not supported as far as I can tell. We are on .NET 8 now. | ||||||||||||||||||||||||||||||||||||||||||
| Comment by Ahmed Alejo [ 13/Feb/23 ] | ||||||||||||||||||||||||||||||||||||||||||
|
Hi, after all the searches I did keep pointing to the dead end that this issue represents. And since I eventually found a fix/workaround/way-forward, below I share with the world.
My actual scenario was a bit more involved
I can add more code if anyone is interested in how I solved it. Hopefully, this will save someone sometime
| ||||||||||||||||||||||||||||||||||||||||||
| Comment by James Turner [ 08/Mar/22 ] | ||||||||||||||||||||||||||||||||||||||||||
|
While I know that code snippet for `DateOnlySerializer` is an example, there are a couple of issues trying to run it. One issue is that you can't use `BsonSerializer.RegisterSerializer(new DateOnlySerializer());` for the serializer as there is a serializer already (though incorrectly) registered via `BsonClassMapSerializer` in v2.14.1. You'll need to register a serialization provider and use that to return the correct serializer. Also `ToDateTimeFromMillisecondsSinceEpoch` seems to cause issues relating to time zones. Serializing a `DateOnly` for `2020-04-08` is fine but will deserialize to `2020-04-07`. Just mentioning this here in case anyone else hits issues with that example! | ||||||||||||||||||||||||||||||||||||||||||
| Comment by James Kovacs [ 17/Jan/22 ] | ||||||||||||||||||||||||||||||||||||||||||
|
At the moment we do not explicitly target .NET 6 and therefore cannot use .NET 6-specific types like DateOnly. The driver is however compatible with .NET 6 and you can use .NET 6-specific types in your own applications with the driver. Eventually when we implement .NET 6 as a TFM then we will be able to support DateOnly directly in the driver. In the meantime, it is trivial to implement your own DateOnly serialization support by implementing a custom IBsonSerializer. The base class StructSerializerBase<T> will handle much of the work for you. The following minimal DateOnlySerializer will store DateOnly as a BsonDateTime in the database. You could modify it to store DateOnly as a string, seconds since epoch, array of date components, etc. depending on your needs.
| ||||||||||||||||||||||||||||||||||||||||||
| Comment by Eugenio Blabla [ 16/Jan/22 ] | ||||||||||||||||||||||||||||||||||||||||||
|
Here I'm wondering too with @Henry, it's 2022 | ||||||||||||||||||||||||||||||||||||||||||
| Comment by Henry Yu [ 26/Dec/21 ] | ||||||||||||||||||||||||||||||||||||||||||
|
.NET 6 has been released for more than 1 month now. Any updates? | ||||||||||||||||||||||||||||||||||||||||||
| Comment by Dmitry Lukyanov (Inactive) [ 28/Jun/21 ] | ||||||||||||||||||||||||||||||||||||||||||
|
Hello manuel.gysin@gmail.com , this is a good feature request, we will consider it when the .net6 will be released | ||||||||||||||||||||||||||||||||||||||||||
| Comment by Dmitry Lukyanov (Inactive) [ 24/Jun/21 ] | ||||||||||||||||||||||||||||||||||||||||||
|
Hello manuel.gysin@gmail.com , thanks for your report, we will discuss this option and come back to you soon |