Lenient SimpleDateFormat acting strange - java

I understand that, in order to properly validate date strings, one must make DateFormat instances non-lenient to get all ParseExceptions from malformed dates. But consider
String dubiousDate = "2014-04-01";
DateFormat sdf = new SimpleDateFormat( "yyyyMMdd");
Date d;
try {
d = sdf.parse( dubiousDate);
System.out.println( dubiousDate + " -> " + d);
} catch ( ParseException e) {
e.printStackTrace();
System.err.println( dubiousDate + " failed");
}
this will give
2014-04-01 -> Wed Dec 04 00:00:00 CET 2013
Now I can understand that the lenient calendars try to be nice and accept funny negative numbers, but this interpretation looks like the -01 is considered as month, even though it appears last, where the days are. And the -04 months become 04 days, with the minus ignored.
In all leniency, why would this make sense to anyone?

I see another possible interpretation:
In the pattern yyyyMMdd the month part is limited to exact two chars because there are no separators between the different numerical fields. So "-0" will be seen as month which is just zero and is one month behind January yielding December in previous year.
After having "parsed" the fake month, the day part comes with "4" stopping before the second minus char. The result is then the fourth of December.
Finally, the remaining chars "-01" are simply ignored. This is typical for the class SimpleDateFormat about how to handle non-digit trailing chars, for example see this code:
String dubiousDate = "2014-04-01xyz";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d;
try {
d = sdf.parse(dubiousDate);
System.out.println(dubiousDate + " -> " + d);
// output: Tue Apr 01 00:00:00 CEST 2014
} catch (ParseException e) {
e.printStackTrace();
System.err.println(dubiousDate + " failed");
}
As thumb rule, with only two equal symbol chars MM or dd the parser will only consume up to at most two chars (if digits are found).
Some research about Java 8:
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.parseLenient();
builder.append(DateTimeFormatter.ofPattern("yyyyMMdd"));
DateTimeFormatter dtf = builder.toFormatter();
String dubiousDate = "2014-04-01";
LocalDate date = LocalDate.parse(dubiousDate, dtf);
System.out.println(date);
According to JDK-8-documentation the formatter constructed this way should behave leniently, but unfortunately still throws an exception:
"Exception in thread "main" java.time.format.DateTimeParseException: Text '2014-04-01' could not be parsed at index 3"
Best option would be in lenient case - theoretically - if the parser just ignores the minus chars. But obviously this is not possible with JSR-310 (still too strict). Well, SimpleDateFormat is lenient, but in rather a wrong way.

This doesn't make sense. It sounds like a bug to me.
I think the right answer is to wait for Java 8 where dates are finally done right. Your code, for example, could now change to something like what is below. And, Java will throw an exception, like it should.
import java.util.*;
import java.lang.*;
import java.io.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String dubiousDate = "2014-04-01";
LocalDate d;
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
d = LocalDate.parse(dubiousDate, formatter);
System.out.println(dubiousDate + " -> " + d);
}
catch (Exception e) {
e.printStackTrace();
System.err.println(dubiousDate + " failed");
}
}
}
}

Related

Is DateTimeFormatter more strict than SimpleDateFormat? Parsing date with milliseconds

I have simple test case:
public static void main(String[] args) {
String pattern = "yyyy-MM-dd HH:mm:ss.SSS";
String date = "2017-01-15 15:15:15.5";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
FastDateFormat fastDateFormat = FastDateFormat.getInstance(pattern);
try {
System.out.println("SFD: " + simpleDateFormat.parse(date));
}catch (Exception e) {
System.err.println("SDF failed");
}
try {
System.out.println("DTF: " + dateTimeFormatter.parse(date));
}catch (Exception e) {
System.err.println("DTF failed");
}
try {
System.out.println("FDF: " + fastDateFormat.parse(date));
}catch (Exception e) {
System.err.println("FDF failed");
}
}
Output is like this:
SFD: Thu Jan 15 15:15:15 CET 1970
DTF failed
FDF: Thu Jan 15 15:15:15 CET 1970
According to the results, Java's 8 DateTimeFormatter is more strict then SimpleDateFormat. My question is why and in that case, what would be best approach to accept both dates with .S as millis or .SSS, like parsing multiple times with try/catch ?
SimpleDateFormat's is not strict per default, because the property lenient is true per default. But you can set the property lenient to false to make it strict.
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
simpleDateFormat.setLenient(false);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
try {
System.out.println("SFD: " + simpleDateFormat.parse(date));
} catch (Exception e) {
System.err.println("SDF failed");
}
try {
System.out.println("DTF: " + dateTimeFormatter.parse(date));
} catch (Exception e) {
System.err.println("DTF failed");
}
The result will be then
SDF failed
DTF failed
See DateFormat.parse(String, ParsePosition)
By default, parsing is lenient: If the input is not in the form used by this object's format method but can still be parsed as a date, then the parse succeeds. Clients may insist on strict adherence to the format by calling setLenient(false).
You are basically asking why SimpleDateFormat accepts one digit millisecond values when the pattern says ".SSS".
The reason is in the javadoc for SimpleDateFormat:
Pattern letters are usually repeated, as their number determines the exact presentation:
...
Number: For formatting, the number of pattern letters is the minimum number of digits, and shorter numbers are zero-padded to this amount. For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.
Apparently, you can change this by calling setLenient(false). However, the javadocs don't specify what the actual effect of leniency is.
By contrast, the javadoc for DateTimeFormatter simply says "the count of pattern letters determines the format", making no distinction between formatting and parsing.
Why are they different? You would need to ask the people who designed the DateTimeFormatter API, but I imagine it was that the designers considered the ad hoc and unspecified nature of SimpleDateFormat (default) lenient parsing mode to be harmful.
How do you simply get DateTimeFormatter to accept dates with one or 3 digits millisecond values?
One approach would be to create the formatter using a DateTimeFormatterBuilder. This allows you to specify a minimum and maximum width for any field in the format.

Regex pattern for date format yyyy/MM/dd

I need to validate a date with format yyyy/MM/dd using a regex pattern. I already have a regex for the format dd/MM/yyyy.
(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)
I'm using the validation from this link http://www.mkyong.com/regular-expressions/how-to-validate-date-with-regular-expression. I need the validation for yyyy/MM/dd. Can anyone help me?
I have found the answer:
((?:19|20)\\d\\d)/(0?[1-9]|1[012])/([12][0-9]|3[01]|0?[1-9])
Old question, I know, but as I've just had cause to do this:
\d{4}\\\d{2}\\\d{2}
Looks a lot neater to my eyes than the other suggestions, and works outside of the 20th/21st century (unclear if OP required this or not).
However, my implementation will match for dates such as 9999/99/99 (clearly invalid) - but as a commenter suggested, SimpleDateFormat is the tool for that kind of validation, in my opinion.
If OP were able to use SimpleDateFormat as well as regex, then this would suffice:
public static final boolean isDateValid(String date) {
if (!date.matches("\d{4}\\\d{2}\\\d{2}"))
return false;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
try {
sdf.parse(date);
return true;
} catch (ParseExceptione) {
return false;
}
}
NB. Usual caveats about SimpleDateFormat not being thread safe etc.
Here is my take on it:
((19|20)[0-9]{2})/((0?[1-9])|1[012])/((0?[1-9])|(1[0-9])|(3[01]))
i think this helpful for u...
var regdate = /^(19[0-9][0-9]|20[0-9][0-9])\/(0[1-9]|1[012])\/(0[1-9]|[12][0-9]|3[01])$/;
A simple regex plus a SimpleDateFormat doesn't filter a String date like "2014\26\26", then it would not suffice.
So maybe the best approach is a fully strict regex pattern.
If you turn over your regex (Java) expression from the mkyong website you should be done. As you were already suggested:
String pattern = "((?:19|20)\\d\\d)/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])";
And for extra assurance you can add a SimpleDateFormat. Here is my extra verbose approach:
if(stringDate.length()==10 && stringDate.matches("((?:19|20)\\d\\d)/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])")){
Date d=null;
String checkDate=null;
DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
try {
//Also parses the String as a Date with the format "yyyy/MM/dd"
//to be sure that the passed string is correct
d=df.parse(stringDate);
} catch (ParseException e) {
e.printStackTrace();
}
if (d != null) {
//Transforms the Date into a String with the format "yyyy/MM/dd"
checkDate=df.format(d);
System.out.println(checkDate);
}
}
Here is an another simple approach, write a small method that converts the string input to date and convert back the date to string. Then compare both string are equal. If equal then date is correct else its incorrect. All validations are taken care by this approach.
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDate {
public static boolean isValidDateFormat(String value, String format) {
Date date = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
date = sdf.parse(value);
if (!value.equals(sdf.format(date))) {
date = null;
}
} catch (Exception ex) {
return false;
}
return date != null;
}
public static void main(String[] args) {
String format = "yyyy/MM/dd";
System.out.println("2017/02/31 isValidDateFormat: " + isValidDateFormat("2017/02/31", format));
System.out.println("2017/03/31 isValidDateFormat: " + isValidDateFormat("2017/03/31", format));
System.out.println("2017/04/31 isValidDateFormat: " + isValidDateFormat("2017/04/31", format));
System.out.println("2017/13/31 isValidDateFormat: " + isValidDateFormat("2017/04/31", format));
System.out.println("2017/01/35 isValidDateFormat: " + isValidDateFormat("2017/01/35", format));
System.out.println("017/01/30 isValidDateFormat: " + isValidDateFormat("017/01/30", format));
// output :
//2017/02/31 isValidDateFormat: false
// 2017/03/31 isValidDateFormat: true
// 2017/04/31 isValidDateFormat: false
// 2017/13/31 isValidDateFormat: false
// 2017/01/35 isValidDateFormat: false
// 017/01/30 isValidDateFormat: false
}
}
Just for fun, I wanted to see how the regex Jon Skeet's very valid comment mentioned (that a regex handling leap years correctly would be horrendous) would look like. And look - he was right ;)
^
(?:(?:19|2[01])\d\d\/(?:1[02]|0[13578])\/(?:[0-2]\d|3[01])) # 31 day months
|
(?:(?:19|2[01])\d\d\/(?:(?:11|0[469])\/(?:[0-2]\d|30))) # 30 day months
|
(?:(?:19|2[01])(?:[02468][1235679]|[13579][01345789])|1900|2100)\/02\/(?:[01]\d|2[0-8]) # Non leap year
|
(?:(?:(?:19|21)(?!00)|20)(?:[02468][048]|[13579][26]))\/02\/(?:[01]\d|2[0-9]) # Leap year
$
See it here at regex101.
It tests using four alternations:
31 day months
30 day months
February non-leap years
February leap years
Note that leap years are the years that are a multiple of four. An exception to that rule are multiples of 100 except if it's a multiple of 400. (Phew... This is what makes it horrendous.)
It's regexp date format(dd.MM.yyyy). You can adapt this one for you.
(((0[1-9]{1}|1[0-9]|2[0-9]).(0[1-9]|1[0-2]))|(30.(04|06|09|11))|((30|31).(01|03|05|07|08|10|12))).[0-9]{4}

Is there a smart date API for Java which recognizes the pattern itself?

I have the following input cases, but I don't want to examine the format myself and change the pattern everytime. I currently make use of DateTimeFormat.forPattern("dd.MM.yyyy");, this fails as soon as a), c) or d) are applied.
a) 1.1.12 => 01.01.0012 x
b) 01.01.2012 => 01.01.2012 ✓
c) 01.01.12 => 01.01.0012 x
d) 1.1.2012 => 01.00.2012 x
I can assure that the format is D.M.Y, but not if it's long or short or mixed up. Is there already a function in Joda which helps to choose the pattern given on a "base pattern"?
Thank you!
I use a search path of patterns. Some dates are ambiguous, so you need to know how you want to handle them e.g. is 1.2.3 the first of Feb 3 AD/1903/2003 or second of January, 3 AD or 1 AD/1901/2001 Feb the third.
A simple pattern I use (except I cache the SimpleDateFormat objects ;)
public static Date parseDate(String dateStr) throws IllegalArgumentException {
// optionally change the separator
dateStr = dateStr.replaceAll("\\D+", "/");
for (String fmt : "dd/MM/yy,yyyy/MM/dd,dd/MM/yyyy".split(",")) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(fmt);
sdf.setLenient(false);
return sdf.parse(dateStr);
} catch (ParseException ignored) {
}
}
throw new IllegalArgumentException("Unable to parse date '" + dateStr + "'");
}
public static void main(String... args) {
String dates = "1.2.12\n" +
"01.02.2012\n" +
"2012.02.01\n" +
"01-01-12\n" +
"1.1.2012";
for (String dateStr : dates.split("\n")) {
Object result;
try {
result = parseDate(dateStr);
} catch (IllegalArgumentException e) {
result = e;
}
System.out.println(dateStr + " => " + result);
}
}
prints
1.2.12 => Wed Feb 01 00:00:00 GMT 2012
01.02.2012 => Wed Feb 01 00:00:00 GMT 2012
2012.02.01 => Wed Feb 01 00:00:00 GMT 2012
01-01-12 => Sun Jan 01 00:00:00 GMT 2012
1.1.2012 => Sun Jan 01 00:00:00 GMT 2012
I think I got a better solution using Joda-Time. I got it down to two parsers that you have to try:
DateTimeFormatter f = new DateTimeFormatterBuilder()
.appendDayOfMonth(1)
.appendLiteral('.')
.appendMonthOfYear(1)
.appendLiteral('.')
.appendTwoDigitYear(1970) // Notice this!!
.toFormatter();
System.out.println(f.parseDateTime("01.1.12"));
System.out.println(f.parseDateTime("01.01.12"));
f = new DateTimeFormatterBuilder()
.appendDayOfMonth(1)
.appendLiteral('.')
.appendMonthOfYear(1)
.appendLiteral('.')
.appendYear(4,4)
.toFormatter();
System.out.println(f.parseDateTime("01.01.2012"));
System.out.println(f.parseDateTime("1.1.2012"));
System.out.println(f.parseDateTime("01.1.2012"));
IMHO you are approaching the problem from the wrong perspective, if you have an input which consist on a list of Strings that represent dates, but in different formats, then you have a text validation problem, not a date formatting problem.
Again, this is only my opinion, but I think you'll find it easier if what you do is create a text parser that changes the text for all this inputs when necessary to a more suitable text format for your date parser, this way you can use more powerful utilities like regex...
If you don't want to use any reference to java.util.Data, you'll have to do it like this:
public DateTime getDateTime(String text) {
DateTimeFormatterBuilder fb = new DateTimeFormatterBuilder();
fb.appendDayOfMonth(2);
fb.appendLiteral('.');
fb.appendMonthOfYear(2);
fb.appendLiteral('.');
fb.appendYear(2, 4);
DateTimeFormatter formatter = fb.toFormatter();
DateTime dt = formatter.parseDateTime(text);
if (dt.getYear() < 2000) {
dt = dt.plusYear(2000);
}
return dt;
}
But I would recommend this solution:
public DateTime getDateTime(String text) {
SimpleDateFormat f = new SimpleDateFormat("dd.MM.yy");
java.util.Date jud = f.parse(text);
if (jud != null) {
return new DateTime(jud);
} else {
return null;
}
}
Both should do the trick and work for your examples.
Note: As Alberto said, you should validate your input first using regular expressions, because SimpleDateFormat doesn't have a very tight matching with this usage and because it's always a good idea to validate input.

Parsing dates of the format "January 10th, 2010" in Java? (with ordinal indicators, st|nd|rd|th)

I need to parse the dates of the format "January 10th, 2010" in Java. How can I do this?
How to handle the ordinal indicators, the st, nd, rd, or th trailing the day number?
This works:
String s = "January 10th, 2010";
DateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy");
System.out.println("" + dateFormat.parse(s.replaceAll("(?:st|nd|rd|th),", "")));
but you need to make sure you are using the right Locale to properly parse the month name.
I know you can include general texts inside the SimpleDateFormat pattern. However in this case the text is dependent on the info and is actually not relevant to the parsing process.
This is actually the simplest solution I can think of. But I would love to be shown wrong.
You can avoid the pitfalls exposed in one of the comments by doing something similar to this:
String s = "January 10th, 2010";
DateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy");
System.out.println("" + dateFormat.parse(s.replaceAll("(?<= \\d+)(?:st|nd|rd|th),(?= \\d+$)", "")));
This will allow you to not match Jath,uary 10 2010 for example.
I should like to contribute the modern answer. Rather than the SimpleDateFormat class used in the two top-voted answer today you should use java.time, the modern Java date and time API. It offers a couple of nice solutions.
Easy solution
We first define a formatter for parsing:
private static final DateTimeFormatter PARSING_FORMATTER = DateTimeFormatter.ofPattern(
"MMMM d['st']['nd']['rd']['th'], uuuu", Locale.ENGLISH);
Then we use it like this:
String dateString = "January 10th, 2010";
LocalDate date = LocalDate.parse(dateString, PARSING_FORMATTER);
System.out.println("Parsed date: " + date);
Output is:
Parsed date: 2010-01-10
The square brackets [] in the format pattern string enclose optional parts, and the single quotes enclose literal text. So d['st']['nd']['rd']['th'] means that there may be st, nd, rd and/or th after the day of month.
More solid solution
A couple of limitations with the approach above are
It accepts any ordinal indicator, for example 10st and even 10stndrdth.
While the formatter works for parsing, you cannot use it for formatting (it would give January 10stndrdth, 2010).
If you want better validation of the ordinal indicator or you want the possibility of formatting the date back into a string, you may build your formatter in this way:
private static final DateTimeFormatter FORMATTING_AND_PARSING_FORMATTER;
static {
Map<Long, String> ordinalNumbers = new HashMap<>(42);
ordinalNumbers.put(1L, "1st");
ordinalNumbers.put(2L, "2nd");
ordinalNumbers.put(3L, "3rd");
ordinalNumbers.put(21L, "21st");
ordinalNumbers.put(22L, "22nd");
ordinalNumbers.put(23L, "23rd");
ordinalNumbers.put(31L, "31st");
for (long d = 1; d <= 31; d++) {
ordinalNumbers.putIfAbsent(d, "" + d + "th");
}
FORMATTING_AND_PARSING_FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("MMMM ")
.appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
.appendPattern(", uuuu")
.toFormatter(Locale.ENGLISH);
}
This will parse the date string the same as the one above. Let’s also try it for formatting:
System.out.println("Formatted back using the same formatter: "
+ date.format(FORMATTING_AND_PARSING_FORMATTER));
Formatted back using the same formatter: January 10th, 2010
Links
Oracle tutorial: Date Time explaining how to use java.time.
My answer to a question about formatting ordinal indicators from which I took the more solid formatter.
You can set nd etc as literals in a SimpleDateFormat. You can define the four needed format and try them. Starting with th first, because I guess this will occur more often. If it fails with ParseException, try the next one. If all fail, throw the ParseException. The code here is just a concept. In real-life you may would not generate the formats new everytime and may think about thread-safety.
public static Date hoolaHoop(final String dateText) throws ParseException
{
ParseException pe=null;
String[] sss={"th","nd","rd","st"};
for (String special:sss)
{
SimpleDateFormat sdf=new SimpleDateFormat("MMMM d'"+special+",' yyyy");
try{
return sdf.parse(dateText);
}
catch (ParseException e)
{
// remember for throwing later
pe=e;
}
}
throw pe;
}
public static void main (String[] args) throws java.lang.Exception
{
String[] dateText={"January 10th, 2010","January 1st, 2010","January 2nd, 2010",""};
for (String dt:dateText) {System.out.println(hoolaHoop(dt))};
}
Output:
Sun Jan 10 00:00:00 GMT 2010
Fri Jan 01 00:00:00 GMT 2010
Sat Jan 02 00:00:00 GMT 2010
Exception in thread "main" java.text.ParseException: Unparseable date: ""
"th","nd","rd","st" is of course only suitable for Locales with english language. Keep that in mind. In france, "re","nd" etc I guess.
This is another easy way ,but need to include apache commons jar.
import org.apache.commons.lang.time.*;
String s = "January 10th, 2010";
String[] freakyFormat = {"MMM dd'st,' yyyy","MMM dd'nd,' yyyy","MMM dd'th,' yyyy","MMM dd'rd,' yyyy"};
DateUtils du = new DateUtils();
System.out.println("" + du.parseDate(s,freakyFormat));

forcing 4 digits year in java's simpledateformat

I want to validate and parse dates using a simpleDateFormat with the format "yyyymmdd"
This also allows 100624, which is parsed to the year 10 (54 years after Julius Ceasar died). The dates will also be something like 1970, so I don't want to settle with SimpleDateFornat("yymmdd").
I'm wondering is there a way to force a four digit year format using the SimpleDateFormat? I'm close to do a regexp test upfront but maybe there is a smart way to use the (Simple)DateFormat()?
As requested the code, things are getting more complicate and my research was half. The Format used was yyyy-MM-dd to start with (it came from a variable, which had a wrong javadoc). However as indicated in an answer below yyyyMMdd does force a four year digit. So my question is changed to How to force a four digit year for the "yyyy-MM-dd" format. And why does "yyyyMMdd" behave different?
public void testMaturity() {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
System.out.println(" " + sdf.format(sdf.parse("40-12-14")));
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
sdf.setLenient(false);
System.out.println(" " + sdf2.format(sdf2.parse("401214")));
fail();
} catch (ParseException pe) {
assertTrue(true);
}
Which prints 0040-12-14
Simply use yyyyMMdd (note: upper case M is used to indicate month, otherwise you're parsing minutes!) and then check if the year is greater some cutoff date (for example, when parsing birth dates, greater 1800 is a safe bet, when parsing dates for upcomming dates greater than or equal the current year would be good).
Hmm. I suspect you should be using "MM" instead of "mm" to start with... but "100624" doesn't parse anyway when I try it - even in lenient mode:
import java.util.*;
import java.text.*;
public class Test
{
public static void main(String[] args) throws Exception
{
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
format.setLenient(true);
tryParse(format, "100624");
format.setLenient(false);
tryParse(format, "100624");
}
static void tryParse(DateFormat format, String text)
{
try
{
Date date = format.parse(text);
System.out.println("Parsed " + text + " to " + date);
}
catch (ParseException pe)
{
System.out.println("Failed to parse " + text);
}
}
}
(And even using "mm" instead of "MM" it still fails to parse.)
Prints:
Failed to parse 100624
Failed to parse 100624
Perhaps you could show the code which is managing to parse this?
There is no easy way for this. If you're saying that dates can be like 1970 the main question would be what 700624 means - 1970 or 2070? You should either implement some cutoff date like Joachim proposed or move entirely to 4 digits year.
Well it is quite straight and forward. Follow these simple steps:
Step 1:
try {
String dates = "40-12-14";
String patterns = "yy-MM-dd";
SimpleDateFormat format3 = new SimpleDateFormat(patterns);``
java.util.Date dates1 = format3.parse(dates);
SimpleDateFormat sdfDates = new SimpleDateFormat("dd/MM/yyyy");
String strDate1 = sdfDate.format(dates1);
System.out.println("Date1: " + strDate1);
}
catch(ParseException e){
e.printStackTrace();
}
This will output:
Date1: 14/12/1940

Categories