toInstant() in Calendar is showing in GMT instead of Local time - java

I am trying to convert a Calendar instance to instant and i am doing that as follows
Calendar cal = new GregorianCalendar();
System.out.println(cal.getTime());
Instant inst = cal.toInstant();
System.out.println(inst.toString());
And, the output for it is as follows
Fri Oct 30 17:23:40 IST 2015
2015-10-30T11:53:40.037Z
So, my question is about the difference in the outputs from the Calendar and the instant. The output from the instant is in GMT instead of the local time.
I have not seen any documentation that says that Instant class only gives the date in GMT. So, i am not sure why this is happening.

Invoking toString on an Instant produces output like the following:
2013-05-30T23:38:23.085Z
This format follows the ISO-8601 standard for representing date and
time.
Have a look at:
Tutorial
Instant class documentation

The answer by Rawat is correct. An Instant is always in UTC by definition.
The format of the string representation generated by the toString method is standard, defined by ISO 8601.
The Instant class is part of the java.time framework built into Java 8 and later. The new classes in this framework supplant the old java.util.Date/.Calendar classes from the early days of Java.
Avoid the old classes as they are notoriously troublesome. Do not mix up the old and new. The conversion methods such as toInstant are intended only for use when interoperating with old code has not yet been updated for the new types.
To adjust an Instant into a time zone, specify the time zone via a ZoneId object to produce a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Do not be confused by the "Local" in LocalDateTime class. That class represents the vague idea of a date-time. It does not apply to any particular time zone and is therefore not tied to the timeline.

Related

Mark time stamp on message in Java across JVM [duplicate]

How do I get the current date and time in Java?
I am looking for something that is equivalent to DateTime.Now from C#.
Just construct a new Date object without any arguments; this will assign the current date and time to the new object.
import java.util.Date;
Date d = new Date();
In the words of the Javadocs for the zero-argument constructor:
Allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond.
Make sure you're using java.util.Date and not java.sql.Date -- the latter doesn't have a zero-arg constructor, and has somewhat different semantics that are the topic of an entirely different conversation. :)
The Java Date and Calendar classes are considered by many to be poorly designed. You should take a look at Joda Time, a library commonly used in lieu of Java's built-in date libraries.
The equivalent of DateTime.Now in Joda Time is:
DateTime dt = new DateTime();
Update
As noted in the comments, the latest versions of Joda Time have a DateTime.now() method, so:
DateTime dt = DateTime.now();
tl;dr
Instant.now()
java.time
The java.util.Date class has been outmoded by the new java.time package (Tutorial) in Java 8 and later. The old java.util.Date/.Calendar classes are notoriously troublesome, confusing, and flawed. Avoid them.
ZonedDateTime
Get the current moment in java.time.
ZonedDateTime now = ZonedDateTime.now();
A ZonedDateTime encapsulates:
Date.
Time-of-day, with a fraction of a second to nanosecond resolution.
Time zone.
If no time zone is specified, your JVM’s current default time zone is assigned silently. Better to specify your desired/expected time zone than rely implicitly on default.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.now( z );
UTC
Generally better to get in the habit of doing your back-end work (business logic, database, storage, data exchange) all in UTC time zone. The code above relies implicitly on the JVM’s current default time zone.
The Instant class represents a moment in the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
The Instant class is a basic building-block class in java.time and may be used often in your code.
When you need more flexibility in formatting, transform into an OffsetDateTime. Specify a ZoneOffset object. For UTC use the handy constant for UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Time Zone
You easily adjust to another time zone for presentation to the user. Use a proper time zone name, never the 3-4 letter codes such as EST or IST.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime nowMontreal = instant.atZone( z );
Generate a String representation of that date-time value, localized.
String output = DateTimeFormatter
.ofLocalizedDate( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
.format ( nowMontreal );
Instant
Or, to stay in UTC, use Instant. An Instant object represents a moment on the timeline, to nanosecond resolution, always in UTC. This provides the building block for a zoned date-time, along with a time zone assignment. You can think of it conceptually this way:
ZonedDateTime = Instant + ZoneId
You can extract an Instant from a ZonedDateTime.
Instant instantNow = zdt.toInstant();
You can start with an Instant. No need to specify a time zone here, as Instant is always in UTC.
Instant now = Instant.now();
I prefer using the Calendar object.
Calendar now = GregorianCalendar.getInstance()
I find it much easier to work with. You can also get a Date object from the Calendar.
http://java.sun.com/javase/6/docs/api/java/util/GregorianCalendar.html
In Java 8 it's:
ZonedDateTime dateTime = ZonedDateTime.now();
import java.util.Date;
Date now = new Date();
Note that the Date object is mutable and if you want to do anything sophisticated, use jodatime.
java.lang.System.currentTimeMillis(); will return the datetime since the epoch
import org.joda.time.DateTime;
DateTime now = DateTime.now();
If you create a new Date object, by default it will be set to the current time:
import java.util.Date;
Date now = new Date();
Java has always got inadequate support for the date and time use cases. For example, the existing classes (such as java.util.Date and SimpleDateFormatter) aren’t thread-safe which can lead to concurrency issues. Also there are certain flaws in API. For example, years in java.util.Date start at 1900, months start at 1, and days start at 0—not very intuitive. These issues led to popularity of third-party date and time libraries, such as Joda-Time. To address a new date and time API is designed for Java SE 8.
LocalDateTime timePoint = LocalDateTime.now();
System.out.println(timePoint);
As per doc:
The method now() returns the current date-time using the system
clock and default time-zone, not null. It obtains the current
date-time from the system clock in the default time-zone. This will
query the system clock in the default time-zone to obtain the current
date-time. Using this method will prevent the ability to use an
alternate clock for testing because the clock is hard-coded.

Time information is missing when converting LocalDate to java.util.Date

Time information is missing when converting LocalDate to java.util.Date
My input date is in the format "2019-08-30T19:47:22+00:00" (String). I have to convert it to java.util.Data. I would like to do it using java 8.
String input = "2019-08-30T19:47:22+00:00";
Date date = null;
LocalDate dateTime = LocalDate.parse(input, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
date = Date.from(dateTime.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println("Parsed from LoacalDate: " + date);
System.out.println("From new Date(): " + new Date());
Output
Parsed from LoacalDate: Fri Aug 30 00:00:00 CDT 2019 From new
Date(): Fri Aug 30 17:16:23 CDT 2019
In the output time information is missing. How to get time information?
tl;dr
LocalDate stores only a date, so wrong class to use.
java.util.Date // Terrible class, now legacy. Avoid. Replaced by `java.time.Instant` in JSR 310. Use only where required, to interoperate with old code not yet updated for java.time.
.from( // Convert from modern `Instant` to legacy `Date`.
OffsetDateTime // The modern class to represent a moment in the context of an offset-from-UTC (a number of hours-minutes-seconds). Not to be confused with a time zone, which is a history of changes to the offset used by the people of a particular region.
.parse( "2019-08-30T19:47:22+00:00" ) // Parse text into an `OffsetDateTime` object.
.toInstant() // Extract an `Instant`, a more basic building-block class that represent a moment in UTC (an offset of zero).
)
.toString() // Generates text representing the value of the `Date`. But this method lies! It dynamically applies your JVM’s current default time zone while generating the text.
Note that java.util.Date::toString tells a lie! That method dynamically applies the JVM’s current default time zone while generating the text to represent the value that is actually in UTC. One of many reasons to never use this Date class.
Details
You are using the wrong classes.
LocalDate
LocalDate represents a date only, no time-of-day, no time zone or offset.
By parsing your input representing a moment as simply a date, you are lopping off the time-of-day and the offset-from-UTC.
OffsetDateTime
Your input "2019-08-30T19:47:22+00:00" represents a moment: a date, a time-of-day, an offset-from-UTC of zero hours-minutes-seconds. So parse that as a OffsetDateTime.
OffsetDateTime odt = OffsetDateTime.parse( "2019-08-30T19:47:22+00:00" ) ;
Avoid legacy date-time classes
The java.util.Date class is terrible, and should no longer be used. It was supplanted years ago by the modern java.time classes as of the adoption of JSR 310.
However, if you must interoperate with old code not yet updated to java.time, you can convert back-and-forth. Look to new to…/from… methods added to the old classes.
The equivalent of java.util.Date is java.time.Instant, both representing a moment in UTC (though with a difference in resolution, milliseconds versus nanoseconds). So extract a basic Instant object from our more flexible OffsetDateTime.
Instant instant = odt.toInstant() ;
java.util.Date d = Date.from( instant ) ;
I was able to make it work using the following code snippet
LocalDateTime dateTime = LocalDateTime.parse(input,DateTimeFormatter.ISO_OFFSET_DATE_TIME);
date = Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("Parsed from LoacalDate:" + date);
System.out.println("From new Date():" + new Date());

How to set Date object to point to different time zone in java

In the code below I have used calendar object to initialize time Zone to GMT and get the time accordingly but when I put back in date object, its automatically converting to my local time zone i.e. IST.
Calendar gmt = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dt=gmt.getTime();
Could anyone suggest a way through which I can retain the GMT format in date object also.
its automatically converting to my local time zone i.e. IST
No it's not. A Date object doesn't have a time zone - it's just an instant in time.
You'll see the system-local time zone if you call toString() on a Date, because that's unfortunately what Date.toString() does... but the time zone is not part of the information stored in a Date.
If you want to see a textual representation of a Date in a particular time zone, use DateFormat and set the time zone that you want to use.
java.time
The other answers are correct. The toString method silently applies your JVM’s current default time zone. This is one of many poor design choices in the old date-time classes. Dump those old classes. Move on to the java.time framework built into Java 8 and later.
An Instant is a moment on the time line in UTC.
Instant now = Instant.now();
Apply a time zone (ZoneId) to an Instant to get a ZonedDateTime.
Why are we bothering to create a ZonedDateTime in UTC if the Instant is already in UTC? Because a ZonedDateTime gives you flexibility in formatting String representations of the date-time values. The java.time.format package does not work with Instant objects.
A subclass of ZoneId, ZoneOffset, has a constant for UTC.
ZonedDateTime zdtUtc = ZonedDateTime.ofInstant( ZoneOffset.UTC );
Adjust into any desired time zone.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = ZonedDateTime.ofInstant( instant , zoneId );
Use proper time zone names
Avoid using 3-4 letter codes for time zones. They are neither standardized nor unique. By IST did you mean India Standard Time or Irish Standard Time?
Use standard time zone names. Most are in the pattern of continent/region. For India, Asia/Kolkata. For Ireland, Europe/Dublin.
The Date class does not represent a timezone. It's toString method uses the default platform time zone to output a human readable timestamp, internally it's just a long.

DateTime showing different date when converted to date

I am currrently working with Java JODATIME DateTime. I have a dateTime as 2015-09-08T11:00:00.000Z , When I convert to date using toDate().
I am getting the date object as Tue Sep 08 06:00:00 CDT 2015.
DateTime dateTime = 2015-09-08T11:00:00.000Z; // Not a string I am getting this date from another API.
Date date = dateTime.toDate(); //Tue Sep 08 06:00:00 CDT 2015.
May I know what is the thing happening here?
A Date object simply holds the number of milliseconds since 1 Jan 1970 UTC. It does not contain presentation logic, so your comment that it equates to 6am CDT shows that something (your IDE, or some date formatter) has applied a timezone in order to render the date to a human readable form. The code is actually working correctly.
Apparently you are calling the toString method on the java.util.Date object. That class’ implementation of toString has the confusing feature of silently applying your JVM’s current default time zone to the date-time value as it generates a String representation.
The java.util.Date object itself has no time zone, and is always in UTC.
This is one of many reasonable avoid these old java.util.Date/.Calendar classes. Use java.time, now built into Java 8 and later. For older versions of Java, use Joda-Time.
Also this topic has been addressed many many times before on StackOverflow. Please search before posting.
A quick bit of example code in java.time. An Instant is a moment on the timeline in UTC. Your input string happens to be in standard ISO 8601 format which java.time uses by default when parsing/generating strings. So you can parse directly without bothering to specify a parsing pattern.
String input = "2015-09-08T11:00:00.000Z";
Instant instant = Instant.parse( input );
Adjust that Instant into a specific time zone to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Search StackOverflow.com for many more examples of java.time.
Actually there is a time zone buried in the source code of java.util.Date but is ignored for practical purposes.

How to get the current date and time

How do I get the current date and time in Java?
I am looking for something that is equivalent to DateTime.Now from C#.
Just construct a new Date object without any arguments; this will assign the current date and time to the new object.
import java.util.Date;
Date d = new Date();
In the words of the Javadocs for the zero-argument constructor:
Allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond.
Make sure you're using java.util.Date and not java.sql.Date -- the latter doesn't have a zero-arg constructor, and has somewhat different semantics that are the topic of an entirely different conversation. :)
The Java Date and Calendar classes are considered by many to be poorly designed. You should take a look at Joda Time, a library commonly used in lieu of Java's built-in date libraries.
The equivalent of DateTime.Now in Joda Time is:
DateTime dt = new DateTime();
Update
As noted in the comments, the latest versions of Joda Time have a DateTime.now() method, so:
DateTime dt = DateTime.now();
tl;dr
Instant.now()
java.time
The java.util.Date class has been outmoded by the new java.time package (Tutorial) in Java 8 and later. The old java.util.Date/.Calendar classes are notoriously troublesome, confusing, and flawed. Avoid them.
ZonedDateTime
Get the current moment in java.time.
ZonedDateTime now = ZonedDateTime.now();
A ZonedDateTime encapsulates:
Date.
Time-of-day, with a fraction of a second to nanosecond resolution.
Time zone.
If no time zone is specified, your JVM’s current default time zone is assigned silently. Better to specify your desired/expected time zone than rely implicitly on default.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.now( z );
UTC
Generally better to get in the habit of doing your back-end work (business logic, database, storage, data exchange) all in UTC time zone. The code above relies implicitly on the JVM’s current default time zone.
The Instant class represents a moment in the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
The Instant class is a basic building-block class in java.time and may be used often in your code.
When you need more flexibility in formatting, transform into an OffsetDateTime. Specify a ZoneOffset object. For UTC use the handy constant for UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Time Zone
You easily adjust to another time zone for presentation to the user. Use a proper time zone name, never the 3-4 letter codes such as EST or IST.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime nowMontreal = instant.atZone( z );
Generate a String representation of that date-time value, localized.
String output = DateTimeFormatter
.ofLocalizedDate( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
.format ( nowMontreal );
Instant
Or, to stay in UTC, use Instant. An Instant object represents a moment on the timeline, to nanosecond resolution, always in UTC. This provides the building block for a zoned date-time, along with a time zone assignment. You can think of it conceptually this way:
ZonedDateTime = Instant + ZoneId
You can extract an Instant from a ZonedDateTime.
Instant instantNow = zdt.toInstant();
You can start with an Instant. No need to specify a time zone here, as Instant is always in UTC.
Instant now = Instant.now();
I prefer using the Calendar object.
Calendar now = GregorianCalendar.getInstance()
I find it much easier to work with. You can also get a Date object from the Calendar.
http://java.sun.com/javase/6/docs/api/java/util/GregorianCalendar.html
In Java 8 it's:
ZonedDateTime dateTime = ZonedDateTime.now();
import java.util.Date;
Date now = new Date();
Note that the Date object is mutable and if you want to do anything sophisticated, use jodatime.
java.lang.System.currentTimeMillis(); will return the datetime since the epoch
import org.joda.time.DateTime;
DateTime now = DateTime.now();
If you create a new Date object, by default it will be set to the current time:
import java.util.Date;
Date now = new Date();
Java has always got inadequate support for the date and time use cases. For example, the existing classes (such as java.util.Date and SimpleDateFormatter) aren’t thread-safe which can lead to concurrency issues. Also there are certain flaws in API. For example, years in java.util.Date start at 1900, months start at 1, and days start at 0—not very intuitive. These issues led to popularity of third-party date and time libraries, such as Joda-Time. To address a new date and time API is designed for Java SE 8.
LocalDateTime timePoint = LocalDateTime.now();
System.out.println(timePoint);
As per doc:
The method now() returns the current date-time using the system
clock and default time-zone, not null. It obtains the current
date-time from the system clock in the default time-zone. This will
query the system clock in the default time-zone to obtain the current
date-time. Using this method will prevent the ability to use an
alternate clock for testing because the clock is hard-coded.

Categories

Resources