Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(LeaveDate);
calendar1.add(Calendar.DAY_OF_MONTH, ProcessDate);
Date fullDate1 = calendar1.getTime();
SimpleDateFormat date1 = new SimpleDateFormat("yyyy-MM-dd");
Here the output i.e., date1 is string, how to convert it to Date
tl;dr
Reading your code, apparently you want to take the current moment as seen in the current default time zone, adjust to a particular day of month, and then convert to a moment as seen in UTC to be represented by the outmoded class java.util.Date.
java.util.Date // Legacy class. Replaced by `java.time.Instant`.
.from( // New conversion method added to old class, to move between legacy and modern classes.
ZonedDateTime // Represents a moment as seen in a particular time zone.
.now() // Implicitly applies the JVM’s current default time zone.
.withDayOfMonth( yourDesiredDayOfMonthGoesHere ) // Adjust to another moment on another date. Returns another `ZonedDateTime` object immutably, rather than altering original.
.toInstant() // Adjust from time zone to UTC. Same moment, different wall-clock time.
) // Returns an object for the same moment, but as a legacy `Date` object. Avoid using this class if at all possible.
But your title asks for something different. The title asks how to generate text in a ISO 8601 standard format (YYYY-MM-DD) for a Calendar object. Assuming your Calendar object is a GregorianCalendar object, we can cast. Then we can convert to the modern java.time.ZonedDateTime object, extract the date-only java.time.LocalDate object, and generate standard text. The java.time classes use ISO 8601 formats by default when parsing/generating text, so no need for a formatting pattern.
(GregorianCalendar) yourCalendarHere // Cast from the more general `Calendar` to the more specific `GregorianCalendar`.
.toZonedDateTime() // Convert from legacy class to modern. Same moment in the same time zone. Returns a `java.time.ZonedDateTime` object.
.toLocalDate() // Strip away the time zone and the time-of-day, leaving only the date. Returns a `java.time.LocalDate` object.
.toString() // Generate text representing the value of that date in standard ISO 8601 format, YYYY-MM-DD. Returns a `String` object.
Tip: Stop using the terribly flawed legacy date-time classes. Use only java.time.
Formatters
Here the output i.e., date1 is string, how to convert it to Date
You seem to misunderstand the classes involved.
Your date1 is a variable declared to be a SimpleDateFormat object. That class is a formatter. As a formatter, its job is to generate text, not hold text nor hold a date. So your variable is misnamed, as it does not hold a date.
Avoid legacy classes
You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310. Never use Date, Calendar, SimpleDateFormat, and such.
java.time
Replace this:
Calendar calendar1 = Calendar.getInstance();
… with this:
ZonedDateTime zdt = ZonedDateTime.now() ; // Implicitly uses the JVM’s current default time zone.
I assume that in this code:
calendar1.setTime(LeaveDate);
… the LeaveDate (should have been named with initial lowercase, leaveDate) represents a java.util.Date object. And you are trying to get a calendar object set to the moment represented by that Date object.
In java.time, we use immutable objects. So, no use of set methods. In java.time, if handed a java.util.Date object, immediately convert to an Instant. Both classes represent a moment as seen in UTC, with an offset of zero hours-minutes-seconds. To convert, use the new conversion methods added to the old classes.
Instant instant = leaveDate.toInstant() ;
Adjust that moment into a time zone.
ZoneId z = ZoneId.systemDefault() ; // The JVM’s current default time zone.
ZonedDateTime zdt = instant.atZone( z ) ;
Both instant & zdt represent the same moment, the very same point on the timeline. But their date and time-of-day are adjusted for the wall-clock time used by the people of two different regions. If someone in Iceland, where they use UTC as their time zone, called someone in Tokyo, and both people looked up to see the calendar and clock on their respective walls, they would see a different time and possibly a different date.
In your line:
calendar1.add(Calendar.DAY_OF_MONTH, ProcessDate);
… I am guessing that you want to set the day-of-month while keeping the same month, year, and time-of-day. For example, let's use the 23rd. Notice that we generate a new ZonedDateTime rather than alter ("mutate") the original. Adjustments are made automatically if the result would be impossible, such as the 30th of February.
ZonedDateTime zdtForSpecificDayOfMonth = zdt.withDayOfMonth( 23 ) ; // Change day-of-month to the 23rd.
Regarding your line:
Date fullDate1 = calendar1.getTime();
… as I said above, you should avoid using Date in modern Java. But if you must do so to interoperate with old code not yet updated to java.time, extract an Instant from the ZonedDateTime object, and convert to a java.util.Date.
Instant instant = zdtForSpecificDayOfMonth.toInstant() ; // Adjust from a time zone to an offset of zero hours-minutes-seconds.
java.util.Date d = Date.from( instant ) ;
Parsing dates in Java with DateFormat or descendants
Tested with Java's REPL jshell
jshell> import java.text.SimpleDateFormat;
jshell> var df = new SimpleDateFormat("yyyy-MM-dd");
df ==> java.text.SimpleDateFormat#f67a0200
jshell> Date dt = df.parse("2022-02-15");
dt ==> Tue Feb 15 00:00:00 CET 2022
Read the official JavaDoc for class SimpleDateFormat to figure out how to use it to parse a String to Date:
import java.text.SimpleDateFormat;
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date dt = df.parse("2022-02-15");
System.out.println(dt); // prints Tue Feb 15 00:00:00 CET 2022
Explained:
The "yyyy-MM-dd" as argument to the constructor is a date-format literal (representing ISO-date format).
The parse method parses a String with this format and returns the Date object if valid format, or throws a ParseException.
Or search Stackoverflow for [java] String to Date to find similar questions.
Formatting dates in Java with DateFormat or descendants
The other way round you can also format a Date object to have a well-formatted String representation. Use the format method of your DateFormat instance:
import java.text.SimpleDateFormat;
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date dt = df.parse("2022-02-15");
String formatted = df.format(dt);
System.out.println(formatted);
For example to format your Calendar instance use:
Calendar calendar1 = Calendar.getInstance();
// whatever modifies the calendar left out here
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formatted = df.format(dt);
System.out.println(calendar1.getTime());
Related
I am trying to instantiate GregorianCalendar with TimeZone GMT, but whenever I call the getTime() method, it gives me time in local TimeZone. Here is my code:
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
System.out.println(cal.getTime());
The output I am getting is this:
Sat Nov 28 19:55:49 PKT 2009
Please help!
I'm not sure if this answers your question, but this is one way to get "now" in GMT.
import java.text.*
import java.util.*
Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(formatter.format(date));
See the Javadoc on SimpleDateFormat for different patterns. Also, you may want to consider Joda Time as it is far superior for dates and times.
The problem is not with GregorianCalendar but with Date, which is being used to format the date/time for toString for println.
If you want control of date formatting, you'll need to instantiate your own DateFormat - I always use SimpleDateFormat because I'm rather picky about how I want my dates to look.
If you're not interested in the details of how the date is formatted, you can also use one of the getInstance... factory methods of DateFormat.
You can explicitly setTimeZone on a DateFormat (including SimpleDateFormat, of course).
tl;dr
Instant.now().toString()
2020-03-08T00:21:48.647951Z
java.util.Date::toString tells a lie
Your call to GregorianCalendar::getTime returns a java.util.Date. As you can see with this method and class naming, these classes are badly designed.
Then you implicitly called Date::toString to generate text that represents the value within that object. That value is actually in UTC, being merely a count of milliseconds since the epoch reference of first moment of 1970 in UTC. Unfortunately, that method dynamically applies the JVM’s current default time zone while generating the text. This creates the illusion of that zone being contained within the object.
Confusing? Yes. One of many reasons to never use these legacy date-time classes. Use java.time classes instead.
java.time
The other Answers are correct, but now obsolete. The terrible Date, Calendar, GregorianCalendar, and SimpleDateFormat classes were years ago supplanted by the modern java.time classes defined in JSR 310.
To get the current moment in UTC, use Instant. This basic building block class in java.time is always in UTC, by definition.
Instant instant = Instant.now() ;
Generate a string in standard in ISO 8601 format by calling toString.
String output = instant.toString() ;
See this code run live at IdeOne.com.
2020-03-08T00:21:48.647951Z
For more flexible formatting when generating strings, use the OffsetDateTime class. Search Stack Overflow to learn about DateTimeFormatter.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
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());
is there a simple way to convert Date(sql) to following format Month(3 character) day(int) , year(int)?
For example:
Jan 3, 2014
Feb 2, 2014
I have this: "2014-02-14"
(i use postgresql, java and javascript on client)
Assuming , if you want to achieve this in the Database side itself. Then use the below sql query.
Lets say "stack" is the column containing your DATE value ie "2014-02-14"
select to_char(stack,'Mon dd, YYYY') from testing;
to_char
--
Feb 14, 2014
Take a look at Java's SimpleDateFormat API
You can do something like this --
SimpleDateFormat format = new SimpleDateFormat("MMM dd, YYYY");
String dateString = format.format(date); // Pass your SQL date object here
This will work:
SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy");
SimpleDateFormat sqlformat = new SimpleDateFormat("yyyy-mm-dd");
java.util.Date date;
try {
date = sqlformat.parse("2014-02-14");
String result = format.format(date);
System.out.println(result);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // Pass your SQL date object here
Short Answer
In Joda-Time 2.3 (substitute your desired time zone and Locale)…
String output = DateTimeFormat.forStyle( "M-" ).withLocale( new java.util.Locale( "fr", "CA" ).withTimeZone( "America/Montreal").print( new DateTime( myJavaDotSqlDotJavaObject ) );
A Date-Time Object Has No Format
You are making the common mistake of conflating a date-time value with its string representation. A java.sql.Date object has no String format. You can generate a String representation from a date-time object, but the two are separate independent objects.
ISO 8601
The format you mentioned is defined by the ISO 8601 standard. The Joda-Time date-time library uses ISO 8601 for its defaults for both inputs and outputs.
Time Zone
Both the question and other answers ignore the crucial issue of time zone.
Determining what day it is (yesterday, today, tomorrow) depends on your time zone. While a new day dawns in Paris for Feb 2, in Montréal the date is still Feb 1.
A java.sql.Date instance has no time zone. It's date-time value internally is effectively in UTC (no offset).
Decent Date-Time Library
The bundled java.util.Date and .Calendar classes in Java are notoriously troublesome. Avoid them. Use either:
Joda-Time
The new java.time package in Java 8.
Joda-Time
Some example code in Joda-Time 2.3.
Get the current date-time.
DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTime nowInParis = DateTime.now( timeZone );
To convert your java.sql.Date instance to a Joda-Time object, simply pass it to the constructor. Be sure to include a time zone to be assigned to the Joda-Time DateTime object. If you omit the time zone, the JVM’s default zone is assigned.
DateTime dateTimeInParis = new DateTime( myJavaDotSqlDotDateObject, timeZoneParis );
Adjust for time zone.
DateTimeZone timeZoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime nowInMontréal = nowInParis.withTimeZone( timeZone );
You may adjust to UTC. This might be helpful for debugging, to verify the UTC value stored in your database. Postgres always stores TIMESTAMP types in UTC. I repeat: both TIMESTAMP WITH TIME ZONE and TIMESTAMP WITHOUT TIME ZONE types are stored in UTC. The 'with' or 'without' names are misleading, as they refer not to storage but to whether or not a time zone is respected during insertion into or retrieval from the database. Expert advice says: Always use TIMESTAMP WITH TIME ZONE.
DateTime dateTimeInUtc = nowInMontréal.withTimeZone( DateTimeZone.UTC );
Generate a string representation of the date-time value using one of the built-in ISO 8601 formatters. For the date-only YYYY-MM-DD format you mentioned, call the factory method ISODateTimeFormat.date().
For the MMM DD, YYYY format you want, I suggest you instead use a localized format. See the line of code at the top of this answer for an example. Pass "M-" to generate a medium-length string representation of the date portion while omitting the time portion. Pass "F", "L", "M", or "S" for Full, Long, Medium, and Short.
If you insist on exactly your specified format, you may create a formatter using the DateTimeFormat.forPattern method. Search StackOverflow for many examples.
Note that the formatter can do the time zone adjusting as part of its process, as an alternative to the time zone adjustment we saw above. The formatter can also localize.
DateTimeFormat formatter = ISODateTimeFormat.date().withTimeZone( timeZoneMontréal ).withLocale( new java.util.Locale( "fr", "CA" ); // Factory producing formatters.
String outputDateOnlyInMontréal = formatter.print( nowInParis );
There is the following code:
Date st = new SimpleDateFormat("HH:mm").parse(date);
And I get the following exception "Unparseable date: "2000-01-01T01:00:00Z" (at offset 4)". How can I fix it?
tl;dr
Instant.parse( "2000-01-01T01:00:00Z" )
Wrong Parsing Pattern
You defined a formatting pattern that says you expect the input string to be hours and minutes. But your input string has much more, years, months, and so on.
java.time
As of Java 8 and later, the old java.util.Date/.Calendar and java.text.SimpleDateFormat have been supplanted by the new java.time package. Avoid the old classes whenever possible as they have proven to be confusing, troublesome, and flawed.
Your input string is using one of the standard date-time formats defined by ISO 8601. Fortunately, java.time uses that format by default.
String input = "2000-01-01T01:00:00Z" ;
Instant instant = Instant.parse( input ) ;
An Instant is a moment on the timeline basically in UTC. You may adjust the value to a particular time zone (a ZoneId), producing a ZonedDateTime object.
ZonedId zoneId = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.of( instant , zoneId ) ;
If you call toString on a ZonedDateTime, you will get a string like:
1999-12-31T20:00:00-05:00[America/Montreal]
The ZonedDateTime class extends the ISO 8601 format by appending the name of the time zone in brackets.
Date st = new SimpleDateFormat("HH:mm").parse(date.substring(11,16));
Use this format instead:
Date st = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(date);
SimpleDateFormat is very unforgiving. It expects you to pass a String that exactly matches the format string you initialized it with. If you pass "HH:mm" as its format string, it will not be able to handle any other format - it cannot handle a date with a year in it, etc. It will handle "3:56" (in which case you'll get Jan 1, 1970 at 03:56AM in your Date).
SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Date date = dtf.parse(date);
dtf = new SimpleDateFormat("HH:mm");
String dateStr = dtf.format(date);
Date finalDate = dtf.parse(date);
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX")
The date in the exception is an xml schema dateTime. Note that simply creating
SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Will not work entirely as you might think because the Z indicates "UTC" timezone and the parser is by default initialized as local time.
Also note that the schema dateTime has a variable definition, it can (optionally) have millisecond precision (0 or more milliseconds) and the timezone (if something other than Z) is not compatible with the format of SimpleDateFormat.
In short: xml date times are tricky with the default libraries. I have written a custom solution for handling them in our environment but you could also look at the joda time library which I believe handles them well. Or you could wait for the next java version which will have a new date API.
I have SimpleDateFormat constructor as
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
and I am parsing string "2013-09-29T18:46:19Z".
I have read that here Z represents the GMT/UTC timezone. but when I print this date on console , It prints IST timezne for the returned date.
Now my question is whether my output is right or wrong?
You haven't set the timezone only added a Z to the end of the date/time, so it will look like a GMT date/time but this doesn't change the value.
Set the timezone to GMT and it will be correct.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
'T' and 'Z' are considered here as constants. You need to pass Z without the quotes. Moreover you need to specify the timezone in the input string.
Example : 2013-09-29T18:46:19-0700
And the format as "yyyy-MM-dd'T'HH:mm:ssZ"
From ISO 8601 String to Java Date Object
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf.parse("2013-09-29T18:46:19Z"); //prints-> Mon Sep 30 02:46:19 CST 2013
if you don't set TimeZone.getTimeZone("GMT") then it will output Sun Sep 29 18:46:19 CST 2013
From Java Date Object to ISO 8601 String
And to convert Dateobject to ISO 8601 Standard (yyyy-MM-dd'T'HH:mm:ss'Z') use following code
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(sdf.format(new Date())); //-prints-> 2015-01-22T03:23:26Z
Also note that without ' ' at Z yyyy-MM-dd'T'HH:mm:ssZ prints 2015-01-22T03:41:02+0000
IF you want to handle 'standard' JSON representation of the Date then better to use this pattern: "yyyy-MM-dd'T'HH:mm:ssX".
Notice the X on the end. It will handle timezones in ISO 8601 standard, and ISO 8601 is exactly what produces this statement in Javascript new Date().toJSON()
Comparing to other answers it has some benefits:
You don't need to require your clients to send date in GMT
You don't need to explicitly convert your Date object to GMT using this: sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
tl;dr
The other Answers are outmoded as of Java 8.
Instant // Represent a moment in UTC.
.parse( "2013-09-29T18:46:19Z" ) // Parse text in standard ISO 8601 format where the `Z` means UTC, pronounces “Zulu”.
.atZone( // Adjust from UTC to a time zone.
ZoneId.of( "Asia/Kolkata" )
) // Returns a `ZonedDateTime` object.
ISO 8601
Your string format happens to comply with the ISO 8601 standard. This standard defines sensible formats for representing various date-time values as text.
java.time
The old java.util.Date/.Calendar and java.text.SimpleDateFormat classes have been supplanted by the java.time framework built into Java 8 and later. See Tutorial. Avoid the old classes as they have proven to be poorly designed, confusing, and troublesome.
Part of the poor design in the old classes has bitten you, where the toString method applies the JVM's current default time zone when generating a text representation of the date-time value that is actually in UTC (GMT); well-intentioned but confusing.
The java.time classes use ISO 8601 formats by default when parsing/generating textual representations of date-time values. So no need to specify a parsing pattern.
An Instant is a moment on the timeline in UTC.
Instant instant = Instant.parse( "2013-09-29T18:46:19Z" );
You can apply a time zone as needed to produce a ZonedDateTime object.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
and if you don't have the option to go on java8 better use
'yyyy-MM-dd'T'HH:mm:ssXXX' as this gets correctly parsed again (while with only one X this may not be the case... depending on your parsing function)
X generates: +01
XXX generates: +01:00
'Z' is not the same as Z
'Z' is just a character literal whereas Z is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
Therefore, do not use 'Z' in pattern for parsing/formatting.
The java.time, the modern Date-Time API
The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards. The Date-Time string, 2013-09-29T18:46:19Z conforms to ISO 8601 standards.
Demo:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.parse("2013-09-29T18:46:19Z");
OffsetDateTime odt = OffsetDateTime.parse("2013-09-29T18:46:19Z");
ZonedDateTime zdt = ZonedDateTime.parse("2013-09-29T18:46:19Z");
System.out.println(instant);
System.out.println(odt);
System.out.println(zdt);
}
}
Output:
2013-09-29T18:46:19Z
2013-09-29T18:46:19Z
2013-09-29T18:46:19Z
ONLINE DEMO
An Instant represents an instantaneous point on the timeline in UTC. The Z in the output is the timezone designator for a zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
Note#1: In case you need to find out what date and time an Instant represents in a particular timezone, you can use Instant#atZone e.g. the following code will print the date and time this Instant in India:
ZonedDateTime zdtIndia = instant.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);
You can even convert an object of ZonedDateTime from one timezone to another using ZonedDateTime#withZoneSameInstant e.g. the following code will convert zdt to an object of ZonedDateTime representing date and time in India:
ZonedDateTime zdtIndia = zdt.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);
Note#2: For any reason, if you need to convert this object of Instant to an object of java.util.Date, you can do so as follows:
Date date = Date.from(instant);
You can even convert the object of OffsetDateTime and ZonedDateTime to an object of java.util.Date, as follows:
Date date = Date.from(odt.toInstant());
&
Date date = Date.from(zdt.toInstant());
Learn more about the modern Date-Time API* from Trail: Date Time.
Why did your java.util.Date object print the India date and time?
A java.util.Date object simply 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 it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
String strDate = sdf.format(date);
System.out.println(strDate);
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
Date date = sdf.parse("2013-09-29T18:46:19Z");
// In JVM's timezone and default format as returned by Date#toString
System.out.println(date);
// In UTC and custom format
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDate = sdf.format(date);
System.out.println(strDate);
// In India and custom format
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
strDate = sdf.format(date);
System.out.println(strDate);
}
}
Output (my timezone is Europe/London):
Sun Sep 29 19:46:19 BST 2013
2013-09-29T18:46:19Z
2013-09-30T00:16:19+05:30
ONLINE DEMO
* 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.
For Java 8:
You can use inbuilt java.time.format.DateTimeFormatter to reduce any chance of typos,
like
DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
ISO_ZONED_DATE_TIME represents 2011-12-03T10:15:30+01:00[Europe/Paris] is one of the bundled standard DateTime formats provided by Oracle link
Reference Examples of existing formatters:
String date1 = "2022-06-19T01:26:05.000+00:00";
// internally using DateTimeFormatter.ISO_OFFSET_DATE_TIME
System.out.println(OffsetDateTime.parse(date1));
//internally using DateTimeFormatter.ISO_ZONED_DATE_TIME
System.out.println(ZonedDateTime.parse(date1));
String date2 = "2022-06-19T01:26:05";
//internally using DateTimeFormatter.ISO_LOCAL_DATE_TIME)
System.out.println(LocalDateTime.parse(date2));
String date3 = "2022-06-19T01:26:05.00Z";
//internally using DateTimeFormatter.ISO_INSTANT
System.out.println(Instant.parse(date3));
Output:
2022-06-19T01:26:05Z
2022-06-19T01:26:05Z
2022-06-19T01:26:05
2022-06-19T01:26:05Z