Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Date.plus not working in 2.5.4 Groovy Runtime, what is the alternative?

Tags:

java

date

groovy

We want to add days to the current date and format it in a specific way. This was solved in Groovy 2.4.13 and the following date manipulation works fine:

​today = new Date()+90;today.format('yyyy-MM-dd HH:mm:ss.S');

Result: 2019-12-02 08:07:15.294

In Groovy 2.5.4 the same expression throws this exception:

groovy.lang.MissingMethodException: No signature of method: java.util.Date.plus() is applicable for argument types: (Integer) values: [90] Possible solutions: parse(java.lang.String), split(groovy.lang.Closure), use([Ljava.lang.Object;), is(java.lang.Object), wait(), clone() at Script1.run(Script1.groovy:3)

I was able to reproduce this behaviour in "Groovy sandboxes" online:

Working fine here: groovy-playground (Version 2.4.1.5) Failing here: groovyconsole (Version 2.5.7)

What is the working alternative in this case? I have read about a new Date API, but couldn't find the details about how to use it, with date manipulation (+ 90 days for example).

like image 655
aschirbaum Avatar asked Oct 03 '19 08:10

aschirbaum


3 Answers

Take a look at TimeCategory

import groovy.time.TimeCategory
def theDate = use(TimeCategory){new Date() + 90.days}.format('yyyy-MM-dd HH:mm:ss.S')
like image 163
Mike W Avatar answered Nov 15 '22 11:11

Mike W


I agree with Ole V.V.'s recommendations to use the new Date/Time API. Here is how you would write his Java sample in a more Groovy style.

// you can assemble aggregate types by left shifting the aggregates
// I'm not endorsing this approach, necessarily, just pointing it out as an alternative 
ZonedDateTime now = LocalDate.now() << LocalTime.now() << ZoneId.of('Africa/Bamako')

// the plus operator is overloaded
ZonedDateTime in90Days = now + 90

// you can pass a String to format without needed a full DateTimeFormatter instance
println in90Days.format('uuuu-MM-dd HH:mm:ss.S')
like image 36
bdkosher Avatar answered Nov 15 '22 09:11

bdkosher


While Groovy adds some further support for the old Java Date class, I still believe that you should not use it. It was always poorly designed and is now long outdated. Instead use java.time, the modern Java date and time API. I am sorry that I will have to trust you to translate from Java code.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.S");
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Africa/Bamako"));
    ZonedDateTime in90Days = now.plusDays(90);
    System.out.println(in90Days.format(formatter));

Output when running just now was:

2020-01-01 08:37:13.3

Please substitute your desired time zone if it didn’t happen to be Africa/Bamako.

Link: Oracle tutorial: Date Time explaining how to use java.time.

like image 32
Ole V.V. Avatar answered Nov 15 '22 10:11

Ole V.V.