TimeSystemTests.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using System.Globalization;
  2. using Jint.Runtime;
  3. using Microsoft.Extensions.Time.Testing;
  4. using NodaTime;
  5. namespace Jint.Tests.PublicInterface;
  6. public class TimeSystemTests
  7. {
  8. [Theory]
  9. [InlineData("401, 0, 1, 0, 0, 0, 0", -49512821989000)]
  10. [InlineData("1900, 0, 1, 0, 0, 0, 0", -2208994789000)]
  11. [InlineData("1920, 0, 1, 0, 0, 0, 0", -1577929189000)]
  12. [InlineData("1969, 0, 1, 0, 0, 0, 0", -31543200000)]
  13. [InlineData("2000, 1, 1, 1, 1, 1, 1", 949359661001)]
  14. public void CanProduceValidDatesUsingNodaTimeIntegration(string input, long expected)
  15. {
  16. var dateTimeZone = DateTimeZoneProviders.Tzdb["Europe/Helsinki"];
  17. TimeZoneInfo timeZone;
  18. try
  19. {
  20. timeZone = TimeZoneInfo.FindSystemTimeZoneById("Europe/Helsinki");
  21. }
  22. catch (TimeZoneNotFoundException)
  23. {
  24. timeZone = TimeZoneInfo.FindSystemTimeZoneById("FLE Standard Time");
  25. }
  26. var engine = new Engine(options =>
  27. {
  28. options.TimeZone = timeZone;
  29. options.TimeSystem = new NodaTimeSystem(dateTimeZone, timeZone);
  30. });
  31. Assert.Equal(expected, engine.Evaluate($"new Date({input}) * 1").AsNumber());
  32. }
  33. [Fact]
  34. public void CanUseTimeProvider()
  35. {
  36. var defaultEngine = new Engine();
  37. var defaultNow = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  38. var defaultScriptNow = defaultEngine.Evaluate("new Date() * 1").AsNumber();
  39. Assert.InRange(defaultScriptNow, defaultNow, defaultNow + 100);
  40. var timeProvider = new FakeTimeProvider();
  41. timeProvider.SetUtcNow(new DateTimeOffset(2023, 11, 6, 0, 0, 0, 0, TimeSpan.Zero));
  42. var timeProviderEngine = new Engine(options =>
  43. {
  44. options.TimeSystem = new TimeProviderTimeSystem(timeProvider);
  45. });
  46. var timeProviderNow = timeProvider.GetUtcNow().ToUnixTimeMilliseconds();
  47. var timeProviderScriptNow = timeProviderEngine.Evaluate("new Date() * 1").AsNumber();
  48. Assert.InRange(timeProviderNow, timeProviderScriptNow, timeProviderScriptNow + 100);
  49. Assert.NotInRange(timeProviderScriptNow, defaultScriptNow - 10000, defaultScriptNow + 10000);
  50. }
  51. }
  52. file sealed class NodaTimeSystem : DefaultTimeSystem
  53. {
  54. private readonly DateTimeZone _dateTimeZone;
  55. public NodaTimeSystem(
  56. DateTimeZone dateTimeZone,
  57. TimeZoneInfo timeZoneInfo) : base(timeZoneInfo, CultureInfo.CurrentCulture)
  58. {
  59. _dateTimeZone = dateTimeZone;
  60. }
  61. public override TimeSpan GetUtcOffset(long epochMilliseconds)
  62. {
  63. var offset = _dateTimeZone.GetUtcOffset(Instant.FromUnixTimeMilliseconds(epochMilliseconds));
  64. return offset.ToTimeSpan();
  65. }
  66. }
  67. file sealed class TimeProviderTimeSystem : DefaultTimeSystem
  68. {
  69. private readonly TimeProvider _timeProvider;
  70. public TimeProviderTimeSystem(TimeProvider timeProvider) : base(TimeZoneInfo.Utc, CultureInfo.CurrentCulture)
  71. {
  72. _timeProvider = timeProvider;
  73. }
  74. public override DateTimeOffset GetUtcNow()
  75. {
  76. return _timeProvider.GetUtcNow();
  77. }
  78. }