I get the following error:
´java.text.ParseException: Unparseable date: "Aug 31 09:53:19 2011"´ with this format: new SimpleDateFormat("MMM dd HH:mm:ss yyyy");
Does anyone see the problem?
Make sure you're using the correct locale. (The SimpleDateFormat(String) constructor uses the system default locale, which may not be the one you want to use.)
This works fine on my machine:
String input = "Aug 31 09:53:19 2011";
DateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", Locale.US);
System.out.println(df.parseObject(input));
(While using Locale.FRENCH for instance, results in a ParseException.)
The format itself is OK for the input you gave. But you might get this error if your default locale is set to something where "Aug" is not a valid abbreviation of a month name. Try using for example to Locale.US and you'll see that it will work:
DateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", Locale.US);
Date date = df.parse("Aug 31 09:53:19 2011");
tl;dr
Specify the Locale, to determine human language and cultural norms used in translating the name of month.
Use modern java.time classes rather that troublesome legacy classes.
Contrived example:
LocalDateTime.parse( // Parse input text as a `LocalDateTime` lacking any concept of time zone or offset-from-UTC.
"Aug 31 09:53:19 2011" ,
DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss yyyy" ) // Specify formatting pattern to match input string.
.withLocale( Locale.US ) // The `Locale` determines the human language and cultural norms used in translating the input text.
) // Returns a `LocalDateTime` object.
Details
The other two answers by aioobe and by Jesper are both correct: Implicitly using a Locale with a human language that does not match the language of your input text.
This Answer explains a new way of doing the job. Also, the other Answers do not address the crucial issue of time zone.
java.time
Fast forward a few years later from this posting, and we now have the new java.time package built into Java 8 and later. These new classes supplant the old java.util.Date/.Calendar & SimpleDateFormat classes. Those old classes have proven to be troublesome, confusing, and flawed.
Formatter Pattern
Define the data to be parsed and its format.
String input = "Aug 31 09:53:19 2011";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss uuuu" );
If not specified, the DateTimeFormatter is assigned the Locale that is currently the default in the JVM. That default can change at any moment, even during runtime(!). So always specify the desired/expected Locale.
formatter = formatter.withLocale( Locale.US ); // Or Locale.UK, Locale.CANADA_FRENCH, etc.
Given that the input lacks any time zone or offset-from-UTC information, parse as a LocalDateTime.
LocalDateTime ldt = LocalDateTime.parse( input , formatter );
If from the context you know the intended offset-from-UTC or a time zone for this date-time value, assign it.
If UTC, use the ZoneOffset.UTC constant to get a OffsetDateTime object.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
A time zone is an offset-from-UTC plus a set of rules for handling anomalies such as Daylight Saving Time (DST). Use proper time zone names, never the 3-4 letter abbreviations.
ZoneId zoneId_Montreal = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId_Montreal );
Specify Time Zone
This human language element was the key missing piece to answer the Question. Specifying the correct Locale for the human language matching the language of your input string solves that problem.
But note that the time zone is also critical; the other answers ignored this issue thereby implicitly using the JVM’s current default time zone. That is not advisable, as it depends on the host operating system as an initial default value (so may vary) and furthermore any code in any thread of any app within the JVM can change the JVM’s current default time zone during runtime. Better to specify the desired/expected time zone than rely implicitly on default.
Immutable Objects
Note the syntax. These classes are designed to be immutable. So rather than modifying (mutating) an object, a fresh new object is created based on the old object’s values. This means we are not affecting the DateTimeFormatter object defined above and held in the formatter variable (object reference). We are creating, using, and discarding a new DateTimeFormatter object (actually, two new objects) within this line of code.
Method Reference
The documentation suggests an alternative way to parse a string is to call the parse method where you pass a method reference (new in Java 8) from the class of the kind of result you desire (as the TemporalQuery): ZonedDateTime::from, LocalDateTime::from, LocalDate::from, and so on.
ZonedDateTime zdt = formatter.withZone( zoneId_Montreal ).withLocale( Locale.ENGLISH ).parse( input, ZonedDateTime :: from );
For demonstration, let's turn around and create a String representation of that ZonedDateTime value but in Québécois French.
String output = formatter.withLocale( Locale.CANADA_FRENCH ).format( zdt );
Even better, let’s localize rather than hard-code a particular format.
String outputLocalized = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ).format( zdt );
Dump to console.
System.out.println( "input: " + input );
System.out.println( "formatter: " + formatter );
System.out.println( "zdt: " + zdt );
System.out.println( "output: " + output );
System.out.println( "outputLocalized: " + outputLocalized );
When run.
input: Aug 31 09:53:19 2011
formatter: Text(MonthOfYear,SHORT)' 'Value(DayOfMonth,2)' 'Value(HourOfDay,2)':'Value(MinuteOfHour,2)':'Value(SecondOfMinute,2)' 'Value(YearOfEra,4,19,EXCEEDS_PAD)
zdt: 2011-08-31T09:53:19-04:00[America/Montreal]
output: août 31 09:53:19 2011
outputLocalized: mercredi 31 août 2011 9 h 53 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….
Related
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.DateFormat;
import groovy.time.TimeCategory
def startDate = 'Monday, May 11 2015'
def today = new Date().format( 'EEEE, MMM dd yyyy' )
def today1 = quantityService.normalizeAndFormat(today, DatumType.DATE,
Formatters.DATE_IN_WORDS)
def diff = today1.minus(startDate);
The startDate is a string extracted from the database. And is formatted exactly like today1 is formatted above to produce 'Monday, May 11 2015'. I am unable to perform the subtract operation to obtain the value of the variable diff. Can you please guide me on how can I obtain the value of diff in the same format like startDate? Currently, the operation doesn't work probably because startDate is a string and today1 is a date object.
tl;dr
Use modern java.time classes, not the terrible legacy classes. Never use Date or DateFormat or SimpleDateFormat.
Example code in Java syntax:
Period
.between(
LocalDate.parse(
"Monday, May 11 2015" ,
DateTimeFormatter.ofPattern( "EEEE, MMM d uuuu" , Locale.US )
) ,
LocalDate.now( ZoneId.of( "America/Los_Angeles" ) )
)
.toString() ;
P3Y8M18D
Avoid legacy date-time classes
You are using terrible date-time classes that were obsoleted years ago by the java.time classes, with the adoption of JSR 310.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-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( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
DateTimeFormatter
Define a formatting pattern to match your input. (Java syntax)
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEEE, MMM d uuuu" , Locale.US ) ;
String input = "Monday, May 11 2015" ;
LocalDate ld = LocalDate.parse( input , f ) ;
ld.toString(): 2015-05-11
Elapsed time
To calculate elapsed time as years-months-days, use Period. For days (24-hour chunks of time, not calendar days), hours, and seconds, use Duration.
Period p = Period.between( ld , today ) ;
p.toString(): P3Y8M18D
That string in standard ISO 8601 formats means “three years, eight months, and eighteen days”.
See the above code run live at IdeOne.com.
There is no localization feature in java.time to represent a Period or Duration with words. Instead, you can generate your own string.
String output = p.getYears() + " years, " + p.getMonths() + " months, " + p.getDays() + " days" ; // Obviously, you could get fancier by checking for zero or singular values and then adjust the text.
ISO 8601
Avoid exchanging date-time values using localized formats such as that seen in your input. Instead, when exchanging date-time values as text, always use the standard ISO 8601 formats. They were wisely designed to avoid ambiguity. They are easy to parse by machine, and easy to read by humans across cultures.
The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify any formatting pattern.
For a date-only value, the standard format is YYYY-MM-DD such as 2019-01-23.
LocalDate ld = LocalDate.parse( "2019-01-23" ) ;
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.
I am trying to parse the String to date. String having date format as
"dd-MMM-yyyy Z" and String having value "12-DEC-2018 ET". Its giving the error
java.text.ParseException: Unparseable date: "12-DEC-2018 ET".
The same code is working for String having value "12-DEC-2018 IST".
below is the code snippet:
public static void main(String[] args) throws ParseException {
String dateInputIST ="12-DEC-2018 IST";
String dateInputET ="12-DEC-2018 ET";
SimpleDateFormat sdfmt1 = new SimpleDateFormat("dd-MMM-yyyy Z");
SimpleDateFormat sdfmt2= new SimpleDateFormat("dd/MM/yyyy");
Date dDate = sdfmt1.parse( dateInputIST );
String strOutput = sdfmt2.format( dDate );
System.out.println(strOutput);
Date etDate = sdfmt1.parse(dateInputET);
strOutput = sdfmt2.format(etDate);
System.out.println(strOutput);
}
Could someone please help. I needed to parse the time in any timezone.
Thanks,
Navin
Change
String dateInputET ="12-DEC-2018 ET";
to
String dateInputET ="12-DEC-2018 EDT";
'ET' is not a recognized time zone.
Pseudo-zones
ET, EST, and IST are not actually time zones. Those 2-4 letter pseudo-zones are not standardized and are not even unique! For example, IST can mean India Standard Time, Ireland Standard Time, Iceland Standard Time, and more.
Real time zone names take the format of Continent/Region such as Africa/Tunis.
Date & zone, separately
Date with time zone has no real meaning.
Handle the date as a LocalDate object.
String input = "12-DEC-2018"
DayeTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" , Locale.US ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
Handle your desired time zone separately, as a ZoneId object.
ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
To combine, determine the first moment of the day.
ZonedDateTime zdtNewYork = ld.atStartOfDay( z ) ;
Generate text representing that moment in standard ISO 8601 format extended to append the name of the time zone in square brackets.
To see that same moment in UTC, extract a Instant.
Instant instant = zdtNewYork.toInstant() ;
Adjust into another zone.
ZonedDateTime zdtKolkata = instant.atZone( ZoneId.of( "Asia/Kolkata" ) ) ;
To focus on the date only, get a LocalDate for the day of that same moment when viewed through the lens of the wall-clock time used in India.
LocalDate ldKolkata = zdtKolkata.toLocalDate() ;
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.
java.time
DateTimeFormatter dateZoneFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd-MMM-uuuu v")
.toFormatter(Locale.ENGLISH);
String dateInputIST ="12-DEC-2018 IST";
String dateInputET ="12-DEC-2018 ET";
TemporalAccessor parsed = dateZoneFormatter.parse(dateInputIST);
System.out.println("Date: " + LocalDate.from(parsed) + " Time zone: " + ZoneId.from(parsed));
parsed = dateZoneFormatter.parse(dateInputET);
System.out.println("Date: " + LocalDate.from(parsed) + " Time zone: " + ZoneId.from(parsed));
On my computer the output from this snippet was:
Date: 2018-12-12 Time zone: Atlantic/Reykjavik
Date: 2018-12-12 Time zone: America/New_York
Format pattern letter v is for the generic time-zone name, that is, the name that is the same all year regardless of summer time (DST), for example Eastern Time or short ET.
If you want to control the interpretation of ambiguous time zone abbreviations (of which there are a lot), you may use the two-arg appendGenericZoneText(TextStyle, Set<ZoneId>) where the second argument contains the preferred zones. Still better if there is a way for you to avoid relying on time zone abbreviations altogether since, as I said, they are very often ambiguous.
I am not sure what sense a date with a time zone makes, though.
As an additional point, always specify locale for your formatters so they will also work if the default locale is changed or one day your program runs in a JVM with a different default locale.
Avoid SimpleDateFormat and Date
I don’t think SimpleDateFormat will be able to parse your string. It’s just the same since that class is already long outdated and is renowned for being troublesome, so you should never want to use it anyway.
I'm trying to parse date like this:
DateFormat df = new SimpleDateFormat("MMM dd, yyyy K:mm:ss,SSS a z", Locale.ENGLISH);
Date date = df.parse("Oct 04, 2015 2:11:58,757 AM UTC");
And I'm getting a value of 5 hours am, because i live in UTC+3 timezone. But i need to have value of 2am, however, with the same format string(date string given in a specified format, which i'm not allowed to change). How to do this?
Upd: I don't need to format the date in proper timezone, i need to COMPARE these dates by its values without timezones. I want exactly that date have parsed ignoring the timezone in original string - and be always in the same timezone (my, for example), no matter what contains original string: UTC or UTC+3 or something else.
The accepted Answer is working too hard. Manipulating offsets is the province of a date-time library. Doing such work yourself is a waste of your time, and likely to be a source of bugs.
The old java.util.Date/.Calendar classes are notoriously troublesome. Avoid them. Instead use either java.time or Joda-Time.
java.time
Java 8 and later has a new java.time framework built-in.
Confused Question
Your Question is confused. You say you want to ignore time zone, yet you accept an answer that does indeed parse and process the time zone. And that answer then adjusts the result by an offset. So, it seems that you do not want to ignore the time zone.
Indeed, ignoring the time zone rarely makes sense. Perhaps you want to compare a pair of factories in Berlin and in Detroit to see if they both take a lunch break at the same time. In this case you are comparing their respective wall-clock time. The java.time framework offers the “Local” classes for this purpose: LocalDate, LocalTime, and LocalDateTime. But this is rarely needed in most business scenarios in my experience. These objects are not tied to the timeline.
So it seems that what you do want is to be able to compare date-time values across various time zones. The java.time classes do that implicitly. ZonedDateTime objects with various assigned time zones can be compared to one another with isBefore, isAfter, and isEqual methods.
Example Code
First we parse the input string.
The z pattern code means to expect and parse a time zone. The resulting date-time object will also be assigned this object if no other specific time zone is specified.
We also assign a Locale object with a human language component matching the text we expect to see in the input string. In this case, we need any Locale with English.
String input = "Oct 04, 2015 2:11:58,757 AM UTC";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd, yyyy K:mm:ss,SSS a z" ).withLocale( Locale.ENGLISH );
ZonedDateTime then = ZonedDateTime.parse( input, formatter );
Next we get the current time for Québec. This arbitrary choice of time zone will demonstrate further below that we can compare this ZonedDateTime object to another with a different time zone. Specifically, comparing against the UTC time zone assigned to our then object above.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
Do the comparison.
Boolean isThenBeforeNow = then.isBefore( now );
By the way, generally-speaking, the best practice in date-time work is to convert all your date-time values to UTC time zone for business logic, storage, and data exchange. Adjust into a time zone only as need be to satisfy a user’s expectations on-screen or in reports.
ZonedDateTime nowUtc = now.withZoneSameInstant( ZoneOffset.UTC );
Dump to console.
System.out.println( "input: " + input );
System.out.println( "then: " + then );
System.out.println( "now: " + now );
System.out.println( "isThenBeforeNow: " + isThenBeforeNow );
System.out.println( "nowUtc: " + nowUtc );
When run.
input: Oct 04, 2015 2:11:58,757 AM UTC
then: 2015-10-04T02:11:58.757Z[UTC]
now: 2015-10-19T19:28:04.619-04:00[America/Montreal]
isThenBeforeNow: true
nowUtc: 2015-10-19T23:28:04.619Z
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.
Upd2: Solved
Okay, now i get what i want:
DateFormat df = new SimpleDateFormat("MMM dd, yyyy K:mm:ss,SSS a z", Locale.ENGLISH);
Date date = df.parse("Oct 04, 2015 2:11:58,757 AM UTC");
long diff = TimeZone.getDefault().getRawOffset() - df.getTimeZone().getRawOffset();
date = new Date(date.getTime()-diff);
Anyway, thanks for everyone
Please help me to format properly my String.
I really need to display "10 November 2015" instead of 10/11/2015
Calendar now = Calendar.getInstance();
now.add(Calendar.MONTH, 10);
textView1.setText(("date after 10 months : " + (now.get(Calendar.MONTH) + 1) + "-"
+ now.get(Calendar.DATE) + "-" + now.get(Calendar.YEAR)));
System.out.println(new SimpleDateFormat("dd MMMM yyyy", Locale.ENGLISH)
.format(new java.util.Date()));
Always stay on the safer size specify the Locale.
Use SimleDateFormat as given by other. Use the below string to get desired output.
SimpleDateFormat format = new SimpleDateFormat("dd MMMM yyyy")
use new SimpleDateFormat("dd MMMM yyyy")Read more about SimpleDateFormat
here you can use this function:-
public static void main(String[] args) throws ParseException {
System.out.println(new SimpleDateFormat("dd MMMM yyyy").parse("10/11/2015"));
}
tl;dr
Apparently you want to get the current date as seen in the wall-clock time used by the people of a particular region, add ten months, and then generate text representing the value of that found date.
LocalDate.now(
ZoneId.of( "Pacific/Auckland" )
)
.plus(
Period.ofMonths( 10 )
)
.format(
DateTimeFormatter.ofLocalizedDate( FormatStyle.LONG )
.withLocale( Locale.ITALY )
)
java.time
The modern approach uses the java.time classes that supplanted the terrible Date & Calendar classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your [desired/expected time zone][2] explicitly as an argument.
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( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Adding to a date
Define the span-of-time you want to add.
Period p = Period.ofMonths( 10 ) ; // Ten months span, unattached to timeline.
Add the period to our LocalDate to get another LocalDate. As an immutable object, LocalDate produces a new instance based on the values of the original object.
LocalDate later = ld.plus( p ) ;
Generating text
To generate text in standard ISO 8601 format, call toString.
String output = later.toString() ;
To generate text in a String representing the value of our LocalDate, use the DateTimeFormatter class.
Generally best to let java.time automatically localize by calling the DateTimeFormatter.ofLocalized… methods.
To hard-code a specific format, specify a formatting pattern.
This has been covered many times already, so search Stack Overflow for more discussion and examples.
To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine:
The human language for translation of name of day, name of month, and such.
The cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Example:
Locale l = Locale.CANADA_FRENCH ; // Or Locale.US, Locale.JAPAN, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.LONG )
.withLocale( l );
String output = later.format( f );
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.
Use the SimpleDateFormat class.
Check this http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
i have this piece of code , where i am trying to convert a date string from one format to another, and finally i want the date object again.
String dateString = "2014-10-04";
SimpleDateFormat oldFormatter = new SimpleDateFormat("yyyy-MM-dd");
Date parsedDate = oldFormatter.parse(dateString);
SimpleDateFormat newFormatter = new SimpleDateFormat("dd-MMM-yyyy");
String convertDateStr = newFormatter.format(parsedDate);
Date convertedDate = newFormatter.parse(convertDateStr);
when i was testing above code with dateString value as "2014-10-04", the above code executes properly but the convertedDate format changed to "Sat Oct 04 00:00:00 IST 2014" instead of "dd-MMM-yyyy" format.
i have functionality like i have two dates with different format, and need to get difference in days remaining while comparing, so i need to convert one date format to other date before getting the difference in number of days.
EDIT - is there an alternate option to convert datestring to a specified format and get back date object with converted format
tl;dr
LocalDate.parse( // Represent a date-only value with a date-only class.
"2014-10-04" // Inputs in standard ISO 8601 format are parsed by default. No need to specify a formatting pattern.
) // Returns a `LocalDate` object. Do not conflate a date-time object with a String that represents its value. A `LocalDate` has no “format”.
.format( // Generate a String representing the `LocalDate` object’s value.
DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) // Define your custom formatting pattern. Specify `Locale` for human language and cultural norms used in localization.
) // Return a String.
java.time
The modern approach uses java.time classes that supplanted the troublesome old legacy date-time classes such as Date/Calendar/SimpleDateFormat.
Use a date-only class for date-only values, rather than a date+time class. The LocalDate class represents a date-only value without time-of-day and without time zone.
Your input string happens to comply with standard ISO 8601 format. The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
String input = "2014-10-04" ;
LocalDate ld = LocalDate.parse( input ) ; // No need to specify a formatting pattern for ISO 8601 inputs.
To generate a string representing the LocalDate object’s value in a particular format, define the formatting pattern. Specify a Locale object to determine the human language and cultural norms used in localizing.
Locale locale = Locale.US ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , locale ) ;
String output = ld.format( f ) ;
04-Oct-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, 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.
A Date object doesn't have format built into it, that is what the SimpleDateFormat does.
When you convert convertDateStr back into a Date object, you've lost the formatting.
Run these after your block of code and you'll see what I mean.
System.out.println(convertedDate);
System.out.println(newFormatter.format(convertedDate));
The Date object doesn't store a format for the date. That output you are seeing is simply the result of its toString method. If you want a date in a specific format, you must always use a formatter to get the string version of the date in the format you want.
You can use this
public static Date getDateFromString(String format, String dateStr) {
DateFormat formatter = new SimpleDateFormat(format);
Date date = null;
try {
date = (Date) formatter.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
public static String getDate(Date date, String dateFormat) {
DateFormat formatter = new SimpleDateFormat(dateFormat);
return formatter.format(date);
}
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This Answer left intact for history.
As explained in the correct answer by forgivenson and in many other questions and answers found by searching StackOverflow for "java date format" or "java date parse" or such:
A java.util.Date object has no format. A j.u.Date is not text. A j.u.Date does not contain a String. A j.u.Date object contains a number of milliseconds since the Unix epoch (ignoring Leap Seconds).
You can generate a String representation of the date-time value of a java.util.Date by either calling its toString implementation or by using a formatter.
The toString method of java.util.Date is confusing in that it applies the JVM's default time zone. The result implies a j.u.Date has a time zone when in fact it does not.
The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. Use a decent date-time library such as Joda-Time or the new java.time package bundled in Java 8.
Your code ignores the crucial issue of time zones. A java.util.Date has a date and a time, and so you need to pay attention to time zones.
Joda-Time and java.time both use formatting defined by the ISO 8601 standard as their default. You may define your own formats as well, or use localized formats.
So your phrase "get back date object with converted format" is a contradiction. A date-time object (whether java.util.Date or Joda-Time or java.time) has no format. You are confusing the string representation generated from a date-time object with the date-time object itself.
Example code using Joda-Time 2.3…
String input = "2014-10-04";
DateTimeZone timeZoneIndia = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZoneIndia ); // Defaults to beginning of the day.
DateTime dateTimeUtc = dateTimeIndia.withZone( DateTimeZone.UTC );
DateTime octoberSecond = new DateTime( 2014, 10, 2, 1, 2, 3, timeZoneIndia ).withTimeAtStartOfDay();
DateTimeFormatter formatter_Iso = ISODateTimeFormat.date();
String dateTimeIndiaAsStringIso = formatter_Iso.print( dateTimeIndia );
DateTimeFormatter formatter_Dmy = DateTimeFormat.forPattern( "dd-MM-yyyy" );
String dateTimeIndiaAsStringDmy = formatter_Dmy.print( dateTimeIndia );
DateTime dateTimeAgain = formatter_Dmy.withZone( timeZoneIndia ).parseDateTime( dateTimeIndiaAsStringDmy ); // Defaults to beginning of the day.
DateTimeFormatter formatter_Québécois = DateTimeFormat.forStyle( "FF" ).withLocale( Locale.CANADA_FRENCH );
String dateTimeIndiaAsStringQuébécois = formatter_Québécois.print( dateTimeIndia );
int daysBetween = Days.daysBetween( octoberSecond, dateTimeIndia ).getDays();
Interval interval = new Interval( octoberSecond, dateTimeIndia );
Period period = interval.toPeriod();
java.util.Date date = dateTimeIndia.toDate();
input: 2014-10-04
dateTimeIndia: 2014-10-04T00:00:00.000+05:30
dateTimeUtc: 2014-10-03T18:30:00.000Z
octoberSecond: 2014-10-02T00:00:00.000+05:30
dateTimeIndiaAsStringIso: 2014-10-04
dateTimeIndiaAsStringDmy: 04-10-2014
dateTimeAgain: 2014-10-04T00:00:00.000+05:30
dateTimeIndiaAsStringQuébécois: samedi 4 octobre 2014 0 h 00 IST
daysBetween: 2
interval: 2014-10-02T00:00:00.000+05:30/2014-10-04T00:00:00.000+05:30
period: P2D
date: Fri Oct 03 11:30:00 PDT 2014
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "octoberSecond: " + octoberSecond );
System.out.println( "dateTimeIndiaAsStringIso: " + dateTimeIndiaAsStringIso );
System.out.println( "dateTimeIndiaAsStringDmy: " + dateTimeIndiaAsStringDmy );
System.out.println( "dateTimeAgain: " + dateTimeAgain );
System.out.println( "dateTimeIndiaAsStringQuébécois: " + dateTimeIndiaAsStringQuébécois );
System.out.println( "daysBetween: " + daysBetween );
System.out.println( "interval: " + interval );
System.out.println( "period: " + period );
System.out.println( "date: " + date ); // Applies JVM's default time zone. North America west coast time zone in my case.
When run…
input: 2014-10-04
dateTimeIndia: 2014-10-04T00:00:00.000+05:30
dateTimeUtc: 2014-10-03T18:30:00.000Z
octoberSecond: 2014-10-02T00:00:00.000+05:30
dateTimeIndiaAsStringIso: 2014-10-04
dateTimeIndiaAsStringDmy: 04-10-2014
dateTimeAgain: 2014-10-04T00:00:00.000+05:30
dateTimeIndiaAsStringQuébécois: samedi 4 octobre 2014 0 h 00 IST
daysBetween: 2
interval: 2014-10-02T00:00:00.000+05:30/2014-10-04T00:00:00.000+05:30
period: P2D
date: Fri Oct 03 11:30:00 PDT 2014