src/jdk/nashorn/internal/objects/NativeDate.java

Print this page




 827      *
 828      * @param self self reference
 829      * @return string representation of date
 830      */
 831     @Function(attributes = Attribute.NOT_ENUMERABLE)
 832     public static Object toISOString(final Object self) {
 833         return toISOStringImpl(self);
 834     }
 835 
 836     /**
 837      * ECMA 15.9.5.44 Date.prototype.toJSON ( key )
 838      *
 839      * Provides a string representation of this Date for use by {@link NativeJSON#stringify(Object, Object, Object, Object)}
 840      *
 841      * @param self self reference
 842      * @param key ignored
 843      * @return JSON representation of this date
 844      */
 845     @Function(attributes = Attribute.NOT_ENUMERABLE)
 846     public static Object toJSON(final Object self, final Object key) {
 847         if (self instanceof NativeDate) {
 848             final NativeDate nd = (NativeDate)self;
 849             return (isNaN(nd.getTime())) ? null : toISOStringImpl(nd);
 850         }
 851         // NOTE: Date.prototype.toJSON is generic. Accepts other objects as well.
 852         final Object selfObj = Global.toObject(self);
 853         if (!(selfObj instanceof ScriptObject)) {
 854             return null;
 855         }
 856         final ScriptObject sobj  = (ScriptObject)selfObj;
 857         final Object       value = sobj.getDefaultValue(Number.class);
 858 
 859         final double num = (value instanceof Number) ? ((Number)value).doubleValue() : NaN;
 860 
 861         if (isInfinite(num) || isNaN(num)) {
 862             return null;
 863         }
 864 
 865         try {
 866             final Object func = TO_ISO_STRING.getGetter().invokeExact(sobj);
 867             if (func instanceof ScriptFunction) {
 868                 return TO_ISO_STRING.getInvoker().invokeExact(func, sobj, key);
 869             }
 870             throw typeError("not.a.function", ScriptRuntime.safeToString(func));


1183 
1184     // ECMA 15.9.1.13 MakeDate (day, time)
1185     private static double makeDate(final double day, final double time) {
1186         return day * msPerDay + time;
1187     }
1188 
1189 
1190     private static double makeDate(final Integer[] d) {
1191         final double time = makeDay(d[0], d[1], d[2]) * msPerDay;
1192         return time + makeTime(d[3], d[4], d[5], d[6]);
1193     }
1194 
1195     private static double makeDate(final double[] d) {
1196         final double time = makeDay(d[0], d[1], d[2]) * msPerDay;
1197         return time + makeTime(d[3], d[4], d[5], d[6]);
1198     }
1199 
1200     // Convert Date constructor args, checking for NaN, filling in defaults etc.
1201     private static double[] convertCtorArgs(final Object[] args) {
1202         final double[] d = new double[7];

1203 



1204         for (int i = 0; i < d.length; i++) {
1205             if (i < args.length) {
1206                 final double darg = JSType.toNumber(args[i]);
1207                 if (isNaN(darg) || isInfinite(darg)) {
1208                     return null;
1209                 }

1210                 d[i] = (long)darg;
1211             } else {
1212                 d[i] = i == 2 ? 1 : 0; // day in month defaults to 1
1213             }
1214         }
1215 
1216         if (0 <= d[0] && d[0] <= 99) {
1217             d[0] += 1900;
1218         }
1219 
1220         return d;
1221     }
1222 
1223     // This method does the hard work for all setter methods: If a value is provided
1224     // as argument it is used, otherwise the value is calculated from the existing time value.
1225     private static double[] convertArgs(final Object[] args, final double time, final int fieldId, final int start, final int length) {
1226         final double[] d = new double[length];

1227 



1228         for (int i = start; i < start + length; i++) {
1229             if (fieldId <= i && i < fieldId + args.length) {
1230                 final double darg = JSType.toNumber(args[i - fieldId]);
1231                 if (isNaN(darg) || isInfinite(darg)) {
1232                     return null;
1233                 }

1234                 d[i - start] = (long) darg;
1235             } else {
1236                 // Date.prototype.set* methods require first argument to be defined
1237                 if (i == fieldId) {
1238                     return null;
1239                 }


1240                 d[i - start] = valueFromTime(i, time);
1241             }
1242         }
1243         return d;
1244 

1245     }
1246 
1247     // ECMA 15.9.1.14 TimeClip (time)
1248     private static double timeClip(final double time) {
1249         if (isInfinite(time) || isNaN(time) || Math.abs(time) > 8.64e15) {
1250             return Double.NaN;
1251         }
1252         return (long)time;
1253     }
1254 
1255     private static NativeDate ensureNativeDate(final Object self) {
1256         return getNativeDate(self);
1257     }
1258 
1259     private static NativeDate getNativeDate(final Object self) {
1260         if (self instanceof NativeDate) {
1261             return (NativeDate)self;
1262         } else if (self != null && self == Global.instance().getDatePrototype()) {
1263             return Global.instance().DEFAULT_DATE;
1264         } else {




 827      *
 828      * @param self self reference
 829      * @return string representation of date
 830      */
 831     @Function(attributes = Attribute.NOT_ENUMERABLE)
 832     public static Object toISOString(final Object self) {
 833         return toISOStringImpl(self);
 834     }
 835 
 836     /**
 837      * ECMA 15.9.5.44 Date.prototype.toJSON ( key )
 838      *
 839      * Provides a string representation of this Date for use by {@link NativeJSON#stringify(Object, Object, Object, Object)}
 840      *
 841      * @param self self reference
 842      * @param key ignored
 843      * @return JSON representation of this date
 844      */
 845     @Function(attributes = Attribute.NOT_ENUMERABLE)
 846     public static Object toJSON(final Object self, final Object key) {




 847         // NOTE: Date.prototype.toJSON is generic. Accepts other objects as well.
 848         final Object selfObj = Global.toObject(self);
 849         if (!(selfObj instanceof ScriptObject)) {
 850             return null;
 851         }
 852         final ScriptObject sobj  = (ScriptObject)selfObj;
 853         final Object       value = sobj.getDefaultValue(Number.class);
 854 
 855         final double num = (value instanceof Number) ? ((Number)value).doubleValue() : NaN;
 856 
 857         if (isInfinite(num) || isNaN(num)) {
 858             return null;
 859         }
 860 
 861         try {
 862             final Object func = TO_ISO_STRING.getGetter().invokeExact(sobj);
 863             if (func instanceof ScriptFunction) {
 864                 return TO_ISO_STRING.getInvoker().invokeExact(func, sobj, key);
 865             }
 866             throw typeError("not.a.function", ScriptRuntime.safeToString(func));


1179 
1180     // ECMA 15.9.1.13 MakeDate (day, time)
1181     private static double makeDate(final double day, final double time) {
1182         return day * msPerDay + time;
1183     }
1184 
1185 
1186     private static double makeDate(final Integer[] d) {
1187         final double time = makeDay(d[0], d[1], d[2]) * msPerDay;
1188         return time + makeTime(d[3], d[4], d[5], d[6]);
1189     }
1190 
1191     private static double makeDate(final double[] d) {
1192         final double time = makeDay(d[0], d[1], d[2]) * msPerDay;
1193         return time + makeTime(d[3], d[4], d[5], d[6]);
1194     }
1195 
1196     // Convert Date constructor args, checking for NaN, filling in defaults etc.
1197     private static double[] convertCtorArgs(final Object[] args) {
1198         final double[] d = new double[7];
1199         boolean nullReturn = false;
1200 
1201         // should not bailout on first NaN or infinite. Need to convert all
1202         // subsequent args for possible side-effects via valueOf/toString overrides
1203         // on argument objects.
1204         for (int i = 0; i < d.length; i++) {
1205             if (i < args.length) {
1206                 final double darg = JSType.toNumber(args[i]);
1207                 if (isNaN(darg) || isInfinite(darg)) {
1208                     nullReturn = true;
1209                 }
1210 
1211                 d[i] = (long)darg;
1212             } else {
1213                 d[i] = i == 2 ? 1 : 0; // day in month defaults to 1
1214             }
1215         }
1216 
1217         if (0 <= d[0] && d[0] <= 99) {
1218             d[0] += 1900;
1219         }
1220 
1221         return nullReturn? null : d;
1222     }
1223 
1224     // This method does the hard work for all setter methods: If a value is provided
1225     // as argument it is used, otherwise the value is calculated from the existing time value.
1226     private static double[] convertArgs(final Object[] args, final double time, final int fieldId, final int start, final int length) {
1227         final double[] d = new double[length];
1228         boolean nullReturn = false;
1229 
1230         // Need to call toNumber on all args for side-effects - even if an argument
1231         // fails to convert to number, subsequent toNumber calls needed for possible
1232         // side-effects via valueOf/toString overrides.
1233         for (int i = start; i < start + length; i++) {
1234             if (fieldId <= i && i < fieldId + args.length) {
1235                 final double darg = JSType.toNumber(args[i - fieldId]);
1236                 if (isNaN(darg) || isInfinite(darg)) {
1237                     nullReturn = true;
1238                 }
1239 
1240                 d[i - start] = (long) darg;
1241             } else {
1242                 // Date.prototype.set* methods require first argument to be defined
1243                 if (i == fieldId) {
1244                     nullReturn = true;
1245                 }
1246 
1247                 if (! nullReturn) {
1248                     d[i - start] = valueFromTime(i, time);
1249                 }
1250             }
1251         }
1252 
1253         return nullReturn? null : d;
1254     }
1255 
1256     // ECMA 15.9.1.14 TimeClip (time)
1257     private static double timeClip(final double time) {
1258         if (isInfinite(time) || isNaN(time) || Math.abs(time) > 8.64e15) {
1259             return Double.NaN;
1260         }
1261         return (long)time;
1262     }
1263 
1264     private static NativeDate ensureNativeDate(final Object self) {
1265         return getNativeDate(self);
1266     }
1267 
1268     private static NativeDate getNativeDate(final Object self) {
1269         if (self instanceof NativeDate) {
1270             return (NativeDate)self;
1271         } else if (self != null && self == Global.instance().getDatePrototype()) {
1272             return Global.instance().DEFAULT_DATE;
1273         } else {