views:

27

answers:

2

Hi,

I've found that the Date.TryParse is pretty lenient on input - so skipping out the day or month will still return a value, though always floor rounded. E.g.:

DateTime.TryParse("2010", out testDate)
-> 01 Jan 2010

or

DateTime.TryParse("may 2010", out testDate)
-> 01 May 2010

I'd like to allow the user to input a date to be used as the upper date limit for a search - Is there a simple way to get it to round up - e.g.: return 31/12/2010 when just '2010' is entered...

Thanks in advance.

+1  A: 

You could have something like this:

string inputDate = "May 2010";
int year = 0;
DateTime date = new DateTime();

// Try to parse just by year.
// Otherwise parse by the input string.
if (int.TryParse(inputDate, out year))
{
    date = new DateTime(year, 12, 31);
}
else
{
    // Parse the date and set to the last day of the month.
    if (DateTime.TryParse(inputDate, out date))
    {
        date = date.AddMonths(1).AddMilliseconds(-1);
    }
    else
    {
        // Throw exception for invalid date?
    }
}
TheCloudlessSky
+1  A: 

Assuming you want to be able to parse all the formats that DateTime.TryParse can, you could do something like this:

    public static bool DateTimeTryParseMax(string dtText, out DateTime testDate)
    {
        testDate = DateTime.MinValue;

        string nFmt = null;
        foreach (string fmt in System.Globalization.DateTimeFormatInfo.CurrentInfo.GetAllDateTimePatterns().Concat(new string[] {"yyyy", "yy"}))
        {
            if (DateTime.TryParseExact(dtText, fmt, System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None, out testDate))
            {
                nFmt = fmt;
                break;
            }
        }

        if (nFmt == null)
            return false;

        nFmt = nFmt.Replace("dddd", "xxxx"); // Remove Day of the week as not helpful
        if (!nFmt.Contains("M")) testDate = testDate.AddMonths(12).AddMonths(-1);
        if (!nFmt.Contains("d")) testDate = testDate.AddMonths(1).AddDays(-1);
        if (!nFmt.Contains("h") & !nFmt.Contains("H")) testDate = testDate.AddDays(1).AddHours(-1);
        if (!nFmt.Contains("m")) testDate = testDate.AddHours(1).AddMinutes(-1);
        if (!nFmt.Contains("s")) testDate = testDate.AddMinutes(1).AddSeconds(-1);

        return true;
    }

This will only set the parts the user didn't to the maximum value.

JDunkerley