Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/olegra/system.datetimeonly
Make DateOnly and TimeOnly data types available for all .NET versions prior to .NET 6
https://github.com/olegra/system.datetimeonly
backported dateonly dotnet timeonly
Last synced: 19 days ago
JSON representation
Make DateOnly and TimeOnly data types available for all .NET versions prior to .NET 6
- Host: GitHub
- URL: https://github.com/olegra/system.datetimeonly
- Owner: OlegRa
- License: mit
- Created: 2021-11-18T13:09:45.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2024-10-11T05:22:08.000Z (about 1 month ago)
- Last Synced: 2024-11-01T09:38:41.619Z (19 days ago)
- Topics: backported, dateonly, dotnet, timeonly
- Language: C#
- Homepage:
- Size: 283 KB
- Stars: 22
- Watchers: 1
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
[![Build](https://github.com/OlegRa/System.DateTimeOnly/actions/workflows/release.yml/badge.svg)](https://github.com/OlegRa/System.DateTimeOnly/actions/workflows/release.yml)
[![Codacy Grade](https://app.codacy.com/project/badge/Grade/37aac9b569e347d591f1648ff2793092)](https://app.codacy.com/gh/OlegRa/System.DateTimeOnly/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Codacy Coverage](https://app.codacy.com/project/badge/Coverage/37aac9b569e347d591f1648ff2793092)](https://app.codacy.com/gh/OlegRa/System.DateTimeOnly/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)
[![PVS-Studio](https://img.shields.io/badge/PVS--Studio-0-blue?logo=opensourceinitiative&logoColor=white&logoWidth=16)](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source)
[![Sponsors](https://img.shields.io/github/sponsors/OlegRa?logo=github)](https://github.com/sponsors/OlegRa)# ![Logo](https://user-images.githubusercontent.com/4800940/174981624-cb9d6acd-ac30-4d46-9118-81425dd4d0fe.png) Portable.System.DateTimeOnly [![Nuget](https://img.shields.io/nuget/v/Portable.System.DateTimeOnly?logo=NuGet)](https://www.nuget.org/packages/Portable.System.DateTimeOnly) [![Nuget](https://img.shields.io/nuget/dt/Portable.System.DateTimeOnly?logo=NuGet)](https://www.nuget.org/stats/packages/Portable.System.DateTimeOnly?groupby=Version)
The .NET 6 introduced two new data types [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) and [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) that can be used in various scenarios. If you want to use the same types in the .NET versions below to .NET 6 you can use this library in form of the NuGet package. You can also use it in your own NuGet package if you want to provide an API that uses these types and make it compatible with all currently supported .NET versions at the same time.
## String Parsing Performance
The original version of this package used the simplified string parsing approach - it just reuses the default [`System.DateTime`](https://docs.microsoft.com/dotnet/api/system.datetime) parsing logic as is. It works well in most use cases but parsing behavior was not matched 100% to the .NET 6 [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) and [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) data types. Their raise the [`System.FormatException`](https://docs.microsoft.com/dotnet/api/system.formatexception) exception in case if the input string contains the time part for the [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) or the date part in the case of [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) types.
Unfortunately, this behavior in .NET 6 implementation depends heavily on an internal parser that provides a lot more information about parsing results than a public version of parsing API. Porting this parser required porting a lot of culture-specific code and looks unpractical for such a simple package. So another approach selected for solving this issue - double parsing using [`System.DateTime.TryParseExact`](https://docs.microsoft.com/dotnet/api/system.datetime.tryparseexact) method with proper formatting strings.
This approach, of course, has an obvious disadvantage - in some cases, we have to parse the same string twice. If performance is critical for you and you are OK with the _incorrect_ parsing results in some rare cases you can restore the original behavior using the application context switch named `Portable.System.DateTimeOnly.UseFastParsingLogic`. Check the [`FastStrictParsingLogicTests`](https://github.com/OlegRa/System.DateTimeOnly/blob/master/DateTimeOnly.Tests/FastStrictParsingLogicTests.cs) for more examples for this issue.
# ![Logo](https://user-images.githubusercontent.com/4800940/174981624-cb9d6acd-ac30-4d46-9118-81425dd4d0fe.png) Portable.System.DateTimeOnly.Json [![Nuget](https://img.shields.io/nuget/v/Portable.System.DateTimeOnly.Json?logo=NuGet)](https://www.nuget.org/packages/Portable.System.DateTimeOnly.Json) [![Nuget](https://img.shields.io/nuget/dt/Portable.System.DateTimeOnly.Json?logo=NuGet)](https://www.nuget.org/stats/packages/Portable.System.DateTimeOnly.Json?groupby=Version)
The [`System.Text.Json`](https://docs.microsoft.com/dotnet/api/system.text.json) NuGet package contains the built-in support for the [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) and [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) types serialization/deserialization. Of course, the backported versions of the same types are not supported by default by this library. If you already use the portable versions of these types in your code and want to make them compatible with the [`System.Text.Json`](https://docs.microsoft.com/dotnet/api/system.text.json) you can implement custom converters or use this package for cross-framework compatible approach.
## Reflection-based Serialization
The package provides two concrete implementations of the [`System.Text.Json.Serialization.JsonConverter`](https://docs.microsoft.com/dotnet/api/system.text.json.serialization.jsonconverter-1) class: `System.Text.Json.DateOnlyConverter` and `System.Text.Json.TimeOnlyConverter` for converting [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) and [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) data types. You can use this converter as usual [`System.Text.Json`](https://docs.microsoft.com/dotnet/api/system.text.json) converters: with the [`System.Text.Json.Serialization.JsonConverterAttribute`](https://docs.microsoft.com/dotnet/api/system.text.json.serialization.jsonconverterattribute) attribute or [`System.Text.Json.JsonSerializerOptions.Converters`](https://docs.microsoft.com/dotnet/api/system.text.json.jsonserializeroptions.converters) property.
The main disadvantage of this "direct" approach for configuring [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) and [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) data types handling by the [`System.Text.Json`](https://docs.microsoft.com/dotnet/api/system.text.json) library is that in this case you'll always use the backported converters even if your code runs on .NET 6 and later. The package also provides two helper attributes `System.Text.Json.DateOnlyConverterAttribute` and `System.Text.Json.TimeOnlyConverterAttribute` for mitigating this problem. These attributes use built-in converters on .NET 6 and later and fall back to the backported one in other cases.
## Source Generators Workaround
Unfortunately, attributes-based approach will not work if you'll try to use [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) and/or [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) data types with the [`System.Text.Json`](https://docs.microsoft.com/dotnet/api/system.text.json) source generators. The only way to make generated code compilable is to use any type names not equal to [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) and/or [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) available in object graph processed by the source generator.
The package provides two helper types: `System.Text.Json.DateOnly` and `System.Text.Json.TimeOnly` (same class names but different full type names). These types have no public properties but they provide implicit conversion operations from/to the [`System.DateOnly`](https://docs.microsoft.com/dotnet/api/system.dateonly) and [`System.TimeOnly`](https://docs.microsoft.com/dotnet/api/system.timeonly) data types respectively. You can use them safely in your JSON-mapping objects with any type of serialization available in the [`System.Text.Json`](https://docs.microsoft.com/dotnet/api/system.text.json) library. These types have custom [`System.Text.Json.Serialization.JsonConverterAttribute`](https://docs.microsoft.com/dotnet/api/system.text.json.serialization.jsonconverterattribute) applied with helper converters that delegate work to `System.Text.Json.DateOnlyConverter` and `System.Text.Json.TimeOnlyConverter` types without code duplication.
## Contributors
Thanks a lot for all contributors. See the full list of project supporters in the [CONTRIBUTORS](https://github.com/OlegRa/System.DateTimeOnly/blob/master/CONTRIBUTORS.md) file.
## SAST Tools
This project uses [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code.