Add precision options to DateTime/LocalDateTime/LocalTime scalars#9167
Add precision options to DateTime/LocalDateTime/LocalTime scalars#9167
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds precision options to the DateTime, LocalDateTime, and LocalTime scalar types in HotChocolate, allowing developers to configure the number of fractional second digits (0-7) for both input parsing and output serialization. This provides flexibility for scenarios where high precision timestamps are not required, potentially optimizing performance and storage.
Changes:
- Added new
DateTimeOptionsstruct to configure input and output precision for date/time scalars - Modified DateTime, LocalDateTime, and LocalTime scalar types to accept and apply precision options
- Added comprehensive test coverage for precision options across all affected scalar types
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/HotChocolate/Core/src/Types/Types/Scalars/DateTimeOptions.cs | New options struct defining input/output precision for date/time scalars with validation |
| src/HotChocolate/Core/src/Types/Types/Scalars/DateTimeType.cs | Added precision-aware constructors, regex patterns, and format strings for DateTimeType |
| src/HotChocolate/Core/src/Types/Types/Scalars/LocalDateTimeType.cs | Added precision-aware constructors, regex patterns, and format strings for LocalDateTimeType |
| src/HotChocolate/Core/src/Types/Types/Scalars/LocalTimeType.cs | Added precision-aware constructors, regex patterns, and format strings for LocalTimeType |
| src/HotChocolate/Core/test/Types.Tests/Types/Scalars/DateTimeOptionsTests.cs | Test coverage for DateTimeOptions validation and default values |
| src/HotChocolate/Core/test/Types.Tests/Types/Scalars/DateTimeTypeTests.cs | Updated and expanded tests to cover precision options for DateTimeType |
| src/HotChocolate/Core/test/Types.Tests/Types/Scalars/LocalDateTimeTypeTests.cs | Updated and expanded tests to cover precision options for LocalDateTimeType |
| src/HotChocolate/Core/test/Types.Tests/Types/Scalars/LocalTimeTypeTests.cs | Updated and expanded tests to cover precision options for LocalTimeType |
| src/HotChocolate/Core/src/Types/Properties/TypeResources.resx | Added error messages for invalid precision values |
| src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs | Generated resource accessors for new error messages |
| dictionary.txt | Added "sszzz" to spell check exceptions for format string sequences |
Files not reviewed (1)
- src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs: Language not supported
Comments suppressed due to low confidence (9)
src/HotChocolate/Core/src/Types/Types/Scalars/LocalTimeType.cs:139
- The GetLocalFormat method creates a new format string on every call for non-default precision values (except 0). Consider caching the format string in a readonly field during construction to avoid repeated string allocation and concatenation during output serialization. The same optimization could be applied to GetUtcFormat in DateTimeType and GetLocalFormat in LocalDateTimeType.
private string GetLocalFormat()
=> _options.OutputPrecision switch
{
DateTimeOptions.DefaultOutputPrecision => LocalFormat,
0 => "HH:mm:ss",
_ => $"HH:mm:ss.{new string('F', _options.OutputPrecision)}"
};
src/HotChocolate/Core/src/Types/Types/Scalars/DateTimeType.cs:160
- The GetUtcFormat and GetLocalFormat methods create new format strings on every call for non-default precision values (except 0). Consider caching these format strings in readonly fields during construction to avoid repeated string allocation and concatenation during output serialization.
private string GetUtcFormat()
=> _options.OutputPrecision switch
{
DateTimeOptions.DefaultOutputPrecision => UtcFormat,
0 => @"yyyy-MM-ddTHH\:mm\:ssZ",
_ => @$"yyyy-MM-ddTHH\:mm\:ss.{new string('F', _options.OutputPrecision)}Z"
};
private string GetLocalFormat()
=> _options.OutputPrecision switch
{
DateTimeOptions.DefaultOutputPrecision => LocalFormat,
0 => @"yyyy-MM-ddTHH\:mm\:sszzz",
_ => @$"yyyy-MM-ddTHH\:mm\:ss.{new string('F', _options.OutputPrecision)}zzz"
};
src/HotChocolate/Core/src/Types/Types/Scalars/LocalTimeType.cs:152
- The GetLocalTimeRegex method evaluates a switch expression on every call during input parsing. Consider caching the Regex instance in a readonly field during construction to avoid the repeated switch evaluation, which would improve performance for input validation.
private Regex GetLocalTimeRegex()
=> _options.InputPrecision switch
{
0 => LocalTimeRegex0(),
1 => LocalTimeRegex1(),
2 => LocalTimeRegex2(),
3 => LocalTimeRegex3(),
4 => LocalTimeRegex4(),
5 => LocalTimeRegex5(),
6 => LocalTimeRegex6(),
_ => LocalTimeRegex7()
};
src/HotChocolate/Core/src/Types/Types/Scalars/LocalDateTimeType.cs:154
- The GetLocalDateTimeRegex method evaluates a switch expression on every call during input parsing. Consider caching the Regex instance in a readonly field during construction to avoid the repeated switch evaluation, which would improve performance for input validation.
private Regex GetLocalDateTimeRegex()
=> _options.InputPrecision switch
{
0 => LocalDateTimeRegex0(),
1 => LocalDateTimeRegex1(),
2 => LocalDateTimeRegex2(),
3 => LocalDateTimeRegex3(),
4 => LocalDateTimeRegex4(),
5 => LocalDateTimeRegex5(),
6 => LocalDateTimeRegex6(),
_ => LocalDateTimeRegex7()
};
src/HotChocolate/Core/src/Types/Types/Scalars/LocalTimeType.cs:40
- When InputPrecision is 0, the Pattern property will contain an invalid regex pattern
\d{1,0}which means "match 1 to 0 digits". This is semantically invalid as the maximum cannot be less than the minimum. The pattern construction should handle precision 0 as a special case to completely omit the fractional seconds part, similar to how the GeneratedRegex methods handle it.
Pattern = @"^\d{2}:\d{2}:\d{2}(?:\.\d{1," + options.Value.InputPrecision + "})?$";
src/HotChocolate/Core/src/Types/Types/Scalars/LocalDateTimeType.cs:41
- When InputPrecision is 0, the Pattern property will contain an invalid regex pattern
\d{1,0}which means "match 1 to 0 digits". This is semantically invalid as the maximum cannot be less than the minimum. The pattern construction should handle precision 0 as a special case to completely omit the fractional seconds part, similar to how the GeneratedRegex methods handle it.
Pattern = @"^\d{4}-\d{2}-\d{2}[Tt]\d{2}:\d{2}:\d{2}(?:\.\d{1," + options.Value.InputPrecision + "})?$";
src/HotChocolate/Core/src/Types/Types/Scalars/DateTimeType.cs:44
- When InputPrecision is 0, the Pattern property will contain an invalid regex pattern
\d{1,0}which means "match 1 to 0 digits". This is semantically invalid as the maximum cannot be less than the minimum. The pattern construction should handle precision 0 as a special case to completely omit the fractional seconds part, similar to how the GeneratedRegex methods handle it.
Pattern =
@"^\d{4}-\d{2}-\d{2}[Tt]\d{2}:\d{2}:\d{2}(?:\.\d{1,"
+ options.Value.InputPrecision
+ @"})?(?:[Zz]|[+-]\d{2}:\d{2})$";
src/HotChocolate/Core/src/Types/Types/Scalars/LocalDateTimeType.cs:141
- The GetLocalFormat method creates a new format string on every call for non-default precision values (except 0). Consider caching the format string in a readonly field during construction to avoid repeated string allocation and concatenation during output serialization.
private string GetLocalFormat()
=> _options.OutputPrecision switch
{
DateTimeOptions.DefaultOutputPrecision => LocalFormat,
0 => @"yyyy-MM-ddTHH\:mm\:ss",
_ => @$"yyyy-MM-ddTHH\:mm\:ss.{new string('F', _options.OutputPrecision)}"
};
src/HotChocolate/Core/src/Types/Types/Scalars/DateTimeType.cs:173
- The GetDateTimeRegex method evaluates a switch expression on every call during input parsing. Consider caching the Regex instance in a readonly field during construction to avoid the repeated switch evaluation, which would improve performance for input validation.
private Regex GetDateTimeRegex()
=> _options.InputPrecision switch
{
0 => DateTimeRegex0(),
1 => DateTimeRegex1(),
2 => DateTimeRegex2(),
3 => DateTimeRegex3(),
4 => DateTimeRegex4(),
5 => DateTimeRegex5(),
6 => DateTimeRegex6(),
_ => DateTimeRegex7()
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Fusion Gateway Performance ResultsSimple Composite Query
Response Times & Query
query TestQuery {
topProducts(first: 5) {
inStock
name
price
shippingEstimate
upc
weight
reviews {
id
body
author {
id
username
name
}
}
}
}Deep Recursion Query
Response Times & Query
query TestQuery {
users {
id
username
name
reviews {
id
body
product {
inStock
name
price
shippingEstimate
upc
weight
reviews {
id
body
author {
id
username
name
reviews {
id
body
product {
inStock
name
price
shippingEstimate
upc
weight
}
}
}
}
}
}
}
topProducts(first: 5) {
inStock
name
price
shippingEstimate
upc
weight
reviews {
id
body
author {
id
username
name
reviews {
id
body
product {
inStock
name
price
shippingEstimate
upc
weight
}
}
}
}
}
}Variable Batching Throughput
Response Times & Query
query TestQuery($upc: ID!, $price: Long!, $weight: Long!) {
productByUpc(upc: $upc) {
inStock
shippingEstimate(weight: $weight, price: $price)
}
}Variables (5 sets batched per request) [
{ "upc": "1", "price": 899, "weight": 100 },
{ "upc": "2", "price": 1299, "weight": 1000 },
{ "upc": "3", "price": 15, "weight": 20 },
{ "upc": "4", "price": 499, "weight": 100 },
{ "upc": "5", "price": 1299, "weight": 1000 }
]Run 22236252464 • Commit 7622694 • Fri, 20 Feb 2026 18:50:02 GMT |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9167 +/- ##
==========================================
- Coverage 74.16% 0 -74.17%
==========================================
Files 2677 0 -2677
Lines 140790 0 -140790
Branches 16371 0 -16371
==========================================
- Hits 104421 0 -104421
+ Misses 30774 0 -30774
+ Partials 5595 0 -5595
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Summary of the changes (Less than 80 chars)