This question already has answers here:
Make SimpleDateFormat.parse() fail on invalid dates (e.g. month is greater than 12)
(4 answers)
Closed 4 years ago.
Is there a Date exception that I can deal with when I try to parse a date with this code here:
try{
SimpleDateFormat df = new SimpleDateFormat("dd:MM:yyyy");
Date date = df.parse(dateRelease);
}catch (ParseException e) {}
Well, if the "dateRelease" isn't in a correct format type it throws ParseException, but I want to get if someone write like "40/03/2010" - WRONG with day, month or year invalid range. Actually, when a invalid date is sent, SimpleDateFormat just create a new Date with default numbers.
Do I have to create my own method with a regex to deal with it or is there an existing exception that tells me it to catch?
Make it non-lenient by SimpleDateFormat#setLenient() with a value of false.
SimpleDateFormat df = new SimpleDateFormat("dd:MM:yyyy");
df.setLenient(false);
Date date = df.parse(dateRelease);
Then it will throw ParseException when the date is not in a valid range.
tl;dr
try {
LocalDate localDate = LocalDate.parse(
"40:03:2010" , // "40:03:2010" is bad input, "27:03:2010" is good input.
DateTimeFormatter.ofPattern( "dd:MM:uuuu" )
) ;
} catch ( DateTimeParseException e ) {
… // Invalid input detected.
}
Using java.time
The modern way is with the java.time classes built into Java 8 and later.
Your example data does not match the format shown in your example code. One uses SOLIDUS (slash) character, the other uses COLON character. I'll go with COLON.
DateTimeFormatter
Define a formatting pattern to match the input string.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd:MM:uuuu" );
LocalDate
Parse as a LocalDate object as the input has no time-of-day and no time zone.
LocalDate localDateGood = LocalDate.parse( "27:03:2010" , f );
System.out.println( "localDateGood: " + localDateGood );
Now try some bad input. Trap for the appropriate exception.
try {
LocalDate localDateBad = LocalDate.parse( "40:03:2010" , f );
} catch ( DateTimeParseException e ) {
System.out.println( "ERROR - Bad input." );
}
See this code run live in IdeOne.com.
localDateGood: 2010-03-27
ERROR - Bad input.
ISO 8601
Use standard ISO 8601 formats when exchanging/storing date-time values as text. The standard formats are sensible, practical, easily read by humans of various cultures, and easy for machines to parse.
For a date-only value the standard format is YYYY-MM-DD such as 2010-03-27.
The java.time classes use standard ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern at all.
LocalDate localDate = LocalDate.parse( "2010-03-27" );
String output = localDate.toString(); // 2010-03-27
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 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 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
I did a lot of searches trying to find this solution. Messing with dates in Java gives me a headache. Most of the results I found were using math to find a previous date or about finding a date offset from today's date. I really needed something from a predefined date (not today). I messed with a lot of classes and code before finding what I needed.
This is also my first post here. I'm a veteran lurker. I hope this saves someone the time I took to find this.
Submit date Dec 2, 2014 and find the date from the week before.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class FilenameDateFormat {
SimpleDateFormat fileDateFormat = new SimpleDateFormat("yyyyMMdd");
public static void main(String[] args) throws ParseException {
new FilenameDateFormat("20141202", -7);
}
public FilenameDateFormat(String dateArg, int offsetDays) throws ParseException {
Date fileDate = fileDateFormat.parse(dateArg);
Calendar cal = new GregorianCalendar();
cal.setTime(fileDate);
cal.add(Calendar.DAY_OF_MONTH, offsetDays);
System.out.println(cal.getTime());
}
}
RESULT
Tue Nov 25 00:00:00 EST 2014
Why dont you use new java.time api ? This could be easily acomplished in java8.
https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html
tl;dr
LocalDate.parse(
"20141202" ,
DateTimeFormatter.BASIC_ISO_DATE
).minusWeeks( 1 )
2014-11-25
Avoid legacy date-time classes
Messing with dates in Java gives me a headache.
Date-time work in general is tricky, slippery, elusive.
And using the troublesome old date-time classes (java.util.Date, java.util.Calendar, etc.) makes the work all the more difficult. Those old classes are now legacy, supplanted by the java.time classes.
LocalDate
Submit date Dec 2, 2014
The LocalDate class represents a date-only value without time-of-day and without time zone.
Your input string happens to be in the “basic” version of the standard ISO 8601 format. The canonical version includes hyphens, 2014-12-02, while the “basic” version minimizes the use of separators, 20141202. I strongly suggest using the fuller version when possible to improve readability and reduce ambiguity/confusion.
DateTimeFormatter
The DateTimeFormatter class includes a pre-defined formatting pattern for your input, DateTimeFormatter.BASIC_ISO_DATE.
String input = "20141202" ;
DateTimeFormatter f = DateTimeFormatter.BASIC_ISO_DATE ;
LocalDate ld = LocalDate.parse( input , f );
In real code, trap for the DateTimeParseException being thrown because of bad input.
String input = "20141202" ;
DateTimeFormatter f = DateTimeFormatter.BASIC_ISO_DATE ;
LocalDate ld = null;
try{
ld = LocalDate.parse( input , f );
} catch ( DateTimeParseException e ) {
… // Handle error because of bad input.
}
Subtracting a week
find the date from the week before
Subtract a week. Note that java.time uses immutable objects. So rather than alter (mutate) the values in an object, we generate a new and separate object based on the original’s values.
LocalDate oneWeekAgo = ld.minusWeeks( 1 );
input: 20141202
ld.toString(): 2014-12-02
oneWeekAgo.toString(): 2014-11-25
See live code in IdeOne.com.
If you want a String in the same format as the input, use the same formatter seen above.
String output = oneWeekAgo.format( DateTimeFormatter.BASIC_ISO_DATE );
20141125
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 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 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 have a problem in converting the date in java, don't know where i am going wrong...
String dateStr = "2011-12-15";
String fromFormat = "yyyy-mm-dd";
String toFormat = "dd MMMM yyyy";
try {
DateFormat fromFormatter = new SimpleDateFormat(fromFormat);
Date date = (Date) fromFormatter.parse(dateStr);
DateFormat toformatter = new SimpleDateFormat(toFormat);
String result = toformatter.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
Input date is 2011-12-15 and I am expecting the result as "15 December 2011", but I get it as "15 January 2011"
where am I going wrong?
Your fromFormat uses minutes where it should use months.
String fromFormat = "yyyy-MM-dd";
I think the fromFormat should be "yyyy-MM-dd".
Here is the format:
m == Minute in Hour
M == Month in Year
More: http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
From format should be:
String fromFormat = "yyyy-MM-dd"
Look at the javadoc of SimpleDateFormat and look at what the m represents. Not months as you think but minutes.
String fromFormat = "yyyy-MM-dd";
m in SimpleDateFormat stands for minutes, while M stands for month. Thus your first format should be yyyy-MM-dd.
tl;dr
LocalDate.parse( "2011-12-15" ) // Date-only, without time-of-day, without time zone.
.format( // Generate `String` representing value of this `LocalDate`.
DateTimeFormatter.ofLocalizedDate( FormatStyle.LONG ) // How long or abbreviated?
.withLocale( // Locale used in localizing the string being generated.
new Locale( "en" , "IN" ) // English language, India cultural norms.
) // Returns a `DateTimeFormatter` object.
) // Returns a `String` object.
15 December 2011
java.time
While the accepted Answer is correct (uppercase MM for month), there is now a better approach. The troublesome old date-time classes are now legacy, supplanted by the java.time classes.
Your input string is in standard ISO 8601 format. So no need to specify a formatting pattern for parsing.
LocalDate ld = LocalDate.parse( "2011-12-15" ); // Parses standard ISO 8601 format by default.
Locale l = new Locale( "en" , "IN" ) ; // English in India.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.LONG )
.withLocale( l );
String output = ld.format( f );
Dump to console.
System.out.println( "ld.toString(): " + ld );
System.out.println( "output: " + output );
ld.toString(): 2011-12-15
output: 15 December 2011
See live code in IdeOne.com.
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.
Well this may not be your case but may help someone. In my case after conversion, day of month and month set 1. So whatever date is, after conversion i get 1 jan which is wrong.
After struggling i found that in date format i have used YYYY instead of yyyy. When i changed all caps Y to y it works fine.
this is the code which returns Date but at the client side i am getting
2016-12-26 14:18:57.0 at the client side . what is the possible solution .. I am using node.js at the client side. But I think it has nothing to do with this problem . I WANT TO REMOVE THIS 0
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date date = sdf.parse(value);
if (!value.equals(sdf.format(date))) {
date = null;
}
return date != null;
Try to set proper format in SimpleDateFormat constructor. Something like this:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String value = "2016-12-26 14:18:57";
Date date = sdf.parse(value);
if (!value.equals(sdf.format(date))) {
System.out.println("not equals");
}
System.out.println("date = " + date);
You are not giving a format pattern string to the SimpleDateFormat constructor, so it uses some default pattern. The solution is to provide a proper format string.
The formatting can be done like this:
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss.SSS")
which would result e.g. in
29.02.2016 23:01:15.999
You want to omit the S format symbols (milliseconds) in the format string. E.g.:
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss")
Of course you need to change this example to your format needs. Play a bit with the order and number of symbols, confer the docs.
tl;dr
LocalDateTime.parse(
"2016-12-26 14:18:57.0".replace( " " , "T" )
)
.truncatedTo( ChronoUnit.SECONDS )
.toString()
.replace( "T" , " " )
Avoid legacy date-time classes
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.
ISO 8601
First replace the SPACE in the middle of your input string to make it comply with the standard ISO 8601 format.
String input = "2016-12-26 14:18:57.0".replace( " " , "T" );
LocalDateTime
Parse as a LocalDateTime given that your input string lacks any indication of offset-from-UTC or time zone.
LocalDateTime ldt = LocalDateTime.parse( input );
Generate a String by simply calling toString. By default an ISO 8601 format is used to create the String. If the value has no fractional second, no decimal mark nor any fractional seconds digits appear.
String output = ldt.toString ();
ldt.toString(): 2016-12-26T14:18:57
If you dislike the T in the middle, replace with a SPACE.
output = output.replace( "T" , " " );
2016-12-26 14:18:57
If your input might carry a fractional second and you want to delete that portion of data entirely rather than merely suppress its display, truncate the LocalDateTime object.
LocalDateTime ldtTruncated = ldt.truncatedTo( ChronoUnit.SECONDS ); // Truncate any fraction of a second.
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 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 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 have the following string variables in which dates are stored in format of dd/mm/yy that is UK format
String s= "04-MAR-15"
String t ="04/03/15"
String p ="04/03/2015"
String w ="04-03-2015"
now i want to convert their format in DD/MM/YYYY format,
please advise how can I convert their format through simple date format in java and show on console.
The process is a two step process:
Convert the String to a Date using the parse method of DateFormat
Convert the Date to the new String using the method format of a DateFormat with the desired format
Use the SimpleDateFormat concrete class. See the documentation to understand the desired pattern.
Try parsing with each expected format
When you have inputs of various formats, if those formats are mutually exclusive (not ambiguous for one another), simply try parsing each known possible format until one works. When a parsing attempt fails, catch the Exception thrown and try parsing with the next format.
For more information on parsing a string into a date-only object, see How can I change the date format in Java? and many other posts already made on Stack Overflow. Here's a brief example of code.
First, define and collect a series of formatters for each expected format.
Locale locale = Locale.UK ;
List<DateTimeFormatter> formatters = new ArrayList<>( 4 );
formatters.add( DateTimeFormatter.ofPattern( "dd-MMM-uu" , locale ) ) ;
formatters.add( DateTimeFormatter.ofPattern( "dd-MM-uu" , locale ) ) ;
formatters.add( DateTimeFormatter.ofPattern( "dd/MM/uuuu" , locale ) ) ;
formatters.add( DateTimeFormatter.ofPattern( "dd-MM-uuuu" , locale ) ) ;
Try each formatter successively until one succeeds.
LocalDate ld = null ;
for( DateTimeFormatter f : formatters ) {
try{
ld = LocalDate.parse( input , f );
break ; // End this 'for' loop. We succeeded in parsing, so no need to try more formatters.
} catch ( DateTimeParseException e ) {
// Swallow this exception as we expect it when trying a series of formatters.
}
}
Test to see if all the formatters failed to parse. This means we received an input of unexpected format, an error situation.
if( null == ld ) { // All the formatters were tried but failed.
… // Deal with unexpected input.
}
Generate a new String as your output using DateTimeFormatter. Consider using the ofLocalized… method rather than specify a particular format.
ISO 8601
Personally, I recommend against ever using a two-digit year. That causes no end of confusion being ambiguous with the month and day-of-month. Memory is cheap enough, and screens big enough, that we can easily afford the bits and pixels to support the luxury of 4-digit years.
Also, consider avoiding your patterns entirely. For data exchange, use only the standard ISO 8601 formats. For a date only that would be YYYY-MM-DD such as 2017-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.
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.
This question already has answers here:
convert string date to java.sql.Date [duplicate]
(2 answers)
Closed 5 years ago.
I have a graphical user interface which takes some user inputs, it takes the current date also. Then I need to store them in a database. Everything is fine but I cannot understand the way how should I parse the input string of date field to mysql date for inserting it into the database.
I have a code like this.
Date date = txtToday.getText();
I know this should be parsed in to a type which is compatible with Data data type.
This Date type is from java.sql.Date.
How can I overcome this issue.?
MySQL’s default DATE field format is: YYYY-MM-DD
Whereas in Java, the Date class’ (available in java.util package) default format is,dow mon dd hh:mm:ss zzz yyyy
so use this:
Date date = txtToday.getText();
String pattern = "yyyy-MM-dd";
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
String mysqlDateString = formatter.format(date);
System.out.println("Java's Default Date Format: " + date);
System.out.println("Mysql's Default Date Format: " + mysqlDateString);
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Date dob = null;
dob = sdf.parse(txtToday.getText());
java.sql.Date sqlDate = new java.sql.Date(dob.getTime());
c1.setDOB(sqlDate); //use this sqlDate for inserting into Database
} catch (ParseException e) {
System.out.println("Parse exception,incorrect input in the textbox");
e.printStackTrace();
}
If this line of code works...
Date date = txtToday.getText();
Then just use the time to convert it to a sql Date...
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
See my Answer to a duplicate Question.
Using java.time
Use the modern java.time classes rather than the troublesome legacy date-time classes.
No need to use java.sql.Date. That class is replaced by LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.
JDBC drivers that comply with JDBC 4.2 can deal directly with java.time types by calling:
PreparedStatement::setObjectmyPrepStmt.setObject( … , myLocalDate ) ;
ResultSet::getObjectLocalDate ld = myResultSet.getObject( … , LocalDate.class );
For presentation of the LocalDate to the user, generate a String for display in your user-interface. Use a DateTimeFormatter to automatically localize. To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Example:
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );
You can go the other direction as well, parsing an input string to get a date.
LocalDate ld = LocalDate.parse( input , f ) ;
Trap for the exception thrown if the user’s input is faulty or unexpected.
try{
LocalDate ld = LocalDate.parse( input , f ) ;
myPrepStmt.setObject( … , ld ) ;
} catch ( DateTimeParseException e ) {
… // Handle the error condition of faulty/unexpected input by user.
}
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.