This week's book giveaway is in the General Computing forum. We're giving away four copies of Arduino in Action and have Martin Evans, Joshua Noble, and Jordan Hochenbaum on-line! See this thread for details.
The following code takes in the string date of the following formats : yyyy-MM-dd HH:mm:ss:S , YYYY-MM-DD format, MM/DD/YYYY HH24:MI:SS or YYYY-MM-DD HH24:MI:SS, YYYY-MM-DDThh:mm:ssTZD, YYYY-MM-DDThh:mm:ss.sTZD, YYYY-MM-DDThh:mm:ss.ssTZD, DD Month YYYY and convert to the required date format yyyy-MM-dd HH:mm:ss. Please can you review if this is a optimum way of doing it ?
You should use code tag to wrap it. It is easier to read.
And actually there is Java API to do it.
Check SimpleDateFormat in Java If you really want to do it by your own code, you have to handle days in month, leap year, etc.
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
Thanks for the reply, but I have already tried using the SimpleDateFormat, but my problem is more complex. It should get the input string date, and check its format and as I said before it should allow only the formats yyyy-MM-dd HH:mm:ss:S , YYYY-MM-DD, YYYY-MM-DDThh:mm:ssTZD, YYYY-MM-DDThh:mm:ss.sTZD, YYYY-MM-DDThh:mm:ss.ssTZD, DD Month YYYY any other formats for example even if it is of the format DD-MM-YYYY it should output an empty string. I tried using the regex but I have another requirement to be checked , that is it should be valid date (DD) should be within 1 and 31 , Month ( MM ) should be within 1-12 and YYYY should not start with a 0. Can you please help me out?
Sindhu Kodoor wrote:Thanks for the reply, but I have already tried using the SimpleDateFormat, but my problem is more complex. It should get the input string date, and check its format and as I said before it should allow only the formats yyyy-MM-dd HH:mm:ss:S , YYYY-MM-DD, YYYY-MM-DDThh:mm:ssTZD, YYYY-MM-DDThh:mm:ss.sTZD, YYYY-MM-DDThh:mm:ss.ssTZD, DD Month YYYY any other formats for example even if it is of the format DD-MM-YYYY it should output an empty string. I tried using the regex but I have another requirement to be checked , that is it should be valid date (DD) should be within 1 and 31 , Month ( MM ) should be within 1-12 and YYYY should not start with a 0. Can you please help me out?
I would suggest you have a String variable 'currentFormat'. With regular expression checks(in if-elseif-else),first determine which format & set it in the currentFormat. Then use currentFormat as an argument to SimpleDateFormat constructor. Dont worry about the valid numbers to be present in date, month, year....when you do a parse, just expect a ParseException(invalid dates will throw one) - catch it, and there you go!
With using SimpleDateFormat, you can check the DateFormats 1 by 1.
If 1st format failed, try 2nd.
If 2nd format failed, try 3rd.
etc..
If no luck at all, return empty string.
So what's the problem you have got with using SimpleDateFormat?
Plus there's an Apache Commons class/method that'll take a number of date formats and do all this checking.
The code itself wouldn't survive a minute in a code review where I work; it's difficult to maintain, difficult to read, and could stand a fair amount of refactoring.
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
@Raymond Tong , yes SimpleDateFormat will convert it for me , but how do I check the format of the incoming date String and then redirect to the right formatting?
here I am using regExp to check the format of the the incoming string date, I am not too strong in regular expressions and it gets complicated while writing for UTC date format, can you please suggest alternative ways?
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
Plus there's an Apache Commons class/method that'll take a number of date formats and do all this checking
Could you please elaborate on the Apache Commons class?
Don't bother with the regular expression - you're just repeating the work that SimpleDateFormat is going to do anyway. Just try to parse with the SimpleDateFormat object. Catch the ParseException that's thrown, and move onto the next format. If a ParseException isn't thrown, then the date was in the right format.
You're parsing date into dateStr (wrong name, really! It suggests it's a string!) which you are then formatting using the same DateFormat. Then you're parsing the result to Date using the same DateFormat again. formattedDate will be the same as date and dateStr will be the same as date1.
Thanks for the reply, but I have already tried using the SimpleDateFormat, but my problem is more complex. It should get the input string date, and check its format and as I said before it should allow only the formats yyyy-MM-dd HH:mm:ss:S , YYYY-MM-DD, YYYY-MM-DDThh:mm:ssTZD, YYYY-MM-DDThh:mm:ss.sTZD, YYYY-MM-DDThh:mm:ss.ssTZD, DD Month YYYY any other formats for example even if it is of the format DD-MM-YYYY it should output an empty string. I tried using the regex but I have another requirement to be checked , that is it should be valid date (DD) should be within 1 and 31 , Month ( MM ) should be within 1-12 and YYYY should not start with a 0. Can you please help me out?
You should check out the other parse method: parse(String, ParsePosition). This method will not throw an exception but return null if the string is invalid. You should also call setLenient(false) on all your DateFormat instances; without it dates like "32-13-2013" will be allowed; this will be turned into February 2nd 2014.
Anyway, using this other parse method you can simply loop (hence the suggestion for an array) through the allowed patterns (order matters here), parse the string using the current pattern, then return the parse results if it isn't null. If all patterns fail to parse the string then it's invalid and you can throw a ParseException yourself.
Matthew Brown wrote:Don't bother with the regular expression - you're just repeating the work that SimpleDateFormat is going to do anyway. Just try to parse with the SimpleDateFormat object. Catch the ParseException that's thrown, and move onto the next format. If a ParseException isn't thrown, then the date was in the right format.
Instead of trying parsing with every format available(try-catch for every 7 formats), if we determine the format at first with regular expressions, wont it be easier to do parsing just once?
Try it and find out. My guess would be no, since my secondary guess would be that when parsing a fixed format regexes wouldn't be used. That would mean you'd be doing (relatively) slow parses to determine which fast parse to use.
But those are guesses--it should be trivial to determine the truth.
I'm not so worried about the performance - more about the maintenance. Why write a bunch of complicated regular expressions when there's no need for them? So "easier" - no.
I'm sure any (vaguely sensible) approach will be fast enough unless the method is really performance critical.
Matthew Brown wrote:I'm not so worried about the performance - more about the maintenance. Why write a bunch of complicated regular expressions when there's no need for them? So "easier" - no.
I'm sure any (vaguely sensible) approach will be fast enough unless the method is really performance critical.
Regular Expression is something very hard to understand if a junior developer will do some maintenance in your code.
I tried all what you people suggested, the problem is two things :
1. The format method is not parsing as expected for example : for the date 2010-10-12 (yyyy-MM-DD ) it is formatting as 2010-01-12 why is that ? is there anything else other than formatting I could do?
2. When I get a input date string , how do I check its format? even if I put it in an array it would nt help, as it would just format according to the array[anything possible] , and give me results in an unusual way, Am I missing something? I am definetly doing it wrong :
Raymond Tong wrote:Remember, Java is case sensitive.
It is, but in this case, what's really relevant is that date format strings are case-sensitive.
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
Hi,
How do I check for the incoming date format of a string date, for example if a date is 2010-12-12 then how do i validate its of the format yyyy-MM-DD? please suggest
You've already been given a number of solutions, which boil down to the same thing: try parsing it as a format. If it fails, it's not that format, try the next format. The Commons library I pointed you at does it for you, the other solutions which suggest the exact same thing are just you doing it yourself instead of using somebody else's code.
What's wrong with the ideas that have already been given to you? Why don't you believe they'll work? Why not use the Apache Commons library that already does what you want? If you can't tell us why you don't think that will work, or what your confusion is, we can't help.
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
Remember, Java is case sensitive.
Dint see this post , it works now , all this while had been given yyyy-MM-DD it should be yyyy-MM-dd . Thanks everyone !!!
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
ok there is one last problem for the solution to work, when I give a date and time as "2010-12-03 10:30:00" it converts to "2010-12-03 12:00:00" , in the SimpleDateFormat javadoc it mentions that it always changes the HH to 12 , how do I get rid of that ? I want it as it is "10:30:00"
If you parse a date(with time) string with format "yyyy-MM-dd", you will get the date object without time details. So in your code, you might be trying the format "yyyy-MM-dd" before "yyyy-MM-dd hh:mm:ss" so the date gets parsed with the first format without time details and the time gets defaulted to 00:00:00.
- Marimuthu Madasamy
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
yes you are right , but how do I get the 24 hour time zone? if I give 2010-03-12 14:30:00 it converts to 2010-03-14 02:30:00, I want it to maintain the 24 hour pattern
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
I got the answer use "k" instead of "HH" it retains the 24 hour pattern :
Letter Date or Time Component Presentation Examples
G Era designator Text AD
y Year Year 1996; 96
M Month in year Month July; Jul; 07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day in week Text Tuesday; Tue
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
The bit about if (foo) return false; is poor style. You can write return (foo); or return !(foo); or return (foo || bar);
Why are you returning false if the month is 0 and then using months[0] for January? What about if a negative number is entered? Shouldn't you throw an Exception instead?
Sindhu Kodoor
Ranch Hand
Joined: Sep 03, 2010
Posts: 65
posted
0
I am not using that code n e more, now I am using SimpleDateFormat. Can anyone help me out in formatting the UTC date format to normal format ?
For ex : 2010-04-18T17:33:13.412Z to 2010-04-18 17:33:13 but currently with the existing code its converting to 2010-04-18 05:30:00
Can you show the actual date you're trying to convert and the formats you're using again?
Rather than posting this code chunk, it's easier for us if you post a minimal code sample showing the least amount of code necessary to reproduce the problem, including all the inputs you're using.