Giter VIP home page Giter VIP logo

Comments (6)

CodeBlanch avatar CodeBlanch commented on August 20, 2024 1

@LeaFrock Try something like this:

		private static readonly JsonSerializerOptions s_ThingOptions = new()
		{
			Converters = { new JsonMicrosoftDateTimeWithOffsetConverter() }
		};

		public Thing ParseThingFromJson(string json)
		{
			return JsonSerializer.Deserialize<Thing>(json, s_ThingOptions);
		}

		public sealed class JsonMicrosoftDateTimeWithOffsetConverter : JsonConverterFactory
		{
			private readonly JsonMicrosoftDateTimeOffsetConverter _DateTimeOffsetFactory = new();

			public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(DateTime);

			public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
			{
				return new Converter(
					(JsonConverter<DateTimeOffset>)_DateTimeOffsetFactory.CreateConverter(typeof(DateTimeOffset), options));
			}

			private class Converter : JsonConverter<DateTime>
			{
				private readonly JsonConverter<DateTimeOffset> _DateTimeOffsetConverter;

				public Converter(JsonConverter<DateTimeOffset> dateTimeOffsetConverter)
				{
					_DateTimeOffsetConverter = dateTimeOffsetConverter;
				}

				public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
				{
					DateTimeOffset dateTimeOffset = _DateTimeOffsetConverter.Read(ref reader, typeToConvert, options);
					return dateTimeOffset.LocalDateTime;
				}

				public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
					=> _DateTimeOffsetConverter.Write(writer, value, options);
			}
		}

What that will do is round-trip your values using local time.

If you read a value from the DB like \/Date(1580803200000-0500)\/ on a system in the pacific timezone and then immediately wrote it back, it would be changed to \/Date(1580803200000-0800)\/. The reason for that is DateTime can't store the offset. It either has to be UTC or Local.

If all your systems are in the same time zone, that should work fine. If your system are not, I recommend switching your ORM to DateTimeOffset because that is what it is for 😄 Sounds like the current design might be bugged.

from core.

CodeBlanch avatar CodeBlanch commented on August 20, 2024

@Malincoln9 Are you able to switch the target type to DateTimeOffset? The JsonMicrosoftDateTimeConverter doesn't understand the time offset in your JSON ("-0600") but JsonMicrosoftDateTimeOffsetConverter can handle that.

Example from the tests:

public void DateTimeOffsetDeserializationTest()
{
TestClass? Actual = JsonSerializer.Deserialize<TestClass>(@"{""DateTimeOffset"":""\/Date(1580803200000-0800)\/""}");
Assert.IsNotNull(Actual);
Assert.AreEqual(
s_TestLocalDateTimeOffsetNegative,
Actual.DateTimeOffset);
Assert.AreEqual(s_TestLocalDateTimeOffsetNegative.UtcDateTime, Actual.DateTimeOffset.UtcDateTime);
Actual = JsonSerializer.Deserialize<TestClass>(@"{""DateTimeOffset"":""/Date(1580745600000+0800)/""}");
Assert.IsNotNull(Actual);
Assert.AreEqual(
s_TestLocalDateTimeOffsetPositive,
Actual.DateTimeOffset);
Assert.AreEqual(s_TestLocalDateTimeOffsetPositive.UtcDateTime, Actual.DateTimeOffset.UtcDateTime);
}

from core.

Malincoln9 avatar Malincoln9 commented on August 20, 2024

I was able to make that work. Would have liked to keep it DateTime, but thanks.

from core.

LeaFrock avatar LeaFrock commented on August 20, 2024

Same issue, but I cannot switch the target type to DateTimeOffset. The situation is that, the DateTime part of our some database entities is stored like /Date(...+..)/ in redis, but the class is defined by ORM as DateTime instead of DateTimeOffset(DBFirst). I have to be compatible with some old apps using redis too, and not affect ORM in order to avoid other problems.

Any workaround?

from core.

paritoshgote-msft avatar paritoshgote-msft commented on August 20, 2024

Spoke offline with @CodeBlanch who is going to create a PR against this issue.

After looking at the DataContractJson docs, we see that "/Date(700000+0500)/" is actually a DateTime format and not DateTimeOffset format. So JsonMicrosoftDateTimeConverter should be handling this case. If there is any +/- offset it's deserialized to local time; if not, it's deserialized to UTC

https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/stand-alone-json-serialization#datetime-wire-format

"The part that consists of "+0500" in the example is optional and indicates that the time is of the Local kind - that is, should be converted to the local time zone on deserialization. If it is absent, the time is deserialized as Utc. The actual number ("0500" in this example) and its sign (+ or -) are ignored."

from core.

CodeBlanch avatar CodeBlanch commented on August 20, 2024

3.0.0-beta2 has been published which updates JsonMicrosoftDateTimeConverter to follow the spec linked above.

from core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.