8025163: Date methods should not return -0

Sat, 21 Sep 2013 10:11:15 +0200

author
hannesw
date
Sat, 21 Sep 2013 10:11:15 +0200
changeset 570
b8d9a63578e2
parent 569
16b6db9f7225
child 571
8f6304373671
child 572
c5475f5d4647

8025163: Date methods should not return -0
Reviewed-by: lagergren, jlaskey

src/jdk/nashorn/internal/objects/NativeDate.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8025163.js file | annotate | diff | comparison | revisions
test/script/basic/JDK-8025163.js.EXPECTED file | annotate | diff | comparison | revisions
     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

mercurial