Using DateTimePicker and Custom Format

Today we ran into a nasty problem with DateTimePickerFormat.Custom. We allow the user to input a month/date with a DateTimePicker as following (nothing fancy):

private void Form1_Load(object sender, EventArgs e)
{
 this.dateTimePicker1.Value = new DateTime(2007, 8, 31);
 this.dateTimePicker1.Format = DateTimePickerFormat.Custom;
 this.dateTimePicker1.CustomFormat = "MM/yyyy";
}

Now, change to 09/2007 and notice that you get an Exception, because the control tries to create an unrepresentable new DateTime(2007, 8+1, 31). Thus, if you’re going to use the DateTimePicker for MM/yyyy input make sure to set it’s value to a DateTimeTime with a day component that exists for all months/years (thus a value between 1 and 28).

Addendum: As usual, super moderator and MVP Hans Passant provided a nice workaround for the problem:)

public class MonthPicker : DateTimePicker {
  public MonthPicker() {
    this.Format = DateTimePickerFormat.Custom;
    this.CustomFormat = "MM/yyyy";
    DateTime now = DateTime.Now;
    this.Value = new DateTime(now.Year, now.Month, 1);
  }
  protected override void WndProc(ref Message m) {
    if (m.Msg == 0x204e) {
      NMHDR hdr = (NMHDR)m.GetLParam(typeof(NMHDR));
      if (hdr.code == -759) {
        NMDATETIMECHANGE dt = (NMDATETIMECHANGE)m.GetLParam(typeof(NMDATETIMECHANGE));
        this.Value = new DateTime(dt.st.wYear, dt.st.wMonth, 1);
        return;
      }
    }
    base.WndProc(ref m);
  }
  // P/Invoke declarations
  [StructLayout(LayoutKind.Sequential)]
  private struct NMHDR {
    public IntPtr hWnd;
    public IntPtr id;
    public int code;
  }
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  private class NMDATETIMECHANGE {
    public NMHDR nmhdr;
    public int dwFlags;
    public SYSTEMTIME st;
  }
  [StructLayout(LayoutKind.Sequential)]
  private class SYSTEMTIME {
    public short wYear;
    public short wMonth;
    public short wDayOfWeek;
    public short wDay;
    public short wHour;
    public short wMinute;
    public short wSecond;
    public short wMilliseconds;
  }
}

4 thoughts on “Using DateTimePicker and Custom Format

  1. Hi Tim,

    I ran into the same datepicker problem today…and yours is the only page on whole of the internet which gives a solution for this problem. Thanks for that.

    BUT, I would like to know if microsoft has confirmed this as bug in the framework? any URLs? links? I mean is it seems to be bug but i dont find any documentation for that on microsoft forum.

    Thanks,
    Ashutosh

  2. Thanks Tim,

    Would you report that as a bug to microsoft? I mean it would be good to have the official reply to this bug.

    If you are buzy and dont mind I can try to report that as a bug.

    Thanks
    Ashutosh

  3. Tive problema semelhante.

    Adicionei o formato custom para MM/yyyy.
    Quando meu calendario marca, por exemplo, 30/03/2011, meu datepicker mostra 03/2011. Entretanto, parece que internamente exibe 30/03/2011. quando altero o datepicker para o mês 2, ele tenta montar a data em 30/02/2011. sendo que o mês 2 não possui o dia 30. causando o erro. Não sei como resolver este problema.

Comments are closed.