From 8c8fcbea609a5f68f8c6b2ea757ddf9bb22d5d4a Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Mon, 3 Sep 2018 09:56:01 +0200 Subject: [PATCH] Fixed date conversions JavaScript usually does not care a lot about timezones, but since the conversion happens via milliseconds since epoch (which is UTC based) one needs to be a bit careful about which conversions to do where. Added/moved tests to a central place so there is an overview over all date related tests. --- .../Noesis.Javascript/JavascriptInterop.cpp | 4 +- Source/Noesis.Javascript/SystemInterop.cpp | 4 +- .../ConvertFromJavascriptTests.cs | 8 -- .../ConvertToJavascriptTests.cs | 10 --- Tests/Noesis.Javascript.Tests/DateTest.cs | 76 +++++++++++++++++++ .../Noesis.Javascript.Tests.csproj | 3 +- 6 files changed, 82 insertions(+), 23 deletions(-) create mode 100644 Tests/Noesis.Javascript.Tests/DateTest.cs diff --git a/Source/Noesis.Javascript/JavascriptInterop.cpp b/Source/Noesis.Javascript/JavascriptInterop.cpp index dec31bc..5e5b795 100644 --- a/Source/Noesis.Javascript/JavascriptInterop.cpp +++ b/Source/Noesis.Javascript/JavascriptInterop.cpp @@ -354,10 +354,10 @@ JavascriptInterop::ConvertObjectFromV8(Handle iObject, ConvertedObjects System::DateTime^ JavascriptInterop::ConvertDateFromV8(Handle iValue) { - System::DateTime^ startDate = gcnew System::DateTime(1970, 1, 1); + System::DateTime^ startDate = gcnew System::DateTime(1970, 1, 1, 0, 0, 0, 0, System::DateTimeKind::Utc); double milliseconds = iValue->NumberValue(); System::TimeSpan^ timespan = System::TimeSpan::FromMilliseconds(milliseconds); - return System::DateTime(timespan->Ticks + startDate->Ticks).ToLocalTime(); + return System::DateTime(timespan->Ticks + startDate->Ticks).ToLocalTime(); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Source/Noesis.Javascript/SystemInterop.cpp b/Source/Noesis.Javascript/SystemInterop.cpp index 04015df..56ce56d 100644 --- a/Source/Noesis.Javascript/SystemInterop.cpp +++ b/Source/Noesis.Javascript/SystemInterop.cpp @@ -337,8 +337,8 @@ SystemInterop::ConvertToSystemString(std::string iString) double SystemInterop::ConvertFromSystemDateTime(System::DateTime^ iDateTime) { - System::DateTime^ startDate = gcnew System::DateTime(1970, 1, 1); - System::TimeSpan^ timespan = *iDateTime - *startDate; + System::DateTime^ startDate = gcnew System::DateTime(1970, 1, 1, 0, 0, 0, 0, System::DateTimeKind::Utc); + System::TimeSpan^ timespan = iDateTime->ToUniversalTime() - *startDate; return timespan->TotalMilliseconds; } diff --git a/Tests/Noesis.Javascript.Tests/ConvertFromJavascriptTests.cs b/Tests/Noesis.Javascript.Tests/ConvertFromJavascriptTests.cs index 57ce357..ed0c819 100644 --- a/Tests/Noesis.Javascript.Tests/ConvertFromJavascriptTests.cs +++ b/Tests/Noesis.Javascript.Tests/ConvertFromJavascriptTests.cs @@ -108,14 +108,6 @@ public void ReadBooleanTrue() _context.GetParameter("myBool").Should().BeOfType().Which.Should().BeTrue(); } - [TestMethod] - public void ReadDate() - { - _context.Run("var myDate = new Date(2010,9,10)"); - - _context.GetParameter("myDate").Should().BeOfType().Which.Should().Be(new DateTime(2010, 10, 10)); - } - [TestMethod] public void ReadObject() { diff --git a/Tests/Noesis.Javascript.Tests/ConvertToJavascriptTests.cs b/Tests/Noesis.Javascript.Tests/ConvertToJavascriptTests.cs index c4d8a5c..c9a2945 100644 --- a/Tests/Noesis.Javascript.Tests/ConvertToJavascriptTests.cs +++ b/Tests/Noesis.Javascript.Tests/ConvertToJavascriptTests.cs @@ -134,16 +134,6 @@ public void SetBoolean() _context.Run("val === true").Should().BeOfType().Which.Should().BeTrue(); } - [TestMethod] - public void SetDateTime() - { - _context.SetParameter("val", new DateTime(2010, 10, 10, 0, 0, 0, DateTimeKind.Utc)); - - _context.Run("val.getUTCFullYear()").Should().BeOfType().Which.Should().Be(2010); - _context.Run("val.getUTCMonth()").Should().BeOfType().Which.Should().Be(9); - _context.Run("val.getUTCDate()").Should().BeOfType().Which.Should().Be(10); - } - [TestMethod] public void SetObject() { diff --git a/Tests/Noesis.Javascript.Tests/DateTest.cs b/Tests/Noesis.Javascript.Tests/DateTest.cs new file mode 100644 index 0000000..5bf26e9 --- /dev/null +++ b/Tests/Noesis.Javascript.Tests/DateTest.cs @@ -0,0 +1,76 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using FluentAssertions; + +namespace Noesis.Javascript.Tests +{ + [TestClass] + public class DateTest + { + private JavascriptContext _context; + + [TestInitialize] + public void SetUp() + { + _context = new JavascriptContext(); + } + + [TestCleanup] + public void TearDown() + { + _context.Dispose(); + } + + [TestMethod] + public void SetDateTime() + { + _context.SetParameter("val", new DateTime(2010, 10, 10, 0, 0, 0, DateTimeKind.Utc)); + + _context.Run("val.getUTCFullYear()").Should().BeOfType().Which.Should().Be(2010); + _context.Run("val.getUTCMonth()").Should().BeOfType().Which.Should().Be(9); + _context.Run("val.getUTCDate()").Should().BeOfType().Which.Should().Be(10); + } + + [TestMethod] + public void SetAndReadDateTimeUtc() + { + var dateTime = new DateTime(2010, 10, 10, 0, 0, 0, DateTimeKind.Utc); + _context.SetParameter("val", dateTime); + + var dateFromV8 = (DateTime) _context.Run("val"); + dateFromV8.ToUniversalTime().Should().Be(dateTime); + } + + [TestMethod] + public void SetAndReadDateTimeLocal() + { + var dateTime = new DateTime(2010, 10, 10, 0, 0, 0, DateTimeKind.Local); + _context.SetParameter("val", dateTime); + + _context.Run("val").Should().Be(dateTime); + } + + [TestMethod] + public void SetAndReadDateTimeUnspecified() + { + var dateTime = new DateTime(2010, 10, 10); + _context.SetParameter("val", dateTime); + + _context.Run("val").Should().Be(dateTime); + } + + [TestMethod] + public void CreateCurrentDateInJavaScript() + { + DateTime currentTimeAsReportedByV8 = (DateTime)_context.Run("new Date()"); + (currentTimeAsReportedByV8 - DateTime.Now).TotalSeconds.Should().BeLessThan(1, "Dates should be mostly equal"); + } + + [TestMethod] + public void CreateFixedDateInJavaScript() + { + DateTime dateAsReportedByV8 = (DateTime)_context.Run("new Date(2010, 9, 10)"); + dateAsReportedByV8.Should().Be(new DateTime(2010, 10, 10)); + } + } +} diff --git a/Tests/Noesis.Javascript.Tests/Noesis.Javascript.Tests.csproj b/Tests/Noesis.Javascript.Tests/Noesis.Javascript.Tests.csproj index 4e4b191..8c0e716 100644 --- a/Tests/Noesis.Javascript.Tests/Noesis.Javascript.Tests.csproj +++ b/Tests/Noesis.Javascript.Tests/Noesis.Javascript.Tests.csproj @@ -91,6 +91,7 @@ + @@ -120,4 +121,4 @@ copy $(ProjectDir)..\..\$(V8Platform)\$(Configuration)\icu*.* $(ProjectDir)$(Out copy $(ProjectDir)..\..\$(V8Platform)\$(Configuration)\*.bin $(ProjectDir)$(OutDir) - \ No newline at end of file +