0

So I'm working on a project and I need to do this:

The required format : 2021-06-17T09:23:01 (UTC timing)

The main thing is need to do it in Spring boot Expression

Expression exp = parser.parseExpression("code comes here");
System.out.println(exp.getValue());

I have tried so so so many combinations and below are some:

Expression exp = parser.parseExpression("new java.text.SimpleDateFormat(\"yyyy-MM-dd'T'hh:mm:ss\").format(new java.util.Date().from( new java.util.Date().toInstant().plusSeconds(5)))");
Expression exp = parser.parseExpression("new java.text.DateFormat.getInstance().format(new java.util.Date().from( new java.util.Date().toInstant().plusSeconds(5)))");
Expression exp = parser.parseExpression("new java.util.Date().toInstant().plusSeconds(5)");
Expression exp = parser.parseExpression("new java.text.SimpleDateFormat(\"yyyy-MM-dd'T'hh:mm:ss\").format(new java.util.Date().toInstant().plusSeconds(5))");

I'm stuck with at least one problem in everything.....So please try to correct it or give correct one plz

ari
  • 13
  • 2
  • 6
    Can you explain _why_ it needs to be done in a Spring Expression ? – Wim Deblauwe Jun 17 '21 at 09:39
  • 3
    Why are you mixing the legacy `java.util.Date` api and the "new" `java.time` api? Did you try creating a method that contains the code you want to have executed and once that works call that method in an expression? – Thomas Jun 17 '21 at 09:40
  • @WimDeblauwe It's client request – ari Jun 17 '21 at 09:44
  • @Thomas I can't initialize new java.time.(anything) – ari Jun 17 '21 at 09:45
  • 1
    What about `OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)`? Can you try that? – deHaar Jun 17 '21 at 09:45
  • @deHaar I can't initialize it as" new java.time.OffsetDateTime.now(ZoneOffset.UTC)" – ari Jun 17 '21 at 09:47
  • OK, then use `new Date().toInstant().plusSeconds(5).atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss"))`, might work ;-) – deHaar Jun 17 '21 at 09:49
  • No.......the ZoneOffset and DateTimeFormatter causes problem.....we have to initialize full package using new keyword.....so can't initialize it as new java.time.ZoneOffsert.UTC....literally every java.time package we can't use – ari Jun 17 '21 at 10:00

1 Answers1

3

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Demo using java.time, the modern Date-Time API:

import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        System.out.println(ZonedDateTime.now(ZoneOffset.UTC).plusSeconds(5)
                .format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss", Locale.ENGLISH)));
    }
}

Output:

2021-06-17T09:45:14

ONLINE DEMO

If you do not want to use the static methods like ZonedDateTime.now, DateTimeFormatter.ofPattern etc. (as you have commented), you can do it as shown below:

import java.time.ZoneOffset;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        System.out.println(new Date().toInstant().plusSeconds(5).atZone(ZoneOffset.UTC).format(
                new DateTimeFormatterBuilder().appendPattern("uuuu-MM-dd'T'HH:mm:ss").toFormatter(Locale.ENGLISH)));
    }
}

ONLINE DEMO

Based on this, you can create your expression as follows:

Expression exp = parser.parseExpression("new Date().toInstant().plusSeconds(5).atZone(ZoneOffset.UTC).format(new DateTimeFormatterBuilder().appendPattern(\"uuuu-MM-dd'T'HH:mm:ss\").toFormatter(Locale.ENGLISH))");

For any reason, if you need to convert this object of Instant to an object of java.util.Date, you can do so using Date#from:

Date.from(new Date().toInstant().plusSeconds(5))

Alternatively,

new Date(new Date().toInstant().plusSeconds(5).toEpochMilli())

However, you need SimpleDateFormat to format an object of java.util.Date and the problem with SimpleDateFormat is that it uses the JVM's timezone by default. If you need the date-time in a particular timezone, you need to set the timezone to SimpleDateFormat explicitly beforehand e.g.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String formatted = sdf.format(date); // date is an instance of java.util.Date

Learn more about the modern Date-Time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • You can't directly initialize anything like Instant, ZoneOffset, DateTimeFormatter – ari Jun 17 '21 at 09:51
  • 1
    @ari - Your requirement seems to be very rigid. I think the last snippet of code in my answer should meet your requirement. – Arvind Kumar Avinash Jun 17 '21 at 10:12
  • Yes.......the only thing that causes problem is ......we can't direct use ZoneOffset.UTC so we need to initialize the whole package like new java.time.ZoneOffset.UTC but the thing is its not possible inside Expressions... – ari Jun 17 '21 at 11:13
  • yes sir but I need the time in UTC only if u see my question clearly..... – ari Jun 17 '21 at 13:57