Home > Net >  Java Instant Datetime how to get the Datetime with timezone offset only? without the region informat
Java Instant Datetime how to get the Datetime with timezone offset only? without the region informat

Time:04-14

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.

CodePudding user response:

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.

CodePudding user response:

tl;dr

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

OffsetDateTime
.now() 
.toString()

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

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

  • Related