Steve B
Steve B

Reputation: 577

How to convert UTC time format to Date in Java

I have to call a web service which is expecting a Date field but they want it in the following format YYYY-MM-DDThh:mm:ss.sssZ. How can I do this?

I tried the following

OffsetDateTime transactionTime = OffsetDateTime.now(ZoneOffset.UTC);

Date.from(transactionTime.toInstant());

but this didn't work. transactionTime is 2021-06-01T15:11:09.942843400Z, but Date.from converts it to Tue Jun 01 11:11:09 EDT 2021.

BTW, I'm using Java 11

Upvotes: 0

Views: 895

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79085

Use DateTimeFormatter to format the Date-Time object

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

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

Output:

2021-06-01T15:49:45.198Z

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

What if I want to use java.util.Date?

For any reason, if you need to convert this object of OffsetDateTime to an object of java.util.Date, you can do so as follows:

Date date = Date.from(transactionTime.toInstant());

Note that a java.util.Date object is not a real Date-Time object like the modern Date-Time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since Date does not have timezone information, it applies the JVM's timezone to return the value of Date#toString in the format, EEE MMM dd HH:mm:ss z yyyy calculated from this milliseconds value. If you need to print the Date-Time in a different format and timezone, you will need to use a SimpleDateFormat with the desired format and the timezone set to the applicable one e.g.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDate = sdf.format(date);
System.out.println(strDate);

Output:

2021-06-01T15:49:45.198Z

Some other important notes:

  1. 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*.
  2. Most of the symbols that you have used in YYYY-MM-DDThh:mm:ss.sssZ are wrong. Check the description of the symbols from the documentation pages of DateTimeFormatter and SimpleDateFormat.

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

Upvotes: 2

Basil Bourque
Basil Bourque

Reputation: 338775

Instant.now().toString()

See that code run live at IdeOne.com.

2021-06-01T15:21:16.783779Z

That format is defined in the ISO 8601 standard. The Z on end means an offset-from-UTC of zero hours-minutes-seconds. Pronounced “Zulu”.

Use java.time.Instant to represent a moment as seen in UTC.

Going the other direction, from text to object.

Instant.parse( "2021-06-01T15:21:16.783779Z" ) 

If you want only milliseconds, you can lop off any microseconds and nanoseconds by truncating.

Instant.now().truncatedTo( ChronoUnit.MILLIS ) ;

Never use the legacy Date class. Use only the java.time classes.

Upvotes: 4

Related Questions