DatePresentation.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using Jint.Native.Date;
  2. namespace Jint.Native;
  3. [Flags]
  4. internal enum DateFlags : byte
  5. {
  6. None = 0,
  7. NaN = 1,
  8. Infinity = 2,
  9. DateTimeMinValue = 4,
  10. DateTimeMaxValue = 8
  11. }
  12. internal readonly record struct DatePresentation(long Value, DateFlags Flags)
  13. {
  14. public static readonly DatePresentation NaN = new(0, DateFlags.NaN);
  15. public static readonly DatePresentation MinValue = new(JsDate.Min, DateFlags.DateTimeMinValue);
  16. public static readonly DatePresentation MaxValue = new(JsDate.Max, DateFlags.DateTimeMaxValue);
  17. public bool DateTimeRangeValid => IsFinite && Value <= JsDate.Max && Value >= JsDate.Min;
  18. public bool IsNaN => (Flags & DateFlags.NaN) != 0;
  19. public bool IsInfinity => (Flags & DateFlags.Infinity) != 0;
  20. public bool IsFinite => (Flags & (DateFlags.NaN | DateFlags.Infinity)) == 0;
  21. public DateTime ToDateTime()
  22. {
  23. return DateConstructor.Epoch.AddMilliseconds(Value);
  24. }
  25. public static implicit operator DatePresentation(long value)
  26. {
  27. return new DatePresentation(value, DateFlags.None);
  28. }
  29. public static implicit operator DatePresentation(double value)
  30. {
  31. if (double.IsInfinity(value))
  32. {
  33. return new DatePresentation(0, DateFlags.Infinity);
  34. }
  35. if (double.IsNaN(value))
  36. {
  37. return new DatePresentation(0, DateFlags.NaN);
  38. }
  39. return new DatePresentation((long) value, DateFlags.None);
  40. }
  41. public static DatePresentation operator +(DatePresentation a, DatePresentation b)
  42. {
  43. if (a.IsNaN || b.IsNaN)
  44. {
  45. return NaN;
  46. }
  47. return new DatePresentation(a.Value + b.Value, DateFlags.None);
  48. }
  49. public static DatePresentation operator -(DatePresentation a, DatePresentation b) => a + -b;
  50. public static DatePresentation operator +(DatePresentation a) => a;
  51. public static DatePresentation operator -(DatePresentation a) => a with { Value = -a.Value };
  52. internal DatePresentation TimeClip()
  53. {
  54. if ((Flags & (DateFlags.NaN | DateFlags.Infinity)) != 0)
  55. {
  56. return NaN;
  57. }
  58. if (Value is < -8640000000000000 or > 8640000000000000)
  59. {
  60. return NaN;
  61. }
  62. return this;
  63. }
  64. internal JsNumber ToJsValue()
  65. {
  66. if (IsNaN || Value is < -8640000000000000 or > 8640000000000000)
  67. {
  68. return JsNumber.DoubleNaN;
  69. }
  70. return JsNumber.Create(Value);
  71. }
  72. }