Sat, 21 Sep 2013 10:11:15 +0200
8025163: Date methods should not return -0
Reviewed-by: lagergren, jlaskey
1.1 --- a/src/jdk/nashorn/internal/objects/NativeDate.java Fri Sep 20 22:37:08 2013 +0530 1.2 +++ b/src/jdk/nashorn/internal/objects/NativeDate.java Sat Sep 21 10:11:15 2013 +0200 1.3 @@ -75,11 +75,11 @@ 1.4 private static final int FORMAT_LOCAL_TIME = 5; 1.5 1.6 // Constants defined in ECMA 15.9.1.10 1.7 - private static final double hoursPerDay = 24; 1.8 - private static final double minutesPerHour = 60; 1.9 - private static final double secondsPerMinute = 60; 1.10 - private static final double msPerSecond = 1_000; 1.11 - private static final double msPerMinute = 60_000; 1.12 + private static final int hoursPerDay = 24; 1.13 + private static final int minutesPerHour = 60; 1.14 + private static final int secondsPerMinute = 60; 1.15 + private static final int msPerSecond = 1_000; 1.16 + private static final int msPerMinute = 60_000; 1.17 private static final double msPerHour = 3_600_000; 1.18 private static final double msPerDay = 86_400_000; 1.19 1.20 @@ -926,13 +926,13 @@ 1.21 case FORMAT_DATE : 1.22 case FORMAT_LOCAL_DATE_TIME: 1.23 // EEE MMM dd yyyy 1.24 - sb.append(weekDays[(int) weekDay(t)]) 1.25 + sb.append(weekDays[weekDay(t)]) 1.26 .append(' ') 1.27 - .append(months[(int) monthFromTime(t)]) 1.28 + .append(months[monthFromTime(t)]) 1.29 .append(' '); 1.30 - zeroPad(sb, (int) dayFromTime(t), 2); 1.31 + zeroPad(sb, dayFromTime(t), 2); 1.32 sb.append(' '); 1.33 - zeroPad(sb, (int) yearFromTime(t), 4); 1.34 + zeroPad(sb, yearFromTime(t), 4); 1.35 if (format == FORMAT_DATE) { 1.36 break; 1.37 } 1.38 @@ -948,11 +948,11 @@ 1.39 offset = (offset / 60) * 100 + offset % 60; 1.40 1.41 // HH:mm:ss GMT+HHmm 1.42 - zeroPad(sb, (int) hourFromTime(t), 2); 1.43 + zeroPad(sb, hourFromTime(t), 2); 1.44 sb.append(':'); 1.45 - zeroPad(sb, (int) minFromTime(t), 2); 1.46 + zeroPad(sb, minFromTime(t), 2); 1.47 sb.append(':'); 1.48 - zeroPad(sb, (int) secFromTime(t), 2); 1.49 + zeroPad(sb, secFromTime(t), 2); 1.50 sb.append(" GMT") 1.51 .append(offset < 0 ? '-' : '+'); 1.52 zeroPad(sb, Math.abs(offset), 4); 1.53 @@ -963,20 +963,20 @@ 1.54 1.55 case FORMAT_LOCAL_DATE: 1.56 // yyyy-MM-dd 1.57 - zeroPad(sb, (int) yearFromTime(t), 4); 1.58 + zeroPad(sb, yearFromTime(t), 4); 1.59 sb.append('-'); 1.60 - zeroPad(sb, (int) monthFromTime(t) + 1, 2); 1.61 + zeroPad(sb, monthFromTime(t) + 1, 2); 1.62 sb.append('-'); 1.63 - zeroPad(sb, (int) dayFromTime(t), 2); 1.64 + zeroPad(sb, dayFromTime(t), 2); 1.65 break; 1.66 1.67 case FORMAT_LOCAL_TIME: 1.68 // HH:mm:ss 1.69 - zeroPad(sb, (int) hourFromTime(t), 2); 1.70 + zeroPad(sb, hourFromTime(t), 2); 1.71 sb.append(':'); 1.72 - zeroPad(sb, (int) minFromTime(t), 2); 1.73 + zeroPad(sb, minFromTime(t), 2); 1.74 sb.append(':'); 1.75 - zeroPad(sb, (int) secFromTime(t), 2); 1.76 + zeroPad(sb, secFromTime(t), 2); 1.77 break; 1.78 1.79 default: 1.80 @@ -996,19 +996,19 @@ 1.81 final StringBuilder sb = new StringBuilder(29); 1.82 final double t = nd.getTime(); 1.83 // EEE, dd MMM yyyy HH:mm:ss z 1.84 - sb.append(weekDays[(int) weekDay(t)]) 1.85 + sb.append(weekDays[weekDay(t)]) 1.86 .append(", "); 1.87 - zeroPad(sb, (int) dayFromTime(t), 2); 1.88 + zeroPad(sb, dayFromTime(t), 2); 1.89 sb.append(' ') 1.90 - .append(months[(int) monthFromTime(t)]) 1.91 + .append(months[monthFromTime(t)]) 1.92 .append(' '); 1.93 - zeroPad(sb, (int) yearFromTime(t), 4); 1.94 + zeroPad(sb, yearFromTime(t), 4); 1.95 sb.append(' '); 1.96 - zeroPad(sb, (int) hourFromTime(t), 2); 1.97 + zeroPad(sb, hourFromTime(t), 2); 1.98 sb.append(':'); 1.99 - zeroPad(sb, (int) minFromTime(t), 2); 1.100 + zeroPad(sb, minFromTime(t), 2); 1.101 sb.append(':'); 1.102 - zeroPad(sb, (int) secFromTime(t), 2); 1.103 + zeroPad(sb, secFromTime(t), 2); 1.104 sb.append(" GMT"); 1.105 return sb.toString(); 1.106 } 1.107 @@ -1023,19 +1023,19 @@ 1.108 final StringBuilder sb = new StringBuilder(24); 1.109 final double t = nd.getTime(); 1.110 // yyyy-MM-dd'T'HH:mm:ss.SSS'Z' 1.111 - zeroPad(sb, (int) yearFromTime(t), 4); 1.112 + zeroPad(sb, yearFromTime(t), 4); 1.113 sb.append('-'); 1.114 - zeroPad(sb, (int) monthFromTime(t) + 1, 2); 1.115 + zeroPad(sb, monthFromTime(t) + 1, 2); 1.116 sb.append('-'); 1.117 - zeroPad(sb, (int) dayFromTime(t), 2); 1.118 + zeroPad(sb, dayFromTime(t), 2); 1.119 sb.append('T'); 1.120 - zeroPad(sb, (int) hourFromTime(t), 2); 1.121 + zeroPad(sb, hourFromTime(t), 2); 1.122 sb.append(':'); 1.123 - zeroPad(sb, (int) minFromTime(t), 2); 1.124 + zeroPad(sb, minFromTime(t), 2); 1.125 sb.append(':'); 1.126 - zeroPad(sb, (int) secFromTime(t), 2); 1.127 + zeroPad(sb, secFromTime(t), 2); 1.128 sb.append('.'); 1.129 - zeroPad(sb, (int) msFromTime(t), 3); 1.130 + zeroPad(sb, msFromTime(t), 3); 1.131 sb.append("Z"); 1.132 return sb.toString(); 1.133 } 1.134 @@ -1072,29 +1072,30 @@ 1.135 } 1.136 1.137 // ECMA 15.9.1.3 Year Number 1.138 - private static double timeFromYear(final double y) { 1.139 + private static double timeFromYear(final int y) { 1.140 return dayFromYear(y) * msPerDay; 1.141 } 1.142 1.143 - private static double yearFromTime(final double t) { 1.144 - double y = Math.floor(t / (msPerDay * 365.2425)) + 1970; 1.145 + // ECMA 15.9.1.3 Year Number 1.146 + private static int yearFromTime(final double t) { 1.147 + int y = (int) Math.floor(t / (msPerDay * 365.2425)) + 1970; 1.148 final double t2 = timeFromYear(y); 1.149 if (t2 > t) { 1.150 y--; 1.151 - } else if (t2 + msPerDay * daysInYear((int) y) <= t) { 1.152 + } else if (t2 + msPerDay * daysInYear(y) <= t) { 1.153 y++; 1.154 } 1.155 return y; 1.156 } 1.157 1.158 - private static double dayWithinYear(final double t, final double year) { 1.159 - return day(t) - dayFromYear(year); 1.160 + private static int dayWithinYear(final double t, final int year) { 1.161 + return (int) (day(t) - dayFromYear(year)); 1.162 } 1.163 1.164 - private static double monthFromTime(final double t) { 1.165 - final double year = yearFromTime(t); 1.166 - final double day = dayWithinYear(t, year); 1.167 - final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0]; 1.168 + private static int monthFromTime(final double t) { 1.169 + final int year = yearFromTime(t); 1.170 + final int day = dayWithinYear(t, year); 1.171 + final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0]; 1.172 int month = 0; 1.173 1.174 while (month < 11 && firstDay[month + 1] <= day) { 1.175 @@ -1103,10 +1104,10 @@ 1.176 return month; 1.177 } 1.178 1.179 - private static double dayFromTime(final double t) { 1.180 - final double year = yearFromTime(t); 1.181 - final double day = dayWithinYear(t, year); 1.182 - final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0]; 1.183 + private static int dayFromTime(final double t) { 1.184 + final int year = yearFromTime(t); 1.185 + final int day = dayWithinYear(t, year); 1.186 + final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0]; 1.187 int month = 0; 1.188 1.189 while (month < 11 && firstDay[month + 1] <= day) { 1.190 @@ -1121,11 +1122,8 @@ 1.191 return firstDay[month]; 1.192 } 1.193 1.194 - private static double weekDay(final double time) { 1.195 - if (isNaN(time)) { 1.196 - return NaN; 1.197 - } 1.198 - final double day = (day(time) + 4) % 7; 1.199 + private static int weekDay(final double time) { 1.200 + final int day = (int) (day(time) + 4) % 7; 1.201 return day < 0 ? day + 7 : day; 1.202 } 1.203 1.204 @@ -1140,26 +1138,26 @@ 1.205 } 1.206 1.207 // ECMA 15.9.1.10 Hours, Minutes, Second, and Milliseconds 1.208 - private static double hourFromTime(final double t) { 1.209 - final double h = Math.floor(t / msPerHour) % hoursPerDay; 1.210 + private static int hourFromTime(final double t) { 1.211 + final int h = (int) (Math.floor(t / msPerHour) % hoursPerDay); 1.212 return h < 0 ? h + hoursPerDay: h; 1.213 } 1.214 - private static double minFromTime(final double t) { 1.215 - final double m = Math.floor(t / msPerMinute) % minutesPerHour; 1.216 + private static int minFromTime(final double t) { 1.217 + final int m = (int) (Math.floor(t / msPerMinute) % minutesPerHour); 1.218 return m < 0 ? m + minutesPerHour : m; 1.219 } 1.220 1.221 - private static double secFromTime(final double t) { 1.222 - final double s = Math.floor(t / msPerSecond) % secondsPerMinute; 1.223 + private static int secFromTime(final double t) { 1.224 + final int s = (int) (Math.floor(t / msPerSecond) % secondsPerMinute); 1.225 return s < 0 ? s + secondsPerMinute : s; 1.226 } 1.227 1.228 - private static double msFromTime(final double t) { 1.229 - final double m = t % msPerSecond; 1.230 + private static int msFromTime(final double t) { 1.231 + final int m = (int) (t % msPerSecond); 1.232 return m < 0 ? m + msPerSecond : m; 1.233 } 1.234 1.235 - private static double valueFromTime(final int unit, final double t) { 1.236 + private static int valueFromTime(final int unit, final double t) { 1.237 switch (unit) { 1.238 case YEAR: return yearFromTime(t); 1.239 case MONTH: return monthFromTime(t); 1.240 @@ -1180,12 +1178,12 @@ 1.241 // ECMA 15.9.1.12 MakeDay (year, month, date) 1.242 private static double makeDay(final double year, final double month, final double date) { 1.243 final double y = year + Math.floor(month / 12); 1.244 - double m = month % 12; 1.245 + int m = (int) (month % 12); 1.246 if (m < 0) { 1.247 m += 12; 1.248 } 1.249 - double d = Math.floor(dayFromYear(y)); 1.250 - d += dayFromMonth((int) m, (int) y); 1.251 + double d = dayFromYear(y); 1.252 + d += dayFromMonth(m, (int) y); 1.253 1.254 return d + date - 1; 1.255 } 1.256 @@ -1257,13 +1255,13 @@ 1.257 nullReturn = true; 1.258 } 1.259 1.260 - if (! nullReturn) { 1.261 + if (!nullReturn && !isNaN(time)) { 1.262 d[i - start] = valueFromTime(i, time); 1.263 } 1.264 } 1.265 } 1.266 1.267 - return nullReturn? null : d; 1.268 + return nullReturn ? null : d; 1.269 } 1.270 1.271 // ECMA 15.9.1.14 TimeClip (time)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/script/basic/JDK-8025163.js Sat Sep 21 10:11:15 2013 +0200 2.3 @@ -0,0 +1,39 @@ 2.4 +/* 2.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/** 2.28 + * JDK-8025163: Date methods should not return -0 2.29 + * 2.30 + * @test 2.31 + * @run 2.32 + */ 2.33 + 2.34 +print(1 / (new Date(0, 0, 1)).getYear()); 2.35 +print(1 / (new Date(1969, 1, 2)).getDay()); 2.36 +print(1 / (new Date(1969, 0, 1)).getHours()); 2.37 +print(1 / (new Date(1969, 0, 1)).getHours()); 2.38 +print(1 / (new Date(1969, 0, 1)).getMinutes()); 2.39 +print(1 / (new Date(1969, 0, 1)).getSeconds()); 2.40 +print(1 / (new Date(1969, 0, 1)).getMilliseconds()); 2.41 +print(1 / (new Date(1969, 0, 1)).getMilliseconds()); 2.42 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/script/basic/JDK-8025163.js.EXPECTED Sat Sep 21 10:11:15 2013 +0200 3.3 @@ -0,0 +1,8 @@ 3.4 +Infinity 3.5 +Infinity 3.6 +Infinity 3.7 +Infinity 3.8 +Infinity 3.9 +Infinity 3.10 +Infinity 3.11 +Infinity