tags:

views:

114

answers:

1

I have the need to handle partial dates, so for example:

  • 1 April 2009 (stored as 1, 4, 200)
  • Jan 2000 (Stored as null, 1, 2000)
  • March 90 (Stored as null, 3, 1990)
  • 00 (Stored as null, null, 2000)

and so on.

Looking at it, I don't think it's a massive problem as it will only have to handle UK dates, so globalization is not a consideration. The fiddly bit will be working out what a user means when they type 50, does that means 1950 or 2050.

Before I actually wade in and reinvent the wheel, has this been done before in some code that I can either use as reference or directly?

Updates for Clarity

The partial dates will be used to store the date of birth for people who are less than 25 years old.

As for how the data will be displayed:

User Enters: 01/00

Interpreted as: Jan/2000

Displayed as: Jan 2000

User Enters: 01/01/99

Interpreted as: 1/Jan/1999

Displayed as: 1 Jan 1999

A: 

If we put these values through DateTime.Parse, then the only one that causes a problem is the last one, because it contains no date indication of any form:

Console.WriteLine(DateTime.Parse("1 April 2009"));
// Outputs 01/04/2009 00:00:00
Console.WriteLine(DateTime.Parse("Jan 2000"));
// Outputs 01/01/2000 00:00:00
Console.WriteLine(DateTime.Parse("March 90"));
// Outputs 01/03/1990 00:00:00
Console.WriteLine(DateTime.Parse("00"));
// Throws an exception

However, putting Jan at the start of the last string gives us:

Console.WriteLine(DateTime.Parse("Jan 00"));
// Outputs 01/01/2000 00:00:00

So, perhaps a slightly hacky solution is to regex match any string consisting solely of 2 or 4 numbers, and prefix it with the text "Jan"?

    String sample = "00";

    //check for 2 or 4 numbers in the string, nothing else 
    //except space before and after
    if (Regex.IsMatch(sample, @"^\s*(\d{2}|\d{4})\s*$"))
    {
        sample = "Jan " + sample;
    }

    Console.WriteLine(DateTime.Parse(sample));
    // Outputs 01/01/2000

That will also work if sample is 00, 2000, or any other 2 or 4 digit (plus whitespace) strings.

The 3/00 string as indicated in your comment is a doozy, DateTime won't except it if it's prefixed with a 0, or if the "/" is replace with whitespace. What you need to do to that is check for a string containing a "/" followed by 2 digits, and then prefix those two digits with "20", resulting in "3/2000", which is parsed ok.

Annoyingly, the DateTime.Parse method does not allow for detection of null fields it found while parsing (it simply detected those as the start of the month/year).


Perhaps, as a UI suggestion, instead of trying to be too clever when putting into the database, while the user is typing in this crazy date string, parse it when the form (is it a web form?) is submitted. If the format is not immediately clear, suggest possibles to the user, like, did you mean 1950, or 2050?

Kazar