2

I am using the Java Instant to get the current date-time information, but it returns to me the UTC Datetime with Z or with [Europe/Berlin]. How do I get the only Datetime information with timezone offset?

Following is the code I have:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;


public class Test {
    public static void main(String[] args) {
        Instant instant = Instant.now();

        System.out.println("Current Time : " + instant);

        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        System.out.println("LocalDateTime : " + localDateTime);

        ZonedDateTime zonedDateTime1 = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
        System.out.println("ZonedDateTime1: " + zonedDateTime1);
    }
}

Following is the output I have:

Current Time : 2022-04-13T08:22:35.362644Z
LocalDateTime : 2022-04-13T10:22:35.362644
ZonedDateTime1: 2022-04-13T10:22:35.362644+02:00[Europe/Berlin]

My expected output is:

expected output: 2022-04-13T10:22:35.362644+02:00

How can I get my expected output 2022-04-13T10:22:35.362644+02:00 using Instant? I am aware that I can do the substring(), but I do not want to do that. I am looking for some direct approach to achieve this. Please provide some suggestion.

Also, I do not wish to pass the region information as the application can be accessed across various regions so do not wish to hardcode the region in code.

2
  • 7
    Why do you want to use Instant when that doesn't include any offset information? It seems to me that what you need is OffsetDateTime. (And if ZonedDateTime has all the information you need, but you need a different format, then use a DateTimeFormatter rather than expecting the default string representation to be exactly what you want.) Commented Apr 13, 2022 at 8:29
  • 1
    I agree with @JonSkeet in the understanding that an OffsetDateTime is what you appear to need. When right now I executed OffsetDateTime.now(ZoneId.systemDefault()) in German time zone, I got 2022-04-13T11:34:10.078283+02:00. Commented Apr 13, 2022 at 9:34

2 Answers 2

3

I don't see why you need Instant. The following code gives your desired output:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Test {

    public static void main(String[] args) {
        System.out.println(ZonedDateTime.now().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
    }
}

When I run the above code, I get the following output:

2022-04-13T12:25:31.1157466+03:00

My local time zone is three hours ahead of UTC.

Sign up to request clarification or add additional context in comments.

3 Comments

It would make more sense to use OffsetDateTime.now() if only offset information is needed though.
@MarkRotteveel they both give the same output.
Sure, but my point is that if the OP is looking for offset only, they should use OffsetDateTime, not ZonedDateTime.
2

tl;dr

How do I get the only Datetime information with timezone offset?

OffsetDateTime
.now() 
.toString()

2022-04-13T22:47:58.123793+02:00

Or, state your desired/expected time zone explicitly rather than rely implicitly on the JVM’s current default time zone.

OffsetDateTime
.now(
    ZoneId.of( "Europe/Berlin" )
) 
.toString()

OffsetDateTime

You asked:

How do I get the only Datetime information with timezone offset?

To represent a date with time-of-day as seen in an offset of some number of hours-minutes-seconds from the meridian of UTC, use the OffsetDateTime class.

Calling OffsetDateTime.now() implicitly applies the offset of your JVM’s current default time zone.

OffsetDateTime odt = OffsetDateTime.now() ;  // Uses current offset.

See that code run live at IdeOne.com.

2022-04-13T20:47:58.059193Z

The Z on the end means an offset of zero from UTC, and is pronounced “Zulu”.

The IdeOne.com site happens to use a default time zone of UTC itself, a.k.a. “Zulu time”. So let’s specify a time zone to see a different offset in action.

OffsetDateTime odt2 = OffsetDateTime.now( ZoneId.of( "Europe/Berlin" ) ) ;  // Use the offset currently in effect for this particular time zone.

2022-04-13T22:47:58.123793+02:00

ZonedDateTime

Usually it is better to use a full time zone rather than a mere offset. A time zone is a named history of the past, present, and future changes to the offset used by the people of a particular region as decided by their politicians.

ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "Europe/Berlin" ) ) ;

2022-04-13T22:47:58.126001+02:00[Europe/Berlin]

But occasionally we need to deal with an offset rather than a zone. Doing SQL work with a database is one important example, as the SQL standard was written only for offsets rather than time zones.

Instant

You asked:

How can I get my expected output 2022-04-13T10:22:35.362644+02:00 using Instant?

You cannot.

The Instant class represents a moment as seen with an offset of zero hours-minutes-seconds from the meridian of UTC. An Instant object by definition is always “in UTC”, that is, carries an offset of zero.

If you have an Instant in hand, you can adjust into a time zone or offset. Rather than assume you know the correct offset, I suggest going through a time zone to let java.time look up the offset in effect at the moment.

ZoneId z = ZoneId.of( "Europe/Berlin" ) ;
ZonedDateTime zdt = myInstant.atZone( z ) ;
OffsetDateTime odt = zdt.toOffsetDateTime() ;

Tip: Be aware that politicians change the time zone rules, and therefore the offset, with surprising frequency and disturbingly little forewarning. Be sure to keep the tzdata up to date if any zone of interest to you is changing. You will find tzdata file in (a) your JVM, (b) your host operating system, and (c) perhaps in ancillary systems such as your database server.

LocalDateTime

Never use LocalDateTime class when tracking a moment, a specific point on the timeline. This class purposely lacks the context of a time zone or offset-from-UTC. An object of LocalDateTime carries only a date and a time-of-day, nothing more.

I cannot imagine any scenario where calling LocalDateTime#now or LocalDateTime.ofInstant would be the right thing to do. In doing so, you would be purposely discarding vital information (the time zone or offset).

2 Comments

when I use Instant.now() I got wrong date, 2 days diff from what it should be. what might causing this?
@etomun Post a Question with your exact code, example input, expected output, and actual results.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.