JsDate.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. }
  18. public JsDate(Engine engine, long dateValue) : this(engine, new DatePresentation(dateValue, DateFlags.None))
  19. {
  20. }
  21. internal JsDate(Engine engine, DatePresentation dateValue) : base(engine, ObjectClass.Date, InternalTypes.Object | InternalTypes.PlainObject)
  22. {
  23. _prototype = engine.Realm.Intrinsics.Date.PrototypeObject;
  24. _dateValue = dateValue.TimeClip();
  25. }
  26. public DateTime ToDateTime()
  27. {
  28. if (_dateValue.Flags == DateFlags.DateTimeMinValue)
  29. {
  30. return DateTime.MinValue;
  31. }
  32. if (_dateValue.Flags == DateFlags.DateTimeMaxValue)
  33. {
  34. return DateTime.MaxValue;
  35. }
  36. if (_dateValue.DateTimeRangeValid)
  37. {
  38. var dateTime = DateConstructor.Epoch.AddMilliseconds(_dateValue.Value);
  39. if (_engine.Options.Interop.DateTimeKind == DateTimeKind.Local)
  40. {
  41. dateTime = TimeZoneInfo.ConvertTimeFromUtc(dateTime, _engine.Options.TimeSystem.DefaultTimeZone);
  42. dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local);
  43. }
  44. return dateTime;
  45. }
  46. Throw.RangeError(_engine.Realm);
  47. return DateTime.MinValue;
  48. }
  49. public double DateValue => _dateValue.IsFinite ? _dateValue.Value : double.NaN;
  50. internal bool DateTimeRangeValid => _dateValue.DateTimeRangeValid;
  51. public override string ToString()
  52. {
  53. if (_dateValue.IsNaN)
  54. {
  55. return "NaN";
  56. }
  57. if (_dateValue.IsInfinity)
  58. {
  59. return "Infinity";
  60. }
  61. return TypeConverter.ToString(this);
  62. }
  63. }