convert string to date type - java

I want to convert string to date format, but the following way didn't work.
It yields null for birth.
Date birth;
try {
DateFormat formatter ;
formatter = new SimpleDateFormat("dd-MMM-yyyy");
birth = (Date)formatter.parse(birthDate); // birtDate is a string
} catch (ParseException e) {
System.out.println("Exception :"+e);
}

Your answer is right on the money. I put it in a full program and tested it.
It now prints out
Default date format Fri Mar 30 00:00:00 CDT 2012
Our SimpleDateFormat 30-Mar-2012
Our SimpleDateFormat with all uppercase 30-MAR-2012
Here are some tips:
Make sure that you are including the correct imports. Depending on
what is in your classpath, you may have accidentally imported
java.sql.Date or some other rogue import.
Try printing the contents
of birthDate before entering the try block and verify that it really
contains a string of format dd-MMM-yyyy
-
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class BirthDate {
public static void main(String[] args) {
Date birth = null;
String birthDate = "30-MAR-2012";
DateFormat formatter = null;
try {
formatter = new SimpleDateFormat("dd-MMM-yyyy");
birth = (Date) formatter.parse(birthDate); // birtDate is a string
}
catch (ParseException e) {
System.out.println("Exception :" + e);
}
if (birth == null) {
System.out.println("Birth object is still null.");
} else {
System.out.println("Default date format " + birth);
System.out.println("Our SimpleDateFormat " + formatter.format(birth));
System.out.println("Our SimpleDateFormat with all uppercase " + formatter.format(birth).toUpperCase());
}
}
}

Your code works fine. If you care to use Joda Time you can use this. You can go through the documentation to unleash the complete functionality in case you plan to use the time for DB testing and stuff.
import org.joda.time.DateTime;
DateTime dt = new DateTime("YYYY-MM-DD");//new DateTime("2012-03-30")
System.out.println(dt);

Related

check in specific date format if not add 0 at end java

I am trying to check the date is in required format and if its not in required format(yyyy-MM-dd'T'HH:mm:sss) i need to add zero at the end to return a date in required format
For example if i get String inputDate= 2018-08-04T09:07:12.42 and i need to convert inputdate to 2018-08-04T09:07:12.420.
For convertStringToDate i am passing inputDate = 2018-08-04T09:07:12.42 and dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS". I tried the below code, but im not sure where i am missing . Pls suggest
public Date convertStringToDate(String inputDate, String dateFormat) {
String formattedInput = inputDate;
try {
// add milliseconds if missing from date
if (validateDateFormat(inputDate, "yyyy-MM-dd'T'HH:mm:ss") && !validateDateFormat(inputDate, dateFormat)) {
formattedInput = inputDate + "0";
}
Log.logInfo(this, "formattedInput: " + formattedInput);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
return simpleDateFormat.parse(formattedInput);
} catch (Exception e) {
Log.logError(this, "error in inputDate: " + formattedInput + " - convertStringToDate: " + e.getMessage());
return null;
}
}
public boolean validateDateFormat(String strDate, String dateFormat) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
simpleDateFormat.setLenient(false);
Date javaDate = null;
try {
javaDate = simpleDateFormat.parse(strDate);
Log.logInfo(this, "formattedInput Date: " + javaDate);
return true;
}
/* Date format is invalid */
catch (Exception e) {
Log.logInfo(this, strDate + " is Invalid Date format");
return false;
}
/* Return true if date format is valid */
}
tl;dr
Parse your date-time strings using LocalDateTime#parse(CharSequence text) and use DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH) to format the obtained LocalDateTime.
Details
Irrespective of whether you have one/two/three digits in the fraction-of-second part of your date-time strings, they are compliant with ISO 8601 standards and therefore, you do not need a DateTimeFormatter to parse your date-time strings into a LocalDateTime by using LocalDateTime#parse(CharSequence text).
However, to keep three digits always in the string resulting from formatting the LocalDateTime, you need to use .SSS with the formatter i.e. DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).
Demo:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream.of(
"2018-08-04T09:07:12.421",
"2018-08-04T09:07:12.42",
"2018-08-04T09:07:12.4"
)
.map(LocalDateTime::parse)
.map(dt -> dt.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH)))
.forEach(System.out::println);
}
}
Output:
2018-08-04T09:07:12.421
2018-08-04T09:07:12.420
2018-08-04T09:07:12.400
Learn more about the modern Date-Time API from Trail: Date Time.
Note: In March 2014, java.time API supplanted the error-prone legacy date-time API. Since then, it has been strongly recommended to use this modern date-time API.

why is calendar.setLenient(false) not generating exception

I was trying to block incompatible date in input. So I intentionally gave wrong date as string. I set calendar.setLenient to false hoping that it would not allow date to parse. But It pass through it. Below is my code:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Test {
public static void main(String[] args) throws Exception{
try {
String from ="2018-15-18";
String to = "2018-15-18";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar calender1 = Calendar.getInstance();
Calendar calender2 = Calendar.getInstance();
calender1.setLenient(false);
calender2.setLenient(false);
calender1.setTime(sdf.parse(from));
calender2.setTime(sdf.parse(to));
Date dtFrom = calender1.getTime();
Date dtTo = calender2.getTime();
System.out.println(sdf.format(dtFrom));
if((from!=null && !from.isEmpty())&&(to!=null && !to.isEmpty())&&(dtFrom!=null && dtTo!=null))
System.out.println("ok");
else
System.out.println("not ok");
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
As I have given wrong date i.e. month 15 does not exist. So I was expecting exception on line calender1.setTime(sdf.parse(from)); but it pass through and printing date value as : 2019-03-18. I did not wanted that. Why is it so? How can I make sure wrong date input should not be entertained further in my code once it is not able to parse.

handling yyyy/mm/dd and yyyy-MMM-dd cases in java through regex or in simple way [duplicate]

I am trying to parse some dates that are coming out of a document. It would appear users have entered these dates in a similar but not exact format.
here are the formats:
9/09
9/2009
09/2009
9/1/2009
9-1-2009
What is the best way to go about trying to parse all of these? These seem to be the most common, but I guess what is hanging me up is that if i have a pattern of "M/yyyy" wont that always catch before "MM/yyyy" Do I have to set up my try/catch blocks nested in a least restrictive to most restrictive way? it seems like it sure is going to take a lot of code duplication to get this right.
You'll need to use a different SimpleDateFormat object for each different pattern. That said, you don't need that many different ones, thanks to this:
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.
So, you'll need these formats:
"M/y" (that covers 9/09, 9/2009, and 09/2009)
"M/d/y" (that covers 9/1/2009)
"M-d-y" (that covers 9-1-2009)
So, my advice would be to write a method that works something like this (untested):
// ...
List<String> formatStrings = Arrays.asList("M/y", "M/d/y", "M-d-y");
// ...
Date tryParse(String dateString)
{
for (String formatString : formatStrings)
{
try
{
return new SimpleDateFormat(formatString).parse(dateString);
}
catch (ParseException e) {}
}
return null;
}
What about just defining multiple patterns? They might come from a config file containing known patterns, hard coded it reads like:
List<SimpleDateFormat> knownPatterns = new ArrayList<SimpleDateFormat>();
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm.ss'Z'"));
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"));
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss"));
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"));
for (SimpleDateFormat pattern : knownPatterns) {
try {
// Take a try
return new Date(pattern.parse(candidate).getTime());
} catch (ParseException pe) {
// Loop on
}
}
System.err.println("No known Date format found: " + candidate);
return null;
Matt's approach above is fine, but please be aware that you will run into problems if you use it to differentiate between dates of the format y/M/d and d/M/y. For instance, a formatter initialised with y/M/d will accept a date like 01/01/2009 and give you back a date which is clearly not what you wanted. I fixed the issue as follows, but I have limited time and I'm not happy with the solution for 2 main reasons:
It violates one of Josh Bloch's quidelines, specifically 'don't use exceptions to handle program flow'.
I can see the getDateFormat() method becoming a bit of a nightmare if you needed it to handle lots of other date formats.
If I had to make something that could handle lots and lots of different date formats and needed to be highly performant, then I think I would use the approach of creating an enum which linked each different date regex to its format. Then use MyEnum.values() to loop through the enum and test with if(myEnum.getPattern().matches(date)) rather than catching a dateformatexception.
Anway, that being said, the following can handle dates of the formats 'y/M/d' 'y-M-d' 'y M d' 'd/M/y' 'd-M-y' 'd M y' and all other variations of those which include time formats as well:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
private static final String[] timeFormats = {"HH:mm:ss","HH:mm"};
private static final String[] dateSeparators = {"/","-"," "};
private static final String DMY_FORMAT = "dd{sep}MM{sep}yyyy";
private static final String YMD_FORMAT = "yyyy{sep}MM{sep}dd";
private static final String ymd_template = "\\d{4}{sep}\\d{2}{sep}\\d{2}.*";
private static final String dmy_template = "\\d{2}{sep}\\d{2}{sep}\\d{4}.*";
public static Date stringToDate(String input){
Date date = null;
String dateFormat = getDateFormat(input);
if(dateFormat == null){
throw new IllegalArgumentException("Date is not in an accepted format " + input);
}
for(String sep : dateSeparators){
String actualDateFormat = patternForSeparator(dateFormat, sep);
//try first with the time
for(String time : timeFormats){
date = tryParse(input,actualDateFormat + " " + time);
if(date != null){
return date;
}
}
//didn't work, try without the time formats
date = tryParse(input,actualDateFormat);
if(date != null){
return date;
}
}
return date;
}
private static String getDateFormat(String date){
for(String sep : dateSeparators){
String ymdPattern = patternForSeparator(ymd_template, sep);
String dmyPattern = patternForSeparator(dmy_template, sep);
if(date.matches(ymdPattern)){
return YMD_FORMAT;
}
if(date.matches(dmyPattern)){
return DMY_FORMAT;
}
}
return null;
}
private static String patternForSeparator(String template, String sep){
return template.replace("{sep}", sep);
}
private static Date tryParse(String input, String pattern){
try{
return new SimpleDateFormat(pattern).parse(input);
}
catch (ParseException e) {}
return null;
}
}
If working in Java 1.8 you can leverage the DateTimeFormatterBuilder
public static boolean isTimeStampValid(String inputString)
{
DateTimeFormatterBuilder dateTimeFormatterBuilder = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ofPattern("" + "[yyyy-MM-dd'T'HH:mm:ss.SSSZ]" + "[yyyy-MM-dd]"));
DateTimeFormatter dateTimeFormatter = dateTimeFormatterBuilder.toFormatter();
try {
dateTimeFormatter.parse(inputString);
return true;
} catch (DateTimeParseException e) {
return false;
}
}
See post: Java 8 Date equivalent to Joda's DateTimeFormatterBuilder with multiple parser formats?
In Apache commons lang, DateUtils class we have a method called parseDate. We can use this for parsing the date.
Also another library Joda-time also have the method to parse the date.
Here is the complete example (with main method) which can be added as a utility class in your project. All the format mentioned in SimpleDateFormate API is supported in the below method.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang.time.DateUtils;
public class DateUtility {
public static Date parseDate(String inputDate) {
Date outputDate = null;
String[] possibleDateFormats =
{
"yyyy.MM.dd G 'at' HH:mm:ss z",
"EEE, MMM d, ''yy",
"h:mm a",
"hh 'o''clock' a, zzzz",
"K:mm a, z",
"yyyyy.MMMMM.dd GGG hh:mm aaa",
"EEE, d MMM yyyy HH:mm:ss Z",
"yyMMddHHmmssZ",
"yyyy-MM-dd'T'HH:mm:ss.SSSZ",
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
"YYYY-'W'ww-u",
"EEE, dd MMM yyyy HH:mm:ss z",
"EEE, dd MMM yyyy HH:mm zzzz",
"yyyy-MM-dd'T'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ss.SSSzzzz",
"yyyy-MM-dd'T'HH:mm:sszzzz",
"yyyy-MM-dd'T'HH:mm:ss z",
"yyyy-MM-dd'T'HH:mm:ssz",
"yyyy-MM-dd'T'HH:mm:ss",
"yyyy-MM-dd'T'HHmmss.SSSz",
"yyyy-MM-dd",
"yyyyMMdd",
"dd/MM/yy",
"dd/MM/yyyy"
};
try {
outputDate = DateUtils.parseDate(inputDate, possibleDateFormats);
System.out.println("inputDate ==> " + inputDate + ", outputDate ==> " + outputDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return outputDate;
}
public static String formatDate(Date date, String requiredDateFormat) {
SimpleDateFormat df = new SimpleDateFormat(requiredDateFormat);
String outputDateFormatted = df.format(date);
return outputDateFormatted;
}
public static void main(String[] args) {
DateUtility.parseDate("20181118");
DateUtility.parseDate("2018-11-18");
DateUtility.parseDate("18/11/18");
DateUtility.parseDate("18/11/2018");
DateUtility.parseDate("2018.11.18 AD at 12:08:56 PDT");
System.out.println("");
DateUtility.parseDate("Wed, Nov 18, '18");
DateUtility.parseDate("12:08 PM");
DateUtility.parseDate("12 o'clock PM, Pacific Daylight Time");
DateUtility.parseDate("0:08 PM, PDT");
DateUtility.parseDate("02018.Nov.18 AD 12:08 PM");
System.out.println("");
DateUtility.parseDate("Wed, 18 Nov 2018 12:08:56 -0700");
DateUtility.parseDate("181118120856-0700");
DateUtility.parseDate("2018-11-18T12:08:56.235-0700");
DateUtility.parseDate("2018-11-18T12:08:56.235-07:00");
DateUtility.parseDate("2018-W27-3");
}
}
Best and Simple Java 8 answer (from https://stackoverflow.com/a/59546290/2131040)
final DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
dtfb.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0);
This solution checks all the possible formats before throwing an exception. This solution is more convenient if you are trying to test for multiple date formats.
Date extractTimestampInput(String strDate){
final List<String> dateFormats = Arrays.asList("yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd");
for(String format: dateFormats){
SimpleDateFormat sdf = new SimpleDateFormat(format);
try{
return sdf.parse(strDate);
} catch (ParseException e) {
//intentionally empty
}
}
throw new IllegalArgumentException("Invalid input for date. Given '"+strDate+"', expecting format yyyy-MM-dd HH:mm:ss.SSS or yyyy-MM-dd.");
}
For the modern answer I am ignoring the requirement to use SimpleDateFormat. While using this class for parsing was a good idea in 2010 when this question was asked, it is now long outdated. The replacement, DateTimeFormatter, came out in 2014. The idea in the following is pretty much the same as in the accepted answer.
private static DateTimeFormatter[] parseFormatters = Stream.of("M/yy", "M/y", "M/d/y", "M-d-y")
.map(DateTimeFormatter::ofPattern)
.toArray(DateTimeFormatter[]::new);
public static YearMonth parseYearMonth(String input) {
for (DateTimeFormatter formatter : parseFormatters) {
try {
return YearMonth.parse(input, formatter);
} catch (DateTimeParseException dtpe) {
// ignore, try next format
}
}
throw new IllegalArgumentException("Could not parse " + input);
}
This parses each of the input strings from the question into a year-month of 2009-09. It’s important to try the two-digit year first since "M/y" could also parse 9/09, but into 0009-09 instead.
A limitation of the above code is it ignores the day-of-month from the strings that have one, like 9/1/2009. Maybe it’s OK as long as most formats have only month and year. To pick it up, we’d have to try LocalDate.parse() rather then YearMonth.parse() for the formats that include d in the pattern string. Surely it can be done.
I'm solved this problem more simple way using regex
fun parseTime(time: String?): Long {
val longRegex = "\\d{4}+-\\d{2}+-\\d{2}+\\w\\d{2}:\\d{2}:\\d{2}.\\d{3}[Z]\$"
val shortRegex = "\\d{4}+-\\d{2}+-\\d{2}+\\w\\d{2}:\\d{2}:\\d{2}Z\$"
val longDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sssXXX")
val shortDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
return when {
Pattern.matches(longRegex, time) -> longDateFormat.parse(time).time
Pattern.matches(shortRegex, time) -> shortDateFormat.parse(time).time
else -> throw InvalidParamsException(INVALID_TIME_MESSAGE, null)
}
}
Implemented the same in scala, Please help urself with converting to Java, the core logic and functions used stays the same.
import java.text.SimpleDateFormat
import org.apache.commons.lang.time.DateUtils
object MultiDataFormat {
def main(args: Array[String]) {
val dates =Array("2015-10-31","26/12/2015","19-10-2016")
val possibleDateFormats:Array[String] = Array("yyyy-MM-dd","dd/MM/yyyy","dd-MM-yyyy")
val sdf = new SimpleDateFormat("yyyy-MM-dd") //change it as per the requirement
for (date<-dates) {
val outputDate = DateUtils.parseDateStrictly(date, possibleDateFormats)
System.out.println("inputDate ==> " + date + ", outputDate ==> " +outputDate + " " + sdf.format(outputDate) )
}
}
}
Using DateTimeFormatter it can be achieved as below:
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.TimeZone;
public class DateTimeFormatTest {
public static void main(String[] args) {
String pattern = "[yyyy-MM-dd[['T'][ ]HH:mm:ss[.SSSSSSSz][.SSS[XXX][X]]]]";
String timeSample = "2018-05-04T13:49:01.7047141Z";
SimpleDateFormat simpleDateFormatter = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
TemporalAccessor accessor = formatter.parse(timeSample);
ZonedDateTime zTime = LocalDateTime.from(accessor).atZone(ZoneOffset.UTC);
Date date=new Date(zTime.toEpochSecond()*1000);
simpleDateFormatter.setTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC));
System.out.println(simpleDateFormatter.format(date));
}
}
Pay attention at String pattern, this is the combination of multiple patterns. In open [ and close ] square brackets you can mention any kind of patterns.
I was having multiple date formats into json, and was extracting csv with universal format. I looked multiple places, tried different ways, but at the end I'm able to convert with the following simple code.
private String getDate(String anyDateFormattedString) {
#SuppressWarnings("deprecation")
Date date = new Date(anyDateFormattedString);
SimpleDateFormat dateFormat = new SimpleDateFormat(yourDesiredDateFormat);
String convertedDate = dateFormat.format(date);
return convertedDate;
}

java string to date conversion without seconds

I have to convert string to date such that it should throw error when string is having seconds. For example if I am giving input string as "2015-08-12 12:24:08" I should get an error because I am giving seconds in the string(i.e., 08 here), whereas if I give input as "2015-08-12 12:24" I shouldn't get any error. How can I achieve that?
I have tried below code
String oldstring2 = "2015-08-12 12:24:08";
Date date2 = null;
try {
date2 = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(oldstring2);
System.out.println(date2);
System.out.println("success");
} catch (ParseException e) {
e.printStackTrace();
System.out.println("error");
}
With Java 8 you can use the DateTimeFormatter class. Because this performs strict parsing instead of trying to match from the beginning like SimpleDateFormat does:
String string = "2015-08-12 12:24";
TemporalAccessor ta = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").parse(string);
LocalDate date = LocalDate.from(ta);
the parse method will throw an Exception when you change string to include seconds:
java.time.format.DateTimeParseException: Text '2015-08-12 12:24:12' could not be parsed, unparsed text found at index 16
String oldstring2 = "2015-08-12 12:24";
String[] str = oldstring2.split(" ");
if(str[1]!=null){
String[] str2 = str[1].split(":");
if(str2.length == 2)
System.out.println("success");
else
System.out.println("error");
}
If your input date is exactly like you specified every time, the above code would work.
Please try this:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateConversion {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:MM:SS");
Date d = sdf.parse("2015-08-12 12:24:08");
System.out.println(d);
}
}
The Regular expression can achieve the goal:
String oldstring2 = "2015-08-12 12:24";
Pattern p = Pattern.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?"
+ "((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))"
+ "|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|"
+ "(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|"
+ "([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?"
+ "((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|"
+ "([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))"
+ "(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])()))?$");
if (p.matcher(oldstring2).matches()) {
// do something
} else {
// return the error
}

Java: Check the date format of current string is according to required format or not [duplicate]

This question already has answers here:
How to sanity check a date in Java
(24 answers)
Closed 4 years ago.
I wanted to know that is there any method available in Java that can do this.Otherwise I may go for Regex solution.
I have input string from user that can be any characters. And I want to check that the input string is according to my required date format or not.
As I have input 20130925 and my required format is dd/MM/yyyy so, for this case I should get false.
I don't want to convert this date I just want to check whether input string is according to required date format or not.
I have tried following
Date date = null;
try {
date = new SimpleDateFormat("dd/MM/yyyy").parse("20130925");
} catch (Exception ex) {
// do something for invalid dateformat
}
but my catch (Exception ex) block is unable to catch any exceptions generated by SimpleDateFormat.Parse();
Disclaimer
Parsing a string back to date/time value in an unknown format is inherently impossible (let's face it, what does 3/3/3 actually mean?!), all we can do is "best effort"
Important
This solution doesn't throw an Exception, it returns a boolean, this is by design. Any Exceptions are used purely as a guard mechanism.
2018
Since it's now 2018 and Java 8+ has the date/time API (and the rest have the ThreeTen backport). The solution remains basically the same, but becomes slightly more complicated, as we need to perform checks for:
date and time
date only
time only
This makes it look something like...
public static boolean isValidFormat(String format, String value, Locale locale) {
LocalDateTime ldt = null;
DateTimeFormatter fomatter = DateTimeFormatter.ofPattern(format, locale);
try {
ldt = LocalDateTime.parse(value, fomatter);
String result = ldt.format(fomatter);
return result.equals(value);
} catch (DateTimeParseException e) {
try {
LocalDate ld = LocalDate.parse(value, fomatter);
String result = ld.format(fomatter);
return result.equals(value);
} catch (DateTimeParseException exp) {
try {
LocalTime lt = LocalTime.parse(value, fomatter);
String result = lt.format(fomatter);
return result.equals(value);
} catch (DateTimeParseException e2) {
// Debugging purposes
//e2.printStackTrace();
}
}
}
return false;
}
This makes the following...
System.out.println("isValid - dd/MM/yyyy with 20130925 = " + isValidFormat("dd/MM/yyyy", "20130925", Locale.ENGLISH));
System.out.println("isValid - dd/MM/yyyy with 25/09/2013 = " + isValidFormat("dd/MM/yyyy", "25/09/2013", Locale.ENGLISH));
System.out.println("isValid - dd/MM/yyyy with 25/09/2013 12:13:50 = " + isValidFormat("dd/MM/yyyy", "25/09/2013 12:13:50", Locale.ENGLISH));
System.out.println("isValid - yyyy-MM-dd with 2017-18--15 = " + isValidFormat("yyyy-MM-dd", "2017-18--15", Locale.ENGLISH));
output...
isValid - dd/MM/yyyy with 20130925 = false
isValid - dd/MM/yyyy with 25/09/2013 = true
isValid - dd/MM/yyyy with 25/09/2013 12:13:50 = false
isValid - yyyy-MM-dd with 2017-18--15 = false
Original Answer
Simple try and parse the String to the required Date using something like SimpleDateFormat
Date date = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
date = sdf.parse(value);
if (!value.equals(sdf.format(date))) {
date = null;
}
} catch (ParseException ex) {
ex.printStackTrace();
}
if (date == null) {
// Invalid date format
} else {
// Valid date format
}
You could then simply write a simple method that performed this action and returned true when ever Date was not null...
As a suggestion...
Updated with running example
I'm not sure what you are doing, but, the following example...
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDateParser {
public static void main(String[] args) {
System.out.println("isValid - dd/MM/yyyy with 20130925 = " + isValidFormat("dd/MM/yyyy", "20130925"));
System.out.println("isValid - dd/MM/yyyy with 25/09/2013 = " + isValidFormat("dd/MM/yyyy", "25/09/2013"));
System.out.println("isValid - dd/MM/yyyy with 25/09/2013 12:13:50 = " + isValidFormat("dd/MM/yyyy", "25/09/2013 12:13:50"));
}
public static boolean isValidFormat(String format, String value) {
Date date = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
date = sdf.parse(value);
if (!value.equals(sdf.format(date))) {
date = null;
}
} catch (ParseException ex) {
ex.printStackTrace();
}
return date != null;
}
}
Outputs (something like)...
java.text.ParseException: Unparseable date: "20130925"
isValid - dd/MM/yyyy with 20130925 = false
isValid - dd/MM/yyyy with 25/09/2013 = true
isValid - dd/MM/yyyy with 25/09/2013 12:13:50 = false
at java.text.DateFormat.parse(DateFormat.java:366)
at javaapplication373.JavaApplication373.isValidFormat(JavaApplication373.java:28)
at javaapplication373.JavaApplication373.main(JavaApplication373.java:19)
Not correct. For isValidFormat("yyyy-MM-dd", "2017-18--15"); not throw any Exception.
isValid - yyyy-MM-dd", "2017-18--15 = false
Seems to work as expected for me - the method doesn't rely on (nor does it throw) the exception alone to perform it's operation
For your case, you may use regex:
boolean isValidFormat = input.matches("([0-9]{2})/([0-9]{2})/([0-9]{4})");
For a larger scope or if you want a flexible solution, refer to MadProgrammer's answer.
Edit
Almost 5 years after posting this answer, I realize that this is a stupid way to validate a date format. But i'll just leave this here to tell people that using regex to validate a date is unacceptable
You can try this to simple date format valdation
public Date validateDateFormat(String dateToValdate) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HHmmss");
//To make strict date format validation
formatter.setLenient(false);
Date parsedDate = null;
try {
parsedDate = formatter.parse(dateToValdate);
System.out.println("++validated DATE TIME ++"+formatter.format(parsedDate));
} catch (ParseException e) {
//Handle exception
}
return parsedDate;
}
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
formatter.setLenient(false);
try {
Date date= formatter.parse("02/03/2010");
} catch (ParseException e) {
//If input date is in different format or invalid.
}
formatter.setLenient(false) will enforce strict matching.
If you are using Joda-Time -
private boolean isValidDate(String dateOfBirth) {
boolean valid = true;
try {
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy");
DateTime dob = formatter.parseDateTime(dateOfBirth);
} catch (Exception e) {
valid = false;
}
return valid;
}
Here's a simple method:
public static boolean checkDatePattern(String padrao, String data) {
try {
SimpleDateFormat format = new SimpleDateFormat(padrao, LocaleUtils.DEFAULT_LOCALE);
format.parse(data);
return true;
} catch (ParseException e) {
return false;
}
}
For example, if you want the date format to be "03.11.2017"
if (String.valueOf(DateEdit.getText()).matches("([1-9]{1}|[0]{1}[1-9]{1}|[1]{1}[0-9]{1}|[2]{1}[0-9]{1}|[3]{1}[0-1]{1})" +
"([.]{1})" +
"([0]{1}[1-9]{1}|[1]{1}[0-2]{1}|[1-9]{1})" +
"([.]{1})" +
"([20]{2}[0-9]{2})"))
checkFormat=true;
else
checkFormat=false;
if (!checkFormat) {
Toast.makeText(getApplicationContext(), "incorrect date format! Ex.23.06.2016", Toast.LENGTH_SHORT).show();
}
A combination of the regex and SimpleDateFormat is the right answer i believe. SimpleDateFormat does not catch exception if the individual components are invalid meaning,
Format Defined: yyyy-mm-dd
input: 201-0-12
No exception will be thrown.This case should have been handled.
But with the regex as suggested by Sok Pomaranczowy and Baby will take care of this particular case.
Regex can be used for this with some detailed info for validation, for example this code can be used to validate any date in (DD/MM/yyyy) format with proper date and month value and year between (1950-2050)
public Boolean checkDateformat(String dateToCheck){
String rex="([0]{1}[1-9]{1}|[1-2]{1}[0-9]{1}|[3]{1}[0-1]{1})+
\/([0]{1}[1-9]{1}|[1]{1}[0-2]{2})+
\/([1]{1}[9]{1}[5-9]{1}[0-9]{1}|[2]{1}[0]{1}([0-4]{1}+
[0-9]{1}|[5]{1}[0]{1}))";
return(dateToCheck.matches(rex));
}

Categories

Resources