Below is my input date string format:
2025-08-08T15%3A41%3A46
I have to convert above string date in the format as shown below:
Fri Aug 08 15:41:46 GMT-07:00 2025
And I got below code:
SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
String decodedDate = URLDecoder.decode("2025-08-08T15%3A41%3A46", "UTF-8");
Date date = dateParser.parse(decodedDate);
//Decode the given date and convert to Date object
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd hh:mm:ss z yyyy", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT-07:00"));
System.out.println(sdf.format(date));
And this is what it prints out on the console. I am not sure why it prints different hour value as compared to what I have above in the desired output. It should print out 15 but it is printing 03.
Fri Aug 08 03:41:46 GMT-07:00 2025
I am not sure what is the reason why hours are getting changed because of timezone difference with GMT?
That is the same time except in the first format you are using "HH" for hour that is "Hour in day (0-23)" and second format uses "hh" that is "Hour in am/pm (1-12)".
As the other Answer correctly states, your formatting pattern used incorrect characters.
Let's look at an alternative modern approach.
ISO 8601
Your input string, once decoded to restore the COLON characters, is in standard ISO 8601 format.
URLDecoder.decode("2025-08-08T15%3A41%3A46", "UTF-8")
2025-08-08T15:41:46
Using java.time
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.
The java.time classes use ISO 8601 by default when parsing/generating strings.
Your input string lacks any indication of offset-from-UTC or time zone. So we parse as a LocalDateTime.
LocalDateTime ldt = LocalDateTime.parse( "2025-08-08T15:41:46" )
ldt.toString(): 2025-08-08T15:41:46
If you know the intended time zone, assign a ZoneId to produce a ZonedDateTime.
ZonedDateTime zdt = ldt.atZone( ZoneId.of( "America/Montreal" ) ) ;
zdt.toString(): 2025-08-08T15:41:46-04:00[America/Montreal]
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Related
DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
DateFormat indianFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
indianFormat .setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
String output = null;
try {
Date timestamp = null;
timestamp = utcFormat.parse(createdAt);
output = indianFormat.format(timestamp);
} catch (ParseException e) {
Log.d("ParseError", String.valueOf(e));
}
I want to convert GMT time of format "2020-03-16T18:50:39.656Z" to IST time of same format as GMT but I am getting unparseable exception
The Z at the end of your createdAt value is an ISO 8601 time zone symbol. To parse it, you need to have X in your date format string, not Z. Change your date format string to "yyyy-MM-dd'T'HH:mm:ss.SSSX" and your program will work.
Alternatively, you could keep Z in the date format string, but give your input as "2020-03-16T18:50:39.656+0000" - that is, use the four digit number to represent the time offset in the input, instead of Z.
tl;dr
Instant
.parse(
"2020-03-16T18:50:39.656Z"
)
.atZone(
ZoneId.of( "Asia/Kolkata" )
)
java.time
You are using terrible date-time classes that were supplanted years ago by the modern java.time classes with the adoption of JSR 310.
ISO 8601
Your input string is in standard ISO 8601 format. The Z on the end means UTC (an offset of zero hours-minutes-seconds), and is pronounced “Zulu”.
The java.time classes use ISO 8601 formats by default. So no need to specify a formatting pattern.
Instant
Parse your input as a Instant, representing a moment as seen in UTC.
String input = "2020-03-16T18:50:39.656Z" ;
Instant instant = Instant.parse( input ) ;
ZonedDateTime
Adjust to India time.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
I am trying to convert date from one format to another using formatter.
But somehow this does not see to be working.
Following is my code
Date today = Calendar.getInstance().getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.ms");
String folderName = formatter.format(today);
Date date = formatter.parse(folderName);
System.out.println("Folder date = " + date); //This prints Wed Nov 09 06:05:57 IST 2016
I need date to be printed in yyyy-MM-dd hh:mm:ss.ms format.
That is I need it to be 2016-11-09 06:50:25.5025 and not Wed Nov 09 06:05:57 IST 2016
In folderName it is in correct format but when I convert back to date again format changes.
Could you please let me know what I am missing?
You did two errors:
The format (check here for a complete list of formats) is yyyy-MM-dd hh:mm:ss.SSS
And you need to print the String, not the Date.
Date today = Calendar.getInstance().getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
String folderName = formatter.format(today);
System.out.println("Folder date = " + folderName);
Using java.time
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
now.toString(): 2016-11-09T06:50:25.502+05:30[Asia/Kolkata]
Generate a string. Your desired format is close to standard ISO 8601 format, just replace the T in the middle with a space. The java.time classes know about ISO 8601 formats.
DateTimeFormatter f = DateTimeFormatter.ISO_LOCAL_DATE_TIME ;
String output = now.format( f ).replace( "T" , " " ) ;
2016-11-09 06:50:25.502
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Last sunday we change the time (-1h) in middle europe. I was making some tests but something does not let me sleep with the java time parser. This is the code
public static void main(String[] args) {
String dateFormatPattern = "yyyy-MM-dd HH:mm:ss";
String dateUtc = "2016-10-09 12:50:00";
SimpleDateFormat dateFormatUtc = new SimpleDateFormat(dateFormatPattern);
dateFormatUtc.setTimeZone(TimeZone.getTimeZone("UTC"));
SimpleDateFormat dateFormatLisboa = new SimpleDateFormat(dateFormatPattern);
dateFormatLisboa.setTimeZone(TimeZone.getTimeZone("Europe/Lisboa"));
SimpleDateFormat dateFormatMadrid = new SimpleDateFormat(dateFormatPattern);
dateFormatMadrid.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
SimpleDateFormat dateFormatParis = new SimpleDateFormat(dateFormatPattern);
dateFormatParis.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
System.out.println("UTC: "+dateUtc);
try {
Date d = dateFormatUtc.parse(dateUtc);
System.out.println("Lisboa: "+dateFormatLisboa.format(d));
System.out.println("Madrid: "+dateFormatMadrid.format(d));
System.out.println("Paris: "+dateFormatParis.format(d));
} catch (ParseException e) {
e.printStackTrace();
}
}
And this is the output
UTC: 2016-10-09 12:50:00
Lisboa: 2016-10-09 12:50:00
Madrid: 2016-10-09 14:50:00
Paris: 2016-10-09 14:50:00
Why the difference between UTC and Madrid time are 2 hours? Now in madrid is UTC+1.
Thanks.
The times are correct as the clocks changed on the 30th October at 2am
if you change you code to this
String dateUtc = "2016-11-09 12:50:00";
You get this output, giving the correct 1 hour difference.
UTC: 2016-11-09 12:50:00
Lisboa: 2016-11-09 12:50:00
Madrid: 2016-11-09 13:50:00
Paris: 2016-11-09 13:50:00
The timezone is due to the when the date object is actually referencing. So it is correct for that time
The accepted Answer by French is correct. The values overlapped the cutover in Daylight Saving Time (DST).
I am just pointing out that your code is using old date-time classes, now legacy, supplanted by the java.time classes.
Parse the input value as a LocalDateTime because it lacks any indicator of time zone or offset-from-UTC.
Replace the SPACE in the middle with a T to comply with ISO 8601 format used by default in the java.time classes for parsing/generating strings.
LocalDateTime ldt = LocalDateTime.parse( "2016-10-09 12:50:00".replace( " " , "T" ) );
We know from the business context that UTC is intended for this input string. So assign an offset of UTC.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
Adjust into a time zone by applying a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "Europe/Lisboa" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I am getting time in string like this "2011-02-27T10:03:33.099-06:00" which is of xml dateTime type. I also have timezone of TimeZone type. How should I convert the dateTime to GregorianCalendar java type in that timezone.
Java has built in code to parse xml datetimes: use DatatypeConverter.parseDateTime(). that will return a Calendar in the parsed TimeZone. you can then set the Calendar TimeZone to your desired target TimeZone for whatever you need to do next.
sdf = new java.text.SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss.S");
parses everything, except the trailing TZ.
sdf.parse (sd);
res168: java.util.Date = Sun Feb 27 10:03:33 CET 2011
From the api docs, I would expect
sdf = new java.text.SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss.SSSz");
to be used to read the -06:00 in the end. But I see, that there is either an offset in the form 0700 expected, or with a prefix of GMT for example "GMT-04:00". So you have to insert that GMT-thingy yourself:
sdf.parse (sd.replaceAll ("(......)$", "GMT$1"))
SDF.parse (str) returns a Date, which has to be converted into a GC:
GregorianCalendar calendar = new GregorianCalendar ();
calendar.setTime (date);
tl;dr
OffsetDateTime.parse( "2011-02-27T10:03:33.099-06:00" )
java.time
The modern approach uses the java.time classes that supplanted the troublesome old legacy date-time classes. Specifically, GregorianCalendar was replaced by ZonedDateTime for a time zone, and OffsetDateTime for a mere offset-from-UTC.
ISO 8601
Your input string happens to comply with the ISO 8601 standard format.
The java.time classes use these standard formats by default when parsing/generating strings. So no need to specify a formatting pattern.
OffsetDateTime
Your input string contains an offset-from-UTC, but not a time zone. So parse as an OffsetDateTime.
OffsetDateTime odt = OffsetDateTime.parse( "2011-02-27T10:03:33.099-06:00" ) ;
ZonedDateTime
If you know for certain the intended time zone, apply a ZoneId to produce a ZonedDateTime.
A time zone is always preferable to a mere offset. A zone is a history of past, present, and future changes to the offset used by the people of a particular region.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Pacific/Galapagos" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Converting legacy ↔ modern
If you must have a GregorianCalendar object to inter-operate with old code not yet updated to java.time, you can convert. Look to new methods added to the old classes.
GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ;
And going the other direction…
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I'm trying to convert this date string 2014-07-17T22:41:17+0000 to a timestmap, similar to this: 1405645259000.
I've tried something similar to this:
String string = "January 2, 2010";
Date date = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(string);
System.out.println(date);
How do I convert this (2014-07-17T22:41:17+000) to a Date? What is the correct format? I'm at a loss.
Take a look at http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Your date string has the same format as
yyyy-MM-dd'T'HH:mm:ssZ //Eg: 2001-07-04T12:08:56-0700
So, your code should be:
String string = "2014-07-17T22:41:17+0000";
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH).parse(string);
System.out.println(date);
use this pattern:
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH).parse(string);
tl;dr
OffsetDateTime.parse( "2014-07-17T22:41:17+0000" )
.toInstant()
.toEpochMilli()
Avoid java.util.Date
Your question is easy in Joda-Time or the new java.time package in Java 8. Avoid java.util.Date and .Calendar as they are notoriously troublesome.
ISO 8601
Your String is in standard format, complying with ISO 8601. Both libraries mentioned above use ISO 8601 as their defaults for parsing and generating strings.
java.time
The OffsetDateTime class represents a moment on the timeline with an offset-from-UTC and with a resolution in nanoseconds.
OffsetDateTime odt = OffsetDateTime.parse( "2014-07-17T22:41:17+0000" );
From there you can ask for the count-of-milliseconds-since-epoch via the Instant class. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
long millisecondsSinceEpoch = odt.toInstant().toEpochMilli();
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Joda-Time
Example code on Joda-Time 2.3.
long millisSinceEpoch = new DateTime( "2014-07-17T22:41:17+0000" ).getMillis();