Hi so I do understand there are many threads out here regarding this and ive been through many of them I'm not able to grasp the whole date format thing so here I am seeking your help :)
I've got a json object giving me this date "2014-01-10T02:01:42.657Z" and I have no idea what sort of format that is. I do know its a datetime from mssql database and I wish to parse this in java for which I'm using this code.
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date result = null;
try {
result = df.parse(last_active);
} catch (ParseException e) {
Log.i("Date Parser problem (Friend.java): ", e.toString());
e.printStackTrace();
}
Log.i("Date: ", result.toString());
I do understand that the "yyyy-MM-dd HH:mm:ss" is the wrong format to parse this date with but I am not able to find the right type of format string to format the following date.
"2014-01-10T02:01:42.657Z"
I appreciate your help :)
Thank you
This is simply a standard ISO-formatted date. The T in the middle is simply a separator, and the Z at the end means "UTC".
To parse it, simply use yyyy-MM-dd'T'HH:mm:ss.SSSX as the pattern.
Try this
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
ISO 8601
That string is in standard format, as defined by ISO 8601. In various protocols, this format is gradually replacing the silly formats of yesteryear such as Sun, 06 Nov 1994 08:49:37 GMT.
Avoid java.util.Date/Calendar
The bundled classes java.util.Date and .Calendar are notoriously troublesome. Avoid them. With the arrival of the java.time package in Java 8, they are practically deprecated. If you cannot go to Java 8, use Joda-Time (which inspired java.time).
Joda-Time
The Joda-Time library (third-party, open-source, free-of-cost) uses ISO 8601 for its defaults. So the Joda-Time class DateTime automatically parses such strings.
DateTime dateTime = new DateTime( "2014-01-10T02:01:42.657Z" );
Dump to console…
System.out.println( "dateTime: " + dateTime );
When run…
dateTime: 2014-01-09T18:01:42.657-08:00
Time Zone
Notice Joda-Time applied my JVM’s default time zone thereby adjusting the time appropriately. If you wish to keep the DateTime object in UTC, pass a DateTimeZone object in that constructor.
DateTime dateTime = new DateTime( "2014-01-10T02:01:42.657Z", DateTimeZone.UTC );
When run…
dateTime: 2014-01-10T02:01:42.657Z
java.time
The java.time package also uses ISO 8601 for its defaults, and automatically parses such standard strings.
Instant instant = Instant.parse( "2014-01-10T02:01:42.657Z" );
Dump to console…
System.out.println( "instant: " + instant );
When run…
instant: 2014-01-10T02:01:42.657Z
Related
When I search online about "how to convert a Calendar to a String", all the results I find suggest to first convert to a Date and then convert the Date to a String.
The problem is that a Date is only a representation of the number of milliseconds since the epoch - it does not respect timezone. Calendar is more advanced in this way.
Of course, I could call the individual Calendar.get methods to create my own formatted string, but surely there must be an easier way?
To illustrate, I wrote this code:
long currentTime = Calendar.getInstance().getTimeInMillis();
Calendar calendar = new GregorianCalendar();
calendar.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
calendar.setTimeInMillis(currentTime);
System.out.println(calendar.getTime().toString());
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()));
System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
While running this code from a machine based in London (UTC+0) at 8:02pm, I got the following results:
Wed Nov 18 20:02:26 UTC 2015
2015-11-18 20:02:26
21
The last line shows the real hour according to the calendar's timezone (Madrid which is UTC+1). It is 9:02pm in Madrid, but obviously both the native Date.toString as well as the DateFormat.format methods ignore the timezone because the timezone information is erased when calling Calendar.getTime (similarly Calendar.getTimeInMillis).
Given this, what is the best way to get a formatted string from a Calendar which respects timezone?
Set the timezone on the SimpleDateFormat object and then use z ..
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
System.out.println(sdf.format(calendar.getTime());
See here for details on how to handle timezones in Java.
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
Calendar cal = Calendar.getInstance();
System.out.println(simpleDateFormat.format(cal.getTime()));
java.time
While the other Answers appear to be correct, a better approach is to avoid using java.util.Date/.Calendar entirely.
Those old date-time classes have been superseded by the java.time framework built into Java 8 and later. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
Instant
An Instant represents a moment on the timeline in UTC.
Instant instant = Instant.now ( ); // Current moment in UTC.
For a given Calendar object, convert to an Instant using the method toInstant added in Java 8.
Instant instant = myCalendar.toInstant();
ZonedDateTime
You can assign a time zone (ZoneId) to an Instant to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of ( "Europe/Madrid" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant, zoneId );
String Representation of Date-Time Value
Dump to console.
System.out.println ( "instant: " + instant + " adjusted into zone: " + zoneId + " is zdt: " + zdt );
The java.time classes use ISO 8601 standard formatting by default when parsing/generating String representations of date-time values. By default the ISO 8601 style is extended by appending the name of the time zone in addition to the usual offset-from-UTC.
instant: 2015-11-18T22:23:46.764Z adjusted into zone: Europe/Madrid is zdt: 2015-11-18T23:23:46.764+01:00[Europe/Madrid]
If you want the ISO 8601 style but without the T, either call .replace( "T" , "" ) on the resulting String object or define your own formatter.
The java.time.format package can do the work of determining a localized format appropriate to a particular Locale.
Locale locale = Locale.forLanguageTag ( "es-ES" );
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL );
String output = zdt.format ( formatter.withLocale ( locale ) );
miércoles 18 de noviembre de 2015 23H38' CET
You can use String.format() to avoid timezone problems
http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html
This example gives a result in the format: "yyyy-MM-dd HH:mm:ss"
Calendar c = Calendar.getInstance();
String s = String.format("%1$tY-%1$tm-%1$td:%1$tM:%1$tS", c);
System.out.println(s);
Output:
2015-11-20:44:55
I wanted to convert a date from one time zone to another, using SimpleDateFormat class in java. But somehow it is generating different results which are suppose to be in the same TimeZone.
Here is a test case, and its generating one result as IST and other one as GMT. i think it should be generating only GMT's for both cases.
public class TestOneCoreJava {
public static void main(String[] args) throws ParseException {// Asia/Calcutta
DateFormat formatter = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a");
System.out.println(getDateStringToShow(formatter.parse("26-Nov-10 03:31:20 PM +0530"),"Asia/Calcutta", "Europe/Dublin", false));
System.out.println(getDateStringToShow(formatter.parse("02-Oct-10 10:00:00 AM +0530"),"Asia/Calcutta", "Europe/Dublin", false));
//------Output--
//26-Nov-10 GMT
//02-Oct-10 IST
}
public static String getDateStringToShow(Date date,
String sourceTimeZoneId, String targetTimeZoneId, boolean includeTime) {
String result = null;
// System.out.println("CHANGING TIMEZONE:1 "+UnitedLexConstants.SIMPLE_FORMAT.format(date));
String date1 = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a").format(date);
SimpleDateFormat sourceTimeZoneFormat = new SimpleDateFormat("Z");
sourceTimeZoneFormat.setTimeZone(TimeZone.getTimeZone(sourceTimeZoneId));
date1 += " " + sourceTimeZoneFormat.format(date);
// Changed from 'Z' to 'z' to show IST etc, in place of +5:30 etc.
SimpleDateFormat targetTimeZoneFormat = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a z");
targetTimeZoneFormat.setTimeZone(TimeZone.getTimeZone(targetTimeZoneId));
SimpleDateFormat timeZoneDayFormat = null;
if (includeTime) {
timeZoneDayFormat = targetTimeZoneFormat;
} else {
timeZoneDayFormat = new SimpleDateFormat("dd-MMM-yy z");
}
timeZoneDayFormat.setTimeZone(TimeZone.getTimeZone(targetTimeZoneId));
try {
result = timeZoneDayFormat.format(targetTimeZoneFormat.parse(date1));
// System.out.println("CHANGING TIMEZONE:3 "+result);
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
}
tl;dr
Use modern java.time classes, specifically ZonedDateTime and ZoneId. See Oracle Tutorial.
ZonedDateTime // Represent a date and time-of-day in a specific time zone.
.now( // Capture the current moment as seen in the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Pacific/Auckland" ) // Specify time zone using proper name in `Continent/Region` format. Never use 3-4 letter pseudo-zone such as IST or PST or EST.
) // Returns a `ZonedDateTime` object.
.withZoneSameInstant( // Adjust from one time zone to another. Same point on the timeline, same moment, but different wall-clock time.
ZoneId.of( "Africa/Tunis" )
) // Returns a new fresh `ZonedDateTime` object rather than altering/“mutating” the original, per immutable objects pattern.
.toString() // Generate text in standard ISO 8601 format, extended to append name of zone in square brackets.
2018-09-18T21:47:32.035960+01:00[Africa/Tunis]
For UTC, call ZonedDateTime::toInstant.
Avoid 3-Letter Time Zone Codes
Avoid those three-letter time zone codes. They are neither standardized nor unique. For example, your use of "IST" may mean India Standard Time, Irish Standard Time, and maybe others.
Use proper time zone names. The definition of time zones and their names change frequently, so keep your source up-to-date. For example the old "Asia/Calcutta" is now "Asia/Kolkata". And not just names; governments are notorious for changing the rules/behavior of a time zone, occasionally at the last minute.
Avoid j.u.Date
Avoid using the bundled java.util.Date and Calendar classes. They are notoriously troublesome and will be supplanted in Java 8 by the new java.time.* package (which was inspired by Joda-Time).
java.time
Instant
Learn to think and work in UTC rather than your own parochial time zone. Logging, data-exchange, and data-storage should usually be done in UTC.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
instant.toString(): 2018-09-18T20:48:43.354953Z
ZonedDateTime
Adjust into a time zone. Same moment, same point on the timeline, different wall-clock time. Apply a ZoneId (time zone) to get a ZonedDateTime object.
ZoneId zMontreal = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtMontreal = instant.atZone( zMontreal ) ; // Same moment, different wall-clock time.
We can adjust again, using either the Instant or the ZonedDateTime.
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = zdtMontreal.withZoneSameInstant( zKolkata ) ;
ISO 8601
Calling toString on any of these classes produce text in standard ISO 8601 class. The ZonedDateTime class extends the standard wisely by appending the name of the time zone in square brackets.
When exchanging date-time values as text, always use ISO 8601 formats. Do not use custom formats or localized formats as seen in your Question.
The java.time classes use the standard formats by default for both parsing and generating strings.
Instant instant = Instant.parse( "2018-01-23T01:23:45.123456Z" ) ;
Using standard formats avoids all that messy string manipulation seen in the Question.
Adjust to UTC
You can always take a ZonedDateTime back to UTC by extracting a Instant.
Instant instant = zdtKolkata.toInstant() ;
DateTimeFormatter
To represent your date-time value in other formats, search Stack Overflow for DateTimeFormatter class. You will find many examples and discussions.
UPDATE: The Joda-Time project is now in maintenance-mode, and advises migration to the java.time classes. I am leaving this section intact as history.
Joda-Time
Beware of java.util.Date objects that seem like they have a time zone but in fact do not. In Joda-Time, a DateTime does indeed know its assigned time zone. Generally should specify a desired time zone. Otherwise, the JVM's default time zone will be assigned.
Joda-Time uses mainly immutable objects. Rather than modify an instance, a new fresh instance is created. When calling methods such as toDateTime, a new fresh DateTime instance is returned leaving the original object intact and unchanged.
//DateTime now = new DateTime(); // Default time zone automatically assigned.
// Convert a java.util.Date to Joda-Time.
java.util.Date date = new java.util.Date();
DateTime now = new DateTime( date ); // Default time zone automatically assigned.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime nowIndia = now.toDateTime( timeZone );
// For UTC/GMT, use built-in constant.
DateTime nowUtcGmt = nowIndia.toDateTime( DateTimeZone.UTC );
// Convert from Joda-Time to java.util.Date.
java.util.Date date2 = nowIndia.toDate();
Dump to console…
System.out.println( "date: " + date );
System.out.println( "now: " + now );
System.out.println( "nowIndia: " + nowIndia );
System.out.println( "nowUtcGmt: " + nowUtcGmt );
System.out.println( "date2: " + date2 );
When run…
date: Sat Jan 25 16:52:28 PST 2014
now: 2014-01-25T16:52:28.003-08:00
nowIndia: 2014-01-26T06:22:28.003+05:30
nowUtcGmt: 2014-01-26T00:52:28.003Z
date2: Sat Jan 25 16:52:28 PST 2014
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.
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.
When dealing with Timezone issues in Google API. I came across such kind of issues.
Look at this piece of code of yours:-
System.out.println(getDateStringToShow(formatter.parse("26-Nov-10 03:31:20 PM
+0530"),"Asia/Calcutta", "Europe/Dublin", false));
System.out.println(getDateStringToShow(formatter.parse("02-Nov-10 10:00:00 AM
+0530"),"Asia/Calcutta", "Europe/Dublin", false));
If i give above as input it will run fine the way we want to.
If you still want to go with this way then you have to perform calculation according to your need.
Like adjusting the time Mathematically and things similar to it.
Or a Simple fix for your case will be something like this
SimpleDateFormat d =new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
d.setTimeZone(TimeZone.getTimeZone("Europe/Dublin"));
Date firsttime = d.parse("2013-12-19T03:31:20");
Date seondtime = d.parse("2013-12-19T10:00:00");
System.out.println(getDateStringToShow(firsttime,"Asia/Calcutta",
"Europe/Dublin", false));
System.out.println(getDateStringToShow(seondtime,"Asia/Calcutta",
"Europe/Dublin", false));
My suggestion will be to refer JODA API . More preferrable over Old School Date.
Im trying parse a date from a JSONObject
"timcre_not":"2013-12-11 21:25:04.800842+01"
and I parse with
mDate = new SimpleDateFormat("y-M-d h:m:s.SSSSSSZZ",
Locale.ENGLISH).parse(json.getString("timcre_not"));
but the mDate value is:
Wed Dec 11 21:38:24 CET 2013
What is happening?
This should be the solution: Date object SimpleDateFormat not parsing timestamp string correctly in Java (Android) environment
SimpleDateFormat cannot take microseconds, only milliseconds.
The answer by treeno is correct.
Joda-Time
As an alternative, you can use the third-party open-source Joda-Time. Joda-Time is often used to supplant the java.util.Date & Calendar classes found in Java (and Android).
ISO 8601
The string you have is loosely in ISO 8601 format. Replace that SPACE with a LATIN CAPITAL LETTER T "T" character to get a strict ISO 8601 format.
Joda-Time's DateTime class accepts an ISO 8601 string directly to its constructor. One catch: As with java.util.Date, a DateTime tracks only to the millisecond not microsecond. But in Joda-Time, rather than throw an error, the DateTime merely truncates (ignores) the extra (beyond 3) decimal places.
Example Code
Here is some example code using Joda-Time 2.3 and Java 8.
String input = "2013-12-11 21:25:04.800842+01";
String string = input.replace( " ", "T" ); // Replace SPACE with "T" for strict ISO 8601 format.
DateTime dateTimeUtc = new DateTime( string, DateTimeZone.UTC );
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTimeParis = new DateTime( string, timeZone );
Dump to console…
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeParis: " + dateTimeParis );
When run…
dateTimeUtc: 2013-12-11T20:25:04.800Z
dateTimeParis: 2013-12-11T21:25:04.800+01:00
Java 8
I tried using the new java.time.* classes in Java 8 to parse your string.
ZonedDateTime zonedDateTime = ZonedDateTime.parse( string );
Unfortunately, the parser did not tolerate the time zone offset being the shortened +01. I tried the longer +01:00 and it worked. This seems to be a flaw in the Java implementation, not your string. The shortened offset is allowed in ISO 8601. While both I and RFC 3339 (a near-profile of ISO 8601) prefer using the longer +01:00, the ISO standard doe allow it and so should the java.time.* classes. I filed Bug Id: 9009717 with Oracle.
Get Better Data
If possible, suggest to the source of your date that they use the more strict and common ISO 8601 format including:
Use the letter "T" in place of SPACE
Longer time zone offset, "+01:00" rather than "+01"
I am using following code to get date in "dd/MM/yyyy HH:mm:ss.SS" format.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateAndTime{
public static void main(String[] args)throws Exception{
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS");
String strDate = sdf.format(cal.getTime());
System.out.println("Current date in String Format: "+strDate);
SimpleDateFormat sdf1 = new SimpleDateFormat();
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
System.out.println("Current date in Date Format: "+date);
}
}
and am getting following output
Current date in String Format: 05/01/2012 21:10:17.287
Current date in Date Format: Thu Jan 05 21:10:17 IST 2012
Kindly suggest what i should do to display the date in same string format(dd/MM/yyyy HH:mm:ss.SS) i.e i want following output:
Current date in String Format: 05/01/2012 21:10:17.287
Current date in Date Format: 05/01/2012 21:10:17.287
Kindly suggest
SimpleDateFormat
sdf=new SimpleDateFormat("dd/MM/YYYY hh:mm:ss");
String dateString=sdf.format(date);
It will give the output 28/09/2013 09:57:19 as you expected.
For complete program click here
You can't - because you're calling Date.toString() which will always include the system time zone if that's in the default date format for the default locale. The Date value itself has no concept of a format. If you want to format it in a particular way, use SimpleDateFormat.format()... using Date.toString() is almost always a bad idea.
The following code gives expected output. Is that what you want?
import java.util.Calendar;
import java.util.Date;
public class DateAndTime {
public static void main(String[] args) throws Exception {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS");
String strDate = sdf.format(cal.getTime());
System.out.println("Current date in String Format: " + strDate);
SimpleDateFormat sdf1 = new SimpleDateFormat();
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
String string = sdf1.format(date);
System.out.println("Current date in Date Format: " + string);
}
}
Use:
System.out.println("Current date in Date Format: " + sdf.format(date));
tl;dr
Use modern java.time classes.
Never use Date/Calendar/SimpleDateFormat classes.
Example:
ZonedDateTime // Represent a moment as seen in the wall-clock time used by the people of a particular region (a time zone).
.now( // Capture the current moment.
ZoneId.of( "Africa/Tunis" ) // Always specify time zone using proper `Continent/Region` format. Never use 3-4 letter pseudo-zones such as EST, PDT, IST, etc.
)
.truncatedTo( // Lop off finer part of this value.
ChronoUnit.MILLIS // Specify level of truncation via `ChronoUnit` enum object.
) // Returns another separate `ZonedDateTime` object, per immutable objects pattern, rather than alter (“mutate”) the original.
.format( // Generate a `String` object with text representing the value of our `ZonedDateTime` object.
DateTimeFormatter.ISO_LOCAL_DATE_TIME // This standard ISO 8601 format is close to your desired output.
) // Returns a `String`.
.replace( "T" , " " ) // Replace `T` in middle with a SPACE.
java.time
The modern approach uses java.time classes that years ago supplanted the terrible old date-time classes such as Calendar & SimpleDateFormat.
want current date and time
Capture the current moment in UTC using Instant.
Instant instant = Instant.now() ;
To view that same moment through the lens of the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime.
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/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Or, as a shortcut, pass a ZoneId to the ZonedDateTime.now method.
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" ) ) ;
The java.time classes use a resolution of nanoseconds. That means up to nine digits of a decimal fraction of a second. If you want only three, milliseconds, truncate. Pass your desired limit as a ChronoUnit enum object.
ZonedDateTime
.now(
ZoneId.of( "Pacific/Auckland" )
)
.truncatedTo(
ChronoUnit.MILLIS
)
in “dd/MM/yyyy HH:mm:ss.SS” format
I recommend always including the offset-from-UTC or time zone when generating a string, to avoid ambiguity and misunderstanding.
But if you insist, you can specify a specific format when generating a string to represent your date-time value. A built-in pre-defined formatter nearly meets your desired format, but for a T where you want a SPACE.
String output =
zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " )
;
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
Never exchange date-time values using text intended for presentation to humans.
Instead, use the standard formats defined for this very purpose, found in ISO 8601.
The java.time use these ISO 8601 formats by default when parsing/generating strings.
Always include an indicator of the offset-from-UTC or time zone when exchanging a specific moment. So your desired format discussed above is to be avoided for data-exchange. Furthermore, generally best to exchange a moment as UTC. This means an Instant in java.time. You can exchange a Instant from a ZonedDateTime, effectively adjusting from a time zone to UTC for the same moment, same point on the timeline, but a different wall-clock time.
Instant instant = zdt.toInstant() ;
String exchangeThisString = instant.toString() ;
2018-01-23T01:23:45.123456789Z
This ISO 8601 format uses a Z on the end to represent UTC, pronounced “Zulu”.
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.
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.
Here's a simple snippet working in Java 8 and using the "new" date and time API LocalDateTime:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss.SS");
LocalDateTime now = LocalDateTime.now();
System.out.println(dtf.format(now));
The output in your first printline is using your formatter. The output in your second (the date created from your parsed string) is output using Date#toString which formats according to its own rules. That is, you're not using a formatter.
The rules are as per what you're seeing and described here:
http://docs.oracle.com/javase/6/docs/api/java/util/Date.html#toString()
Disclaimer: this answer does not endorse the use of the Date class (in fact it’s long outdated and poorly designed, so I’d rather discourage it completely). I try to answer a regularly recurring question about date and time objects with a format. For this purpose I am using the Date class as example. Other classes are treated at the end.
You don’t want to
You don’t want a Date with a specific format. Good practice in all but the simplest throw-away programs is to keep your user interface apart from your model and your business logic. The value of the Date object belongs in your model, so keep your Date there and never let the user see it directly. When you adhere to this, it will never matter which format the Date has got. Whenever the user should see the date, format it into a String and show the string to the user. Similarly if you need a specific format for persistence or exchange with another system, format the Date into a string for that purpose. If the user needs to enter a date and/or time, either accept a string or use a date picker or time picker.
Special case: storing into an SQL database. It may appear that your database requires a specific format. Not so. Use yourPreparedStatement.setObject(yourParamIndex, yourDateOrTimeObject) where yourDateOrTimeObject is a LocalDate, Instant, LocalDateTime or an instance of an appropriate date-time class from java.time. And again don’t worry about the format of that object. Search for more details.
You cannot
A Date hasn’t got, as in cannot have a format. It’s a point in time, nothing more, nothing less. A container of a value. In your code sdf1.parse converts your string into a Date object, that is, into a point in time. It doesn’t keep the string nor the format that was in the string.
To finish the story, let’s look at the next line from your code too:
System.out.println("Current date in Date Format: "+date);
In order to perform the string concatenation required by the + sign Java needs to convert your Date into a String first. It does this by calling the toString method of your Date object. Date.toString always produces a string like Thu Jan 05 21:10:17 IST 2012. There is no way you could change that (except in a subclass of Date, but you don’t want that). Then the generated string is concatenated with the string literal to produce the string printed by System.out.println.
In short “format” applies only to the string representations of dates, not to the dates themselves.
Isn’t it strange that a Date hasn’t got a format?
I think what I’ve written is quite as we should expect. It’s similar to other types. Think of an int. The same int may be formatted into strings like 53,551, 53.551 (with a dot as thousands separator), 00053551, +53 551 or even 0x0000_D12F. All of this formatting produces strings, while the int just stays the same and doesn’t change its format. With a Date object it’s exactly the same: you can format it into many different strings, but the Date itself always stays the same.
Can I then have a LocalDate, a ZonedDateTime, a Calendar, a GregorianCalendar, an XMLGregorianCalendar, a java.sql.Date, Time or Timestamp in the format of my choice?
No, you cannot, and for the same reasons as above. None of the mentioned classes, in fact no date or time class I have ever met, can have a format. You can have your desired format only in a String outside your date-time object.
Links
Model–view–controller on Wikipedia
All about java.util.Date on Jon Skeet’s coding blog
Answers by Basil Bourque and Pitto explaining what to do instead (also using classes that are more modern and far more programmer friendly than Date)
If you are using JAVA8 API then this code will help.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateTimeString = LocalDateTime.now().format(formatter);
System.out.println(dateTimeString);
It will print the date in the given format.
But if you again create a object of LocalDateTime it will print the 'T' in between the date and time.
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime.toString());
So as mentioned in earlier posts as well, the representation and usage is different.
Its better to use "yyyy-MM-dd'T'HH:mm:ss" pattern and convert the string/date object accordingly.
use
Date date = new Date();
String strDate = sdf.format(date);
intead Of
Calendar cal = Calendar.getInstance();
String strDate = sdf.format(cal.getTime());
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateAndTime{
public static void main(String[] args)throws Exception{
Date date = new Date(System.currentTimeMillis());
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS",
Locale.ENGLISH);
String strDate = format.format(date);
System.out.println("Current date in String Format: "+strDate);
}
}
use this code u will get current date in expected string format
I have a String of a date and time like this: 2011-04-15T20:08:18Z. I don't know much about date/time formats, but I think, and correct me if I'm wrong, that's its UTC format.
My question: what's the easiest way to parse this to a more normal format, in Java?
tl;dr
String output =
Instant.parse ( "2011-04-15T20:08:18Z" )
.atZone ( ZoneId.of ( "America/Montreal" ) )
.format (
DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL )
.withLocale ( Locale.CANADA_FRENCH )
)
;
vendredi 15 avril 2011 16 h 08 EDT
Details
The answer by Josh Pinter is correct, but could be even simpler.
java.time
In Java 8 and later, the bundled java.util.Date/Calendar classes are supplanted by the java.time framework defined by JSR 310. Those classes are inspired by Joda-Time but are entirely re-architected.
The java.time framework is the official successor to Joda-Time. The creators of Joda-Time have advised we should migrate to java.time as soon as is convenient. Joda-Time continues to be updated and tweaked, but further innovation will be done only in java.time and its extensions in the ThreeTen-Extra project.
The bulk of java.time functionality has been back-ported to Java 6 & 7 in the ThreeTen-Backport project, and further adapted to Android in ThreeTenABP project.
The equivalent for the Joda-Time code above is quite similar. Concepts are similar. And like Joda-Time, the java.time classes by default use ISO 8601 formats when parsing/generating textual representations of date-time values.
An Instant is a moment on the timeline in UTC with a resolution of nanoseconds (versus milliseconds used by Joda-Time & java.util.Date).
Instant instant = Instant.parse( "2011-04-15T20:08:18Z" );
Apply a time zone (ZoneId) to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Adjust into yet another time zone.
ZoneId zoneId_NewYork = ZoneId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt.withZoneSameInstant( zoneId_NewYork );
To create strings in other formats beyond those of the toString methods, use the java.time.format classes. You can specify your own formatting pattern or let java.time localize automatically. Specify a Locale for (a) the human language used in translation of name of month/day-of-week, and (b) cultural norms for period-versus-comma, order of the parts, and such.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL );
formatter = formatter.withLocale( Locale.US );
String output = zdt_NewYork.format( formatter );
Friday, April 15, 2011 4:08:18 PM EDT
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.
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, 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 (<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.
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This section left intact for history.
Pass String To Constructor
Joda-Time can take that string directly. Simply pass to a constructor on the DateTime class.
Joda-Time understands the standard ISO 8601 format of date-times, and uses that format as its default.
Example Code
Here is example code in Joda-Time 2.3 running in Java 7 on a Mac.
I show how to pass the string to a DateTime constructor, in two ways: With and without a time zone. Specifying a time zone solves many problems people encounter in doing date-time work. If left unspecified, you get the default time zone which can bring surprises when placed into production.
I also show how specify no time zone offset (UTC/GMT) using the built-in constant DateTimeZone.UTC. That's what the Z on the end, short for Zulu time, means: No time zone offset (00:00).
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
// Default time zone.
DateTime dateTime = new DateTime( "2011-04-15T20:08:18Z" );
// Specified time zone.
DateTime dateTimeInKolkata = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "Asia/Kolkata" ) );
DateTime dateTimeInNewYork = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "America/New_York" ) );
// In UTC/GMT (no time zone offset).
DateTime dateTimeUtc = dateTimeInKolkata.toDateTime( DateTimeZone.UTC );
// Output in localized format.
DateTimeFormatter formatter = DateTimeFormat.shortDateTime().withLocale( Locale.US );
String output_US = formatter.print( dateTimeInNewYork );
Dump to console…
System.out.println("dateTime: " + dateTime );
System.out.println("dateTimeInKolkata: " + dateTimeInKolkata );
System.out.println("dateTimeInNewYork: " + dateTimeInNewYork );
System.out.println("dateTimeUtc: " + dateTimeUtc );
System.out.println("dateTime in US format: " + output_US );
When run…
dateTime: 2011-04-15T13:08:18.000-07:00
dateTimeInKolkata: 2011-04-16T01:38:18.000+05:30
dateTimeInNewYork: 2011-04-15T16:08:18.000-04:00
dateTimeUtc: 2011-04-15T20:08:18.000Z
dateTime in US format: 4/15/11 4:08 PM
Use JodaTime
I kept getting parsing errors using the other solutions with the Z at the end of the format.
Instead, I opted to leverage JodaTime's excellent parsing functionality and was able to do the following very easily:
String timestamp = "2011-04-15T20:08:18Z";
DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime(timestamp);
This correctly recognizes the UTC timezone and allows you to then use JodaTime's extensive manipulation methods to get what you want out of it.
Hope this helps others.
Already has lot of answer but just wanted to update with java 8 in case any one faced issues while parsing string date.
Generally we face two problems with dates
Parsing String to Date
Display Date in desired string format
DateTimeFormatter class in Java 8 can be used for both of these purpose.
Below methods try to provide solution to these issues.
Method 1:
Convert your UTC string to Instant. Using Instant you can create Date for any time-zone by providing time-zone string and use DateTimeFormatter to format date for display as you wish.
String dateString = "2016-07-13T18:08:50.118Z";
String tz = "America/Mexico_City";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm a");
ZoneId zoneId = ZoneId.of(tz);
Instant instant = Instant.parse(dateString);
ZonedDateTime dateTimeInTz =ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(dateTimeInTz.format(dtf));
Method 2:
Use DateTimeFormatter built in constants e.g ISO_INSTANT to parse string to LocalDate.
ISO_INSTANT can parse dates of pattern
yyyy-MM-dd'T'HH:mm:ssX e.g '2011-12-03T10:15:30Z'
LocalDate parsedDate
= LocalDate.parse(dateString, DateTimeFormatter.ISO_INSTANT);
DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("yyyy MM dd");
System.out.println(parsedDate.format(displayFormatter));
Method 3:
If your date string has much precision of time e.g it captures fraction of seconds as well as in this case 2016-07-13T18:08:50.118Z then method 1 will work but method 2 will not work. If you try to parse it will throw DateTimeException Since ISO_INSTANT formatter will not be able to parse fraction of seconds as you can see from its pattern.
In this case you will have to create a custom DateTimeFormatter by providing date pattern as below.
LocalDate localDate
= LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX"));
Taken from a blog link written by me.
The Java 7 version of SimpleDateFormat supports ISO-8601 time zones using the uppercase letter X.
String string = "2011-04-15T20:08:18Z";
DateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = iso8601.parse(string);
If you're stuck with Java 6 or earlier, the answer recommending JodaTime is a safe bet.
You have to give the following format:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date parse = simpleDateFormat.parse( "2011-04-15T20:08:18Z" );
I had a parse error in Andrew White solution.
Adding the single quote around the Z solved the issue
DateFormat m_ISO8601Local = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss'Z'");
the pattern in #khmarbaise answer worked for me, here's the utility method I extracted (note that the Z is omitted from the pattern string):
/**
* Converts an ISO-8601 formatted UTC timestamp.
*
* #return The parsed {#link Date}, or null.
*/
#Nullable
public static Date fromIsoUtcString(String isoUtcString) {
DateFormat isoUtcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
isoUtcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return isoUtcFormat.parse(isoUtcString);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
For all the older versions of JDK (6 down) it may be useful.
Getting rid of trailing 'Z' and replacing it literally with 'UTC' timezone display name - then parsing the whole string using proper simple date formatter.
String timeZuluVal = "2011-04-15T20:08:18Z";
timeZuluVal = timeZuluVal.substring( 0, timeZuluVal.length() - 2 ); // strip 'Z';
timeZuluVal += " " + TimeZone.getTimeZone( "UTC" ).getDisplayName();
DateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss zzzz" );
Date dateVal = simpleDateFormat.parse( timeZuluVal );
Joda Time
public static final String SERVER_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static DateTime getDateTimeFromUTC(String time) {
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(SERVER_TIME_FORMAT).withZoneUTC();
Calendar localTime = Calendar.getInstance();
DateTimeZone currentTimeZone = DateTimeZone.forTimeZone(localTime.getTimeZone());
return dateTimeFormatter.parseDateTime(time).toDateTime().withZone(currentTimeZone);
} catch (Exception e) {
return DateTime.now();
}
}