• Post Reply Bookmark Topic Watch Topic
  • New Topic

Handling Multiple Date Formats Elegantly  RSS feed

 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm working on an application which utilizes dates. One example is a person's date of birth. I read this data in as a String and then need to convert it to a Date object. I was planning on using the SimpleDateFormat class to do the conversion for me, but my problem is that people couple type in multiple date formats.

For example, I might get a date that looks like any of these:

10/21/2004
2004-21-10
10/21/04

With SimpleDateFormat, you need to specify what the format will look like when you create your object, like this:



If the date can't be parsed properly, I get a ParseException. So, to handle multiple date formats, I devised this:



To me, this really seems like a disgusting way to handle multiple date formats. The code is ugly and, anytime I want to add a new date format, I'd have to add another nested try/catch block.

Anyone have any better ways to go about this?

Muchas Gracias.
 
author & internet detective
Marshal
Posts: 37518
554
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Corey,
If you are on Java 1.4 or later, I would recommend using a regular expression. If 1.3 or below, just do a test for '-' or the length to figure it out.

Aside from being ugly, the try/catch blocks are misleading. Here a parse error is not an exception. It is something you are expecting to happen.

How are you handling the case where the user enters garbage like 'aaaa.' This may need to factor into your design decision.
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Honestly, Jeanne Boyarsky, do you just search these forums for my posts so you can answer 'em?


If you are on Java 1.4 or later, I would recommend using a regular expression. If 1.3 or below, just do a test for '-' or the length to figure it out.


Yup, I had considered that, but I'm not so good with regular expressions. I had figured they'd probably do well on this problem - I was wondering if someone would suggest them. I suppose this would be a good learning opportunity for me, then. :roll:


Aside from being ugly, the try/catch blocks are misleading. Here a parse error is not an exception. It is something you are expecting to happen.

How are you handling the case where the user enters garbage like 'aaaa.' This may need to factor into your design decision.


Indeed, the exceptions are a little bit misleading because they can be thrown when an expected result occurs.

I did consider what would happen if the user really entered some garbage data. Notice that the final "parse" isn't wrapped in it's own "try" block. If that one fails, it throws a ParseException and, likewise, so does the method this code is in (which, of course, you can't see ).

Thanks, Jeanne. As always, I appreciate the advice.
 
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree, regexes are probably your best option here. But you probably need try/catch also, for things like

13/20/04
2004-30-02

Writing a regex that will catch all the possible errors here is daunting, and probably a bad idea to even attempt. It's going to be way uglier than having three try/catch blocks. Actually you can probably get away with one try/catch here, since once you've determined the general form of the date, any further errors like having 30 days in February are just plain wrong, for any format.

Now, an important caveat: people in much of the world write dates with formats like dd/MM/yy rather than MM/dd/yy. If you've got users who use both formats, you're in for a hard time telling these types apart. Unless you can determine the locale of your user, to choose the appropriate format. You might get away with a heuristic approach if you have enough dates from each user - i.e. if you see 01/30/04, they're using dd/MM/yy, and you can probably assume that format for other dates from the same user. But if the only date you have is 02/05/04, and you don't know where the user is from, you really can't tell what they mean.

Personally I think all date formats other than yyyy/MM/dd should be banned, and users who persist in using them should be poked with a sharp stick.
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fortunately, anyone using this app will be in Iowa, Minnesota, or Wisconsin so, unless they're transplants from Europe (and, believe me, not many people move from Europe to Wisconsin), I can be sure that the dates will be MM/dd/yyyy, rather than the other way around.
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I just came to a revelation that should have struck me long ago - we're using Java 1.3. That means no regexes. Gah! I guess I'll have to come up with something nice and ugly.
 
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
...unless you use Jakarta's Regex libs which were created precicely to get around this deficiency in pre 1.4 APIs.
 
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
After reading this thread, I have a question: where do these date entries come from? If you are writing a front end GUI for the application, you *could* just force the user to enter the date in a certain format using JFormattedTextField along with a SimpleDateFormat configured with your desired format string. If you are retrieiving the dates from a database, it should already have a them in some standard format that you can easily manipulate. I guess it boild down to how much control you have over how the user enters the date. If you have the code that implements this portion of the application, you should be able to just tell the user if the format is not as you expected.

That's just my $0.02

Layne
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Layne Lund:
where do these date entries come from?


I had considered that, Layne, thanks. In some cases, I am getting data from a GUI (web browser) and, in that, I've forced the user to give me a specific date format so no worries there.

The problem I have is that there is also a feature that allows the user to upload a file filled with data, including dates. Since I'm processing this data "after the fact," I can't easily yell at the user for giving me an invalid date. In theory, all of the files should follow a specific format, but I trust theory about as far as I can throw my car.

Nonetheless, I think I'm finding ways to get around the problems of invalid dates. Thanks for all the help, folks.
 
Bartender
Posts: 1840
Eclipse IDE Java Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've got an algorithm around somewhere that handles any MMddyy(yy) format -- MM.dd.yy, MM/dd-yyyy, MMsomerandomstuffddsomemorerandomstuffyyyy -- all that. It unfortunately does not handle yyyy-MM-dd formats. You could handle others just by adding another parameter and telling it how to parse, but then you have determine if its MMddyyyy, ddMMyyyy, or yyyyMMdd (or yyyyddMM if you're sadistic...). I'll see if I can dig that up somewhere....
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 37518
554
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Honestly, Jeanne Boyarsky, do you just search these forums for my posts so you can answer 'em?

No I think we are in the same forums alot because we use the same tools. (This post being an extremely poor example of what I am trying to say.) Thanks for the emphasis on the y

We aren't on Java 1.4 yet either, but regular expressions are a good thing to keep in the back of your mind. Note that I wasn't suggesting using a regular expression to check the format, not to actually provide validation. There are a lot of regular expression examples for dates on the web.

I did consider what would happen if the user really entered some garbage data. Notice that the final "parse" isn't wrapped in it's own "try" block. If that one fails, it throws a ParseException and, likewise, so does the method this code is in (which, of course, you can't see ).

Yes, but the nested try/catches obstruct that making it hard to see what is going on.
 
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What I've done for time strings (but something similar could work for dates as well I guess) is to create a function that changes them around from pretty much whatever the user inputs to the format I want them to be.
So we now can have the user type 900, 0900, 090000, 9:00, etc. to mean 09:00:00.

With dates this can get a tad tricky if the order of the fields isn't guaranteed as you'll need some way to guestimate what that order will be (which isn't guaranteed to give the right result, for example what do you think 04/03/02 to be? Is it 2 march 2004, 3 feb 2004, 4 march 2002, 3 april 2002, etc. etc.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!