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

5

5

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).

Tanganyika answered 3/10, 2019 at 8:8 Comment(0)
C
3

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')
Conferva answered 4/10, 2019 at 15:26 Comment(0)
E
6

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')
Esquibel answered 3/10, 2019 at 10:16 Comment(2)
I'd recommend this approach to anyone who needs to keep using the java.util.Date object.Considered
This is the only real answer to the question. Yes, java.time and/or Joda-Time are much better for Date/Time programming needs, but not everyone has the opportunity to switchJock
C
3

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')
Conferva answered 4/10, 2019 at 15:26 Comment(0)
S
2

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.

Somatoplasm answered 3/10, 2019 at 8:40 Comment(0)
L
1

For Groovy 2.5 and above, you can get the same behavior as in Groovy 2.4 by adding the groovy-dateutil module to your classpath. It became an optional module in Groovy 2.5 since many folks are using the now preferred java.time classes. Groovy's extension methods for the new classes are in the groovy-datetime module which is referenced in the groovy-all POM.

Lordship answered 3/3 at 4:8 Comment(0)
A
0

You can use Calendar to achieve that

    Calendar cal = new GregorianCalendar();
    cal.add(Calendar.DATE, 90);
    Date date = cal.getTime();

All steps must be separate and not in a single line.

Audry answered 17/12, 2020 at 16:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.