dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.16k stars 4.72k forks source link

DateTime year is wrong when using Japanese calendar in Windows. #82487

Closed moriyaki closed 1 year ago

moriyaki commented 1 year ago

Description

System.DateTime.Parse works fine, but when I pass the data through JsonSerializer, the date (year) is wrong.

Reproduction Steps

using System.Text.Json;

namespace JsonTestNamespace { 
    public class JsonTest { public DateTime Date { get; set; } }

    public class Program { 
        public static void Main() {
            var today = DateTime.Parse("2022-03-22");
            Console.WriteLine(today.ToString());

            var now = new JsonTest { Date = DateTime.Parse("2022-03-22") };
            string jsonString = JsonSerializer.Serialize(now, new JsonSerializerOptions());
            Console.WriteLine(jsonString);
        }
    }
}

Expected behavior

2022/03/22 0:00:00 {"Date":"2022-03-22T00:00:00"}

Actual behavior

2022/03/22 0:00:00 {"Date":"4040-03-22T00:00:00"}

Regression?

No response

Known Workarounds

No response

Configuration

.net 6.0 Windows10 Pro(Japanese, and the Japanese Calender) x64

Other information

No response

ghost commented 1 year ago

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis See info in area-owners.md if you want to be subscribed.

Issue Details
### Description System.DateTime.Parse works fine, but when I pass the data through JsonSerializer, the date (year) is wrong. ### Reproduction Steps ```cs using System.Text.Json; namespace JsonTestNamespace { public class JsonTest { public DateTime Date { get; set; } } public class Program { public static void Main() { var today = DateTime.Parse("2022-03-22"); Console.WriteLine(today.ToString()); var now = new JsonTest { Date = DateTime.Parse("2022-03-22") }; string jsonString = JsonSerializer.Serialize(now, new JsonSerializerOptions()); Console.WriteLine(jsonString); } } } ``` ### Expected behavior 2022/03/22 0:00:00 {"Date":"2022-03-22T00:00:00"} ### Actual behavior 2022/03/22 0:00:00 {"Date":"4040-03-22T00:00:00"} ### Regression? _No response_ ### Known Workarounds _No response_ ### Configuration .net 6.0 Windows10 Pro(Japanese, and the Japanese Calender) x64 ### Other information _No response_
Author: moriyaki
Assignees: -
Labels: `area-System.Text.Json`, `untriaged`
Milestone: -
Clockwork-Muse commented 1 year ago

var today = DateTime.Parse("2022-03-22");

That's because this isn't actually giving you what you think it is. It's parsing the date as a Japanese-era year date, not the Gregorian year date. If you're trying to parse an ISO/Gregorian date, use DateTime.Parse("2022-03-22", CultureInfo.InvariantCulture); Remember that DateTime doesn't "remember" culture calendars, and is strictly a representation of the ISO/Gregorian calendar. If you do today.Year, it's going to give you 4040.

tarekgh commented 1 year ago

@moriyaki

@Clockwork-Muse is correct. You are parsing the date using default CurrentCulture (which it seems in your case is the Japanese culture using Japanese calendar). The time will parse to equivalent Japanese date and as indicated DateTime doesn't carry any information regarding the associated calendar. Using DateTime.Parse("2022-03-22", CultureInfo.InvariantCulture); should fix your issue.