groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fabio de Matos Quaresma Gonçalves <fmato...@gmail.com>
Subject Bug: Dates.internalDate() fails to initialize miliseconds field properly
Date Tue, 09 Jun 2015 15:17:56 GMT
I found a bug on Dates class, on how it instantiates objects without
explicitly specifying the miliseconds parameter. By omission, it ends up
using the value provided by Calendar.getInstance(), which is copied over
from System.currentTimeMillis(). This is a problem when comparing dates,
even if I don't care about such high resolution.


I reproduced it using groovy console v 2.4.3 on JVM 1.8. I also cloned the
git repo and I'm sure the bug is still unsolved.

Unfortunately this code is tricky to run, I had it returning the same
amount of miliseconds if the Thread.sleep line is removed. Even with a
println in between constructors didn't guarantee the expected result.
>>>>>>>>>>>>>>>
import groovy.json.internal.Dates
import groovy.transform.TypeChecked
        Date d1 =
Dates.toDate(TimeZone.getTimeZone("GMT"),2015,06,07,23,55,59)

        Thread.sleep(1) // lets get some time between calling constructors

        Date d2 =
Dates.toDate(TimeZone.getTimeZone("GMT"),2015,06,07,23,55,59)


        println Date.getMillisOf(d1) + "!=" + Date.getMillisOf(d2)

        assert d1 == d2
<<<<<<<<<<<<<<<

The problem is in the following code (suggested fix is commented within
snippet):
>>>>>>>>>>>>>>>
    private static Date internalDate(TimeZone tz, int year, int month, int
day, int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();

        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.setTimeZone(tz);

        // missed setting ms to some deterministic value
calendar.set(Calendar.MILLISECOND, 0);

        return calendar.getTime();
    }
<<<<<<<<<<<<<<<

An alternative way to see the bug and fix it:

>>>>>>>>>>>>>>>
    public static Date toDate(TimeZone tz, int year, int month, int day,
                              int hour, int minute, int second) {
        return internalDate(tz, year, month, day, hour, minute, second);
 // this is bugged
        //return internalDate(tz, year, month, day, hour, minute,
second,0); //this will work
    }
<<<<<<<<<<<<<<<

I'd gladly submit a jira issue or a pull request, but apparently I need
permission for any of those.

I'd like to stay unsubscribed to the emailing list if possible, so please
CC me in the reply.


-- 
Fabio de Matos Gonçalves

Mime
View raw message