Browse Source

fix the behavior of Date.parse and Date.UTC

Brian Beard 11 years ago
parent
commit
f965c82e20
2 changed files with 68 additions and 27 deletions
  1. 32 0
      Jint.Tests/Runtime/EngineTests.cs
  2. 36 27
      Jint/Native/Date/DateConstructor.cs

+ 32 - 0
Jint.Tests/Runtime/EngineTests.cs

@@ -738,5 +738,37 @@ namespace Jint.Tests.Runtime
             }
         }
 
+        [Fact]
+        public void ParseShouldReturnNumber()
+        {
+            
+
+            RunTest(@"
+                var d = Date.parse('1970-01-01'); 
+                assert(d === 0);
+            ");
+
+            var engine = new Engine();
+
+            var result = engine.Execute("Date.parse('1970-01-01');").GetCompletionValue().AsNumber();
+            Assert.Equal(0, result);
+        }
+
+        [Fact]
+        public void UtcShouldUseUtc()
+        {
+            
+
+            RunTest(@"
+                var d = Date.UTC(1970,0,1); 
+                assert(d === 0);
+            ");
+
+            var engine = new Engine();
+
+            var result = engine.Execute("Date.UTC(1970,0,1)").GetCompletionValue().AsNumber();
+            Assert.Equal(0, result);
+        }
+
     }
 }

+ 36 - 27
Jint/Native/Date/DateConstructor.cs

@@ -81,13 +81,12 @@ namespace Jint.Native.Date
                 }
             }
 
-            return Construct(result);
+            return FromDateTime(result);
         }
 
         private JsValue Utc(JsValue thisObj, JsValue[] arguments)
         {
-            var local = (DateInstance) Construct(arguments);
-            return local.PrimitiveValue;
+            return TimeClip(ConstructTimeValue(arguments, useUtc: true));
         }
 
         private JsValue Now(JsValue thisObj, JsValue[] arguments)
@@ -109,46 +108,56 @@ namespace Jint.Native.Date
         {
             if (arguments.Length == 0)
             {
-                return Construct(DateTime.Now);
+                return Construct(DateTime.UtcNow);
             }
             else if (arguments.Length == 1)
             {
                 var v = TypeConverter.ToPrimitive(arguments[0]);
                 if (v.IsString())
                 {
-                    return Parse(Undefined.Instance, Arguments.From(v)).AsObject();
+                    return Construct(Parse(Undefined.Instance, Arguments.From(v)).AsNumber());
                 }
 
-                return Construct(DatePrototype.TimeClip(TypeConverter.ToNumber(v)));
+                return Construct(TypeConverter.ToNumber(v));
             }
             else
             {
-                var y = TypeConverter.ToNumber(arguments[0]);
-                var m = (int)TypeConverter.ToInteger(arguments[1]);
-                var dt = arguments.Length > 2 ? (int)TypeConverter.ToInteger(arguments[2]) : 1;
-                var h = arguments.Length > 3 ? (int)TypeConverter.ToInteger(arguments[3]) : 0;
-                var min = arguments.Length > 4 ? (int)TypeConverter.ToInteger(arguments[4]) : 0;
-                var s = arguments.Length > 5 ? (int)TypeConverter.ToInteger(arguments[5]) : 0;
-                var milli = arguments.Length > 6 ? (int)TypeConverter.ToInteger(arguments[6]) : 0;
-
-                for (int i = 2; i < arguments.Length; i++)
-                {
-                    if (double.IsNaN(TypeConverter.ToNumber(arguments[i])))
-                    {
-                        return Construct(double.NaN);
-                    }
-                }
+                return Construct(ConstructTimeValue(arguments, useUtc: false));
+            }
+        }
 
-                if ((!double.IsNaN(y)) && (0 <= TypeConverter.ToInteger(y)) && (TypeConverter.ToInteger(y) <= 99))
+        private double ConstructTimeValue(JsValue[] arguments, bool useUtc)
+        {
+            if (arguments.Length < 2)
+            {
+                throw new ArgumentOutOfRangeException("arguments", "There must be at least two arguments.");
+            }
+
+            var y = TypeConverter.ToNumber(arguments[0]);
+            var m = (int)TypeConverter.ToInteger(arguments[1]);
+            var dt = arguments.Length > 2 ? (int)TypeConverter.ToInteger(arguments[2]) : 1;
+            var h = arguments.Length > 3 ? (int)TypeConverter.ToInteger(arguments[3]) : 0;
+            var min = arguments.Length > 4 ? (int)TypeConverter.ToInteger(arguments[4]) : 0;
+            var s = arguments.Length > 5 ? (int)TypeConverter.ToInteger(arguments[5]) : 0;
+            var milli = arguments.Length > 6 ? (int)TypeConverter.ToInteger(arguments[6]) : 0;
+
+            for (int i = 2; i < arguments.Length; i++)
+            {
+                if (double.IsNaN(TypeConverter.ToNumber(arguments[i])))
                 {
-                    y += 1900;
+                    return double.NaN;
                 }
+            }
 
-                var finalDate = DatePrototype.MakeDate(DatePrototype.MakeDay(y, m, dt),
-                    DatePrototype.MakeTime(h, min, s, milli));
-
-                return Construct(DatePrototype.TimeClip(DatePrototype.Utc(finalDate)));
+            if ((!double.IsNaN(y)) && (0 <= TypeConverter.ToInteger(y)) && (TypeConverter.ToInteger(y) <= 99))
+            {
+                y += 1900;
             }
+
+            var finalDate = DatePrototype.MakeDate(DatePrototype.MakeDay(y, m, dt),
+                DatePrototype.MakeTime(h, min, s, milli));
+
+            return useUtc ? finalDate : DatePrototype.Utc(finalDate);
         }
 
         public DatePrototype PrototypeObject { get; private set; }