JsDate.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using Jint.Native.Date;
  2. using Jint.Native.Object;
  3. using Jint.Runtime;
  4. namespace Jint.Native;
  5. public sealed class JsDate : ObjectInstance
  6. {
  7. // Maximum allowed value to prevent DateTime overflow
  8. internal static readonly long Max = (long) (DateTime.MaxValue - DateConstructor.Epoch).TotalMilliseconds;
  9. // Minimum allowed value to prevent DateTime overflow
  10. internal static readonly long Min = (long) -(DateConstructor.Epoch - DateTime.MinValue).TotalMilliseconds;
  11. internal DatePresentation _dateValue;
  12. public JsDate(Engine engine, DateTimeOffset value) : this(engine, value.UtcDateTime)
  13. {
  14. }
  15. public JsDate(Engine engine, DateTime value) : this(engine, engine.Realm.Intrinsics.Date.FromDateTime(value))
  16. {
  17. if (value == DateTime.MinValue)
  18. {
  19. _dateValue = _dateValue with { Flags = DateFlags.DateTimeMinValue };
  20. }
  21. else if (value == DateTime.MinValue)
  22. {
  23. _dateValue = _dateValue with { Flags = DateFlags.DateTimeMaxValue };
  24. }
  25. }
  26. public JsDate(Engine engine, long dateValue) : this(engine, new DatePresentation(dateValue, DateFlags.None))
  27. {
  28. }
  29. internal JsDate(Engine engine, DatePresentation dateValue) : base(engine, ObjectClass.Date, InternalTypes.Object | InternalTypes.PlainObject)
  30. {
  31. _prototype = engine.Realm.Intrinsics.Date.PrototypeObject;
  32. _dateValue = dateValue.TimeClip();
  33. }
  34. public DateTime ToDateTime()
  35. {
  36. if (_dateValue.Flags == DateFlags.DateTimeMinValue)
  37. {
  38. return DateTime.MinValue;
  39. }
  40. if (_dateValue.Flags == DateFlags.DateTimeMaxValue)
  41. {
  42. return DateTime.MaxValue;
  43. }
  44. if (_dateValue.DateTimeRangeValid)
  45. {
  46. var dateTime = DateConstructor.Epoch.AddMilliseconds(_dateValue.Value);
  47. if (_engine.Options.Interop.DateTimeKind == DateTimeKind.Local)
  48. {
  49. dateTime = TimeZoneInfo.ConvertTimeFromUtc(dateTime, _engine.Options.TimeSystem.DefaultTimeZone);
  50. dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local);
  51. }
  52. return dateTime;
  53. }
  54. ExceptionHelper.ThrowRangeError(_engine.Realm);
  55. return DateTime.MinValue;
  56. }
  57. public double DateValue => _dateValue.IsFinite ? _dateValue.Value : double.NaN;
  58. internal bool DateTimeRangeValid => _dateValue.DateTimeRangeValid;
  59. public override string ToString()
  60. {
  61. if (_dateValue.IsNaN)
  62. {
  63. return "NaN";
  64. }
  65. if (_dateValue.IsInfinity)
  66. {
  67. return "Infinity";
  68. }
  69. return TypeConverter.ToString(this);
  70. }
  71. }