0

I've got a Datepicker and I'd like to allow multiple formats for users. For example, for the date January 5th 2014 I want to allow the following formats:

  • 05-01-2014 : dd-MM-yyyy
  • 5-01-2014 : d-MM-yyyy
  • 5-1-2014 : d-M-yyyy
  • 5-01-14 : d-MM-yy
  • 5-1-14 : d-M-yy
  • 05-1-2014 : dd-M-yyyy
  • 05-1-14 : dd-M-yy
  • 05-01-14 : dd-MM-yy
  • 05012014 : ddMMyyyy
  • 050114 : ddMMyy
  • 512014 : dMyyyy
  • 5114 : dMyy

I did create the following test-converter:

public class DatepickerConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return null;

        return ((DateTime)value).ToString("dd-MM-yyyy", CultureInfo.InvariantCulture);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (string.IsNullOrWhiteSpace(value as string)) return null;

        DateTime dt = DateTime.MinValue;
        string[] checks = {
                            "dd-MM-yyyy",
                            "d-MM-yyyy",
                            "d-MM-yy",
                            "d-M-yyyy",
                            "d-M-yy",
                            "dd-M-yyyy",
                            "dd-M-yy",
                            "d-M-yyyy",
                            "d-M-yy",
                            "ddMMyyyy",
                            "ddMMyy",
                            //"dMyyyy",
                            //"dMyy",
                        };
        for(int i = 0; i < checks.Length; i++)
        {
            try
            {
                dt = DateTime.ParseExact(value as string, checks[i], CultureInfo.InvariantCulture);
                if (dt != null) break;
            }
            catch (Exception){ }
        }

        return dt as DateTime?;
    }
}

I have however one problem, and one concern.

The problem is that I've never assigned a converter to a DatePicker. I've googled it and found this stackoverflow answer, but it doesn't seem to go to the converter in debug mode.. FIXED

And my concern is that using this for-loop every time the user inputs something is a bit performance-counterproductive. I know I can add a Property-Delay so I can do this formatting when the User has put in the entire date, instead of doing this per character the user puts in, but still, isn't there a more efficient / more readable solution than checking all formats one by one?

Community
  • 1
  • 1
Kevin Cruijssen
  • 9,153
  • 9
  • 61
  • 135
  • 1
    Your strings that have one digit for month, day or year part might have problems. Read: http://stackoverflow.com/a/26778076/447156 – Soner Gönül Nov 18 '14 at 13:18
  • For exaample; `5114` doesn't match with `dMyy` format. – Soner Gönül Nov 18 '14 at 13:22
  • @SonerGönül Yeah, just had it working and was testing everything when I came across this. I think I'll just don't allow that particular one. So users should either use `0501year` or `5-1-year`. Thanks for the link btw. – Kevin Cruijssen Nov 18 '14 at 13:34

1 Answers1

1

Throwing exceptions each step costs a lot performance. Get rid of try{} catch{}, the for loop and use the very user-friendly TryParseExact. It will accept your 'checks' array variable.

if(DateTime.TryParseExact(value as string, checks, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
{
    // success
}
deafjeff
  • 754
  • 7
  • 25