Skip to content

[Breaking change]: Fix DateOnly/TimeOnly TryParse to throw on invalid DateTimeStyles and format specifiers #51438

@tarekgh

Description

@tarekgh

[Breaking change]: DateOnly.TryParse and TimeOnly.TryParse now throw exceptions for invalid DateTimeStyles and format specifiers

Description

Starting in .NET 11 Preview 2, the DateOnly.TryParse, DateOnly.TryParseExact, TimeOnly.TryParse, and TimeOnly.TryParseExact methods have been updated to throw an ArgumentException when invalid DateTimeStyles values or format specifiers are provided. Previously, these methods returned false in such cases, which was inconsistent with the behavior of other TryParse APIs in .NET.

This change was introduced to improve API consistency and ensure that invalid arguments are explicitly flagged as errors, rather than being silently ignored.

This change was implemented in dotnet/runtime#123805.

Version

.NET 11 Preview 2

Previous behavior

When invalid DateTimeStyles values or format specifiers were passed to DateOnly.TryParse, DateOnly.TryParseExact, TimeOnly.TryParse, or TimeOnly.TryParseExact, the methods returned false without throwing an exception.

Example

using System;
using System.Globalization;

bool result = DateOnly.TryParseExact(
    "2023-10-15",
    "yyyy-MM-dd",
    CultureInfo.InvariantCulture,
    (DateTimeStyles)999, // Invalid DateTimeStyles value
    out DateOnly date);

Console.WriteLine(result); // Output: False

New behavior

When invalid DateTimeStyles values or format specifiers are passed to these methods, an ArgumentException is thrown. The exception includes details about the invalid argument, such as the parameter name.

Example

using System;
using System.Globalization;

try
{
    bool result = DateOnly.TryParseExact(
        "2023-10-15",
        "yyyy-MM-dd",
        CultureInfo.InvariantCulture,
        (DateTimeStyles)999, // Invalid DateTimeStyles value
        out DateOnly date);
}
catch (ArgumentException ex)
{
    Console.WriteLine(ex.Message); // Output: "The value '999' is not valid for DateTimeStyles. (Parameter 'style')"
}

Type of breaking change

  • Behavioral change: Existing binaries might behave differently at runtime.

Reason for change

This change was introduced to align the behavior of DateOnly and TimeOnly parsing methods with other TryParse APIs in .NET, which throw exceptions for invalid arguments. The previous behavior of returning false for invalid arguments could lead to silent failures and make debugging more difficult.

Recommended action

Developers should review their usage of DateOnly.TryParse, DateOnly.TryParseExact, TimeOnly.TryParse, and TimeOnly.TryParseExact to ensure that valid DateTimeStyles values and format specifiers are being passed. If invalid arguments are possible, consider wrapping the calls in a try-catch block to handle ArgumentException.

Example of handling exceptions

using System;
using System.Globalization;

try
{
    bool result = DateOnly.TryParseExact(
        "2023-10-15",
        "yyyy-MM-dd",
        CultureInfo.InvariantCulture,
        (DateTimeStyles)999, // Invalid DateTimeStyles value
        out DateOnly date);
}
catch (ArgumentException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
    // Handle the exception as needed
}

Affected APIs

  • DateOnly.TryParse(string, out DateOnly)
  • DateOnly.TryParse(string, IFormatProvider, DateTimeStyles, out DateOnly)
  • DateOnly.TryParseExact(string, string, IFormatProvider, DateTimeStyles, out DateOnly)
  • DateOnly.TryParseExact(string, string[], IFormatProvider, DateTimeStyles, out DateOnly)
  • TimeOnly.TryParse(string, out TimeOnly)
  • TimeOnly.TryParse(string, IFormatProvider, DateTimeStyles, out TimeOnly)
  • TimeOnly.TryParseExact(string, string, IFormatProvider, DateTimeStyles, out TimeOnly)
  • TimeOnly.TryParseExact(string, string[], IFormatProvider, DateTimeStyles, out TimeOnly)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions