diff --git a/src/MoonSharp.Interpreter.Tests/EndToEnd/TimeZoneTests.cs b/src/MoonSharp.Interpreter.Tests/EndToEnd/TimeZoneTests.cs new file mode 100644 index 00000000..87c65569 --- /dev/null +++ b/src/MoonSharp.Interpreter.Tests/EndToEnd/TimeZoneTests.cs @@ -0,0 +1,60 @@ +using System; +using NUnit.Framework; + +namespace MoonSharp.Interpreter.Tests.EndToEnd +{ + [TestFixture] + public class TimeZoneTests + { + [Test] + public void LocalTime1() + { + Script S = new Script(); + try + { + S.Options.LocalTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time"); + } + catch (TimeZoneNotFoundException) + { + S.Options.LocalTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin"); + } + + DynValue res = S.DoString("return os.date(\"%Y-%m-%d %H:%M:%S\", 0)"); + + Assert.AreEqual(DataType.String, res.Type); + Assert.AreEqual("1970-01-01 01:00:00", res.String); + } + + [Test] + public void LocalTime2() + { + Script S = new Script(); + try + { + S.Options.LocalTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time"); + } + catch (TimeZoneNotFoundException) + { + S.Options.LocalTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin"); + } + + DynValue res = S.DoString("return os.date(\"!%Y-%m-%d %H:%M:%S\", 0)"); + + Assert.AreEqual(DataType.String, res.Type); + Assert.AreEqual("1970-01-01 00:00:00", res.String); + } + + [Test] + public void LocalTime3() + { + Script S = new Script(); + + TimeSpan offset = TimeZoneInfo.Local.GetUtcOffset(new DateTime(1970, 1, 1)); + + DynValue res = S.DoString(string.Format("return os.date(\"%Y-%m-%d %H:%M:%S\", -{0})", offset.TotalSeconds)); + + Assert.AreEqual(DataType.String, res.Type); + Assert.AreEqual("1970-01-01 00:00:00", res.String); + } + } +} diff --git a/src/MoonSharp.Interpreter.Tests/MoonSharp.Interpreter.Tests.net35-client.csproj b/src/MoonSharp.Interpreter.Tests/MoonSharp.Interpreter.Tests.net35-client.csproj index 3af2831c..86a1a337 100644 --- a/src/MoonSharp.Interpreter.Tests/MoonSharp.Interpreter.Tests.net35-client.csproj +++ b/src/MoonSharp.Interpreter.Tests/MoonSharp.Interpreter.Tests.net35-client.csproj @@ -135,6 +135,7 @@ + diff --git a/src/MoonSharp.Interpreter/CoreLib/OsTimeModule.cs b/src/MoonSharp.Interpreter/CoreLib/OsTimeModule.cs index 762632fa..36ac41b4 100755 --- a/src/MoonSharp.Interpreter/CoreLib/OsTimeModule.cs +++ b/src/MoonSharp.Interpreter/CoreLib/OsTimeModule.cs @@ -123,7 +123,9 @@ public static DynValue date(ScriptExecutionContext executionContext, CallbackArg try { - reference = TimeZoneInfo.ConvertTimeFromUtc(reference, TimeZoneInfo.Local); + TimeZoneInfo localTimeZoneInfo = executionContext.OwnerScript.Options.LocalTimeZoneInfo ?? TimeZoneInfo.Local; + + reference = TimeZoneInfo.ConvertTimeFromUtc(reference, localTimeZoneInfo); isDst = reference.IsDaylightSavingTime(); } catch (TimeZoneNotFoundException) diff --git a/src/MoonSharp.Interpreter/ScriptOptions.cs b/src/MoonSharp.Interpreter/ScriptOptions.cs index f74131a9..41d23dd9 100644 --- a/src/MoonSharp.Interpreter/ScriptOptions.cs +++ b/src/MoonSharp.Interpreter/ScriptOptions.cs @@ -27,6 +27,8 @@ internal ScriptOptions(ScriptOptions defaults) this.ScriptLoader = defaults.ScriptLoader; this.CheckThreadAccess = defaults.CheckThreadAccess; + + this.LocalTimeZoneInfo = defaults.LocalTimeZoneInfo; } /// @@ -88,13 +90,17 @@ internal ScriptOptions(ScriptOptions defaults) /// Gets or sets a value indicating whether the thread check is enabled. /// A "lazy" thread check is performed everytime execution is entered to ensure that no two threads /// calls MoonSharp execution concurrently. However 1) the check is performed best effort (thus, it might - /// not detect all issues) and 2) it might trigger in very odd legal situations (like, switching threads + /// not detect all issues) and 2) it might trigger in very odd legal situations (like, switching threads /// inside a CLR-callback without actually having concurrency. - /// + /// /// Disable this option if the thread check is giving problems in your scenario, but please check that /// you are not calling MoonSharp execution concurrently as it is not supported. /// public bool CheckThreadAccess { get; set; } + /// + /// Gets or sets the local time zone. If null, TimeZoneInfo.Local is used. + /// + public TimeZoneInfo LocalTimeZoneInfo { get; set; } } }