diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.DotNetCore.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.DotNetCore.csproj index 56afc8180e..92b5d848a6 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.DotNetCore.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.DotNetCore.csproj @@ -11,5 +11,6 @@ + \ No newline at end of file diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj index 96d17d7fff..c14f176de6 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -43,6 +43,9 @@ false + + ..\packages\NodaTime.1.4.7\lib\net35-Client\NodaTime.dll + @@ -609,6 +612,7 @@ + - + + + + diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs index f9874ba234..938d4ab919 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs @@ -46,7 +46,7 @@ namespace Apache.Ignite.Core.Binary private bool _isInUse; /** Force timestamp flag. */ - private bool _forceTimestamp; + private bool _forceTimestamp = true; /// /// Write binary object. @@ -89,10 +89,12 @@ namespace Apache.Ignite.Core.Binary /// Gets or sets a value indicating whether all DateTime values should be written as Timestamp. /// /// Timestamp format is required for values used in SQL and for interoperation with other platforms. - /// Only UTC values are supported in Timestamp format. Other values will cause an exception on write. /// - /// Normally serializer uses for DateTime fields. + /// is true by default. + /// /// This attribute changes the behavior to . + /// When is disabled the serializer uses + /// for DateTime fields. /// /// See also . /// diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs index 445d42162f..c764ab5389 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs @@ -29,6 +29,8 @@ namespace Apache.Ignite.Core.Impl.Binary using Apache.Ignite.Core.Binary; using Apache.Ignite.Core.Impl.Binary.IO; using Apache.Ignite.Core.Impl.Common; + using NodaTime; + using NodaTime.TimeZones; /// /// Utilities for binary serialization. @@ -81,6 +83,16 @@ namespace Apache.Ignite.Core.Impl.Binary RegistrationDisabled = true }; + /** + * We use NodaTime to ensure Java/.NET interoperability since adjustment rules + * are incomplete for some time zones. + */ + private static readonly DateTimeZone NodaZone = DateTimeZoneProviders.Tzdb.GetSystemDefault(); + + /** Ambiguous and skipped local time resolvers. */ + private static readonly ZoneLocalMappingResolver NodaZoneMappingResolver = + Resolvers.CreateMappingResolver(Resolvers.ReturnEarlier, Resolvers.ReturnStartOfIntervalAfter); + /** Method: ReadArray. */ public static readonly MethodInfo MtdhReadArray = typeof(BinaryUtils).GetMethod("ReadArray", BindFlagsStatic); @@ -406,7 +418,20 @@ namespace Apache.Ignite.Core.Impl.Binary long high = stream.ReadLong(); int low = stream.ReadInt(); - return new DateTime(JavaDateTicks + high * TimeSpan.TicksPerMillisecond + low / 100, DateTimeKind.Utc); + var utcDateTime = new DateTime( + JavaDateTicks + high * TimeSpan.TicksPerMillisecond + low / 100, + DateTimeKind.Utc); + var nodaTime = Instant.FromDateTimeUtc(utcDateTime).InZone(NodaZone); + + return new DateTime( + nodaTime.Year, + nodaTime.Month, + nodaTime.Day, + nodaTime.Hour, + nodaTime.Minute, + nodaTime.Second, + nodaTime.Millisecond, + DateTimeKind.Local); } /// @@ -1610,13 +1635,12 @@ namespace Apache.Ignite.Core.Impl.Binary */ private static void ToJavaDate(DateTime date, out long high, out int low) { - if (date.Kind != DateTimeKind.Utc) - { - throw new BinaryObjectException( - "DateTime is not UTC. Only UTC DateTime can be used for interop with other platforms."); - } - - long diff = date.Ticks - JavaDateTicks; + long diff = date.Kind == DateTimeKind.Utc + ? date.Ticks - JavaDateTicks + : LocalDateTime.FromDateTime(date) + .InZone(NodaZone, NodaZoneMappingResolver) + .ToInstant() + .ToUnixTimeTicks(); high = diff / TimeSpan.TicksPerMillisecond;