Does Mathematica have a built-in date picker?

Date-picker implementation in Mathematica

The following is my implementation of a simple date-picker. The current date is highlighted in LightBlue and the weekends are highlighted in LightGreen. The selected date is always highlighted in LightRed (the default selection is the current date).

You can tap into this calendar by using the Dynamic values for year, month and date for your custom function (a simple example in the last Panel).

Code:

Note that the following implementation uses DayName, which was introduced in version 9. You might have to roll your own if you want to use this in earlier versions of Mathematica.

With[{startDayOffset = Thread[{Sunday, Monday, Tuesday, Wednesday, Thursday, 
        Friday, Saturday} -> Range@7]},   
    DynamicModule[{month, year, date, today = DateList[][[;;3]], daysInMonth, calendarView},
        
        {year, month, date} = today;

        daysInMonth[m_Integer,y_Integer] := DatePlus[{y, m, 1}, {{1, "Month"}, {-1, "Day"}}][[3]];

        calendarView[m_Integer, y_Integer] := Grid[
            {Style[#, FontWeight -> Bold]& /@ {"Su","M","Tu","W","Th","F","Sa"}} ~Join~ 
            Partition[Range@daysInMonth[m, y], 7, 7, {DayName[{y, m, 1}] /. startDayOffset, 1}, {""}],
            Frame -> All,
            FrameStyle -> LightGray
        ] /. { i_Integer :> Button[
                    i, 
                    date=i, 
                    Appearance->"Palette", 
                    Background -> Which[
                        date==i, LightRed,
                        {year, month, i} === today, LightBlue,
                        !FreeQ[DayName[{year, month, i}],Saturday|Sunday],LightGreen,
                        True,White
                    ],
                    ImageSize->{32,32}
                ],
                s_String :> Button[
                    s, 
                     , 
                    Appearance -> "Palette", 
                    Enabled -> False, 
                    Background -> If[!s == "", LightGray],
                    ImageSize->{32,32}
                ]
            };

        Panel[
            Column[{
                Row[{
                    Style["Year ",FontSize->16], PopupMenu[Dynamic@year, 1970 ~Range~ 2020],Spacer[10]
                    Style["Month ",FontSize->16],PopupMenu[Dynamic@month, Range@12 ]
                }],
                Dynamic@calendarView[month, year],
                Panel[Dynamic@StringForm["Selected date: `1`/`2`/`3`", date, month, year]]
            }]
        ]
    ]
]

There is a built-in DateSetter:

{Developer`DateSetter[Dynamic@date], Dynamic@date}

ScreenGIF

By default the first selectable date is tomorrow and one can only go to future months. However, the option NotebookTools`DateSetterRange can be used to set the first selectable date to sometime in the past,

{Developer`DateSetter[Dynamic@date, NotebookTools`DateSetterRange -> {2015, 1, 1}], 
 Dynamic@date}

DateSetterInAction1

or to only allow a certain date range.

{Developer`DateSetter[Dynamic@date, 
  NotebookTools`DateSetterRange -> {{2015, 1, 1}, {2015, 5, 2}}], 
 Dynamic@date}

DateSetterInAction2


Here is one that should work in version 6 and later. The full code is at bottom.

Here is what it looks like:

{dateSetter[Dynamic[d]],Dynamic[d]}

dateSetter button

I did not incorporate the year here, but you could put it in a Tooltip or add it to the button's graphic.

And when you click on the button you get

enter image description here

Incorporate this into a Manipulate using {d,dateSetter[#]&} as a control:

Manipulate[DynamicModule[{difference},
 difference=DateDifference[DateList[][[1;;3]],d];Style[Row[{DateString[d,{"DayShort"," ","MonthName"," ","Year"}]," ",difference/.{x_/;x<-1:>Row[{"was ",-x," days ago."}],
 x_/;x==-1->"was yesterday.",
 x_/;x==0->"is today.",
 x_/;x==1->"is tomorrow.",
 x_:>Row[{"is ",x," days from now."}]}}],"Text"]],{{d,DateList[][[1;;3]],""},dateSetter[#]&}]

dateSetter in Manipulate

The code:

Clear[monthDays];
monthDays[year_,month_]:=DateDifference[DateList@{year,month},DateList@{year,month+1}];
monthDays[date_List/;Length@date<=6]:=monthDays[date[[1]],date[[2]]];
monthDays[date_String]:=monthDays@@DateList[date][[1;;2]];

Clear[monthDates];
monthDates[year_,month_]:=DatePlus[DateList@{year,month,0},#]&/@Range[monthDays[year,month]];
monthDates[date_List/;Length@date<=6]:=monthDates[date[[1]],date[[2]]];
monthDates[date_String]:=monthDates@@DateList[date][[1;;2]];

Clear[dayNames];
dayNames[]=DateString[{0,0,#},"DayNameShort"]&/@Range[-1,5];

Clear[dayOfWeek];
dayOfWeek[date_List]:=DateString[date,{"DayNameShort"}]/.Thread[dayNames[]->Range[0,6]];
dayOfWeek[year_,month_]:=dayOfWeek[{year,month,1}];

Clear[previousMonth];
previousMonth[year_,month_]:=Take[monthDates[year,month][[All,3]],-dayOfWeek[year,month]];

Clear[nextMonth];
nextMonth[year_,month_]:=Take[monthDates[year,month+1][[All,3]],7-dayOfWeek[year,month+1]];

Clear[monthArray];
monthArray[year_,month_]:=Module[{array},array=Partition[Join[Button[Style[#,Gray,Bold,FontFamily->"Helvetica"],Appearance->None,ImageSize->All,Enabled->False]&/@previousMonth[year,month],Button[Style[#,Darker[Cyan,.4],Bold,FontFamily->"Helvetica"],DialogReturn[{year,month,#}],Appearance->None,ImageSize->All]&/@monthDates[year,month][[All,3]],Button[Style[#,Gray,Bold,FontFamily->"Helvetica"],Appearance->None,ImageSize->All,Enabled->False]&/@nextMonth[year,month]],7,7,1,{}];
If[Length@array<6,Append[array,ConstantArray[Button[Style["",Gray,Bold,FontFamily->"Helvetica"],Appearance->None,ImageSize->All,Enabled->False],7]],array]]

Clear[dateSetter];
dateSetter[Dynamic[date_]]:=DynamicModule[{tmpdate,mousepos,storeddate},
   If[Length@date<3,date=storeddate=tmpdate=DateList[][[1;;3]],tmpdate=storeddate=date];
   Button[Dynamic[Graphics[{Lighter[Red,.3],Rectangle[{0,.6},{1,1},RoundingRadius->.1],
            White,Rectangle[{0,0},{1,.5},RoundingRadius->.1],
            Rectangle[{0,.3},{1,0.7}],
            EdgeForm[GrayLevel[0.4]],FaceForm[],Rectangle[{0,0},{1,1},RoundingRadius->.1],
            White,Text[Style[DateString[storeddate,{"MonthNameShort"}],Bold,FontFamily->"Helvetica"],{0.5,0.85}],
            GrayLevel[0.3],Text[Style[DateString[storeddate,{"DayShort"}],Bold,FontFamily->"Helvetica",FontSize->Scaled[.5]],{0.5,0.35}]},
            ImageSize->40]],
          mousepos=MousePosition["ScreenAbsolute"];
          tmpdate=DialogInput[Dynamic@Style[Grid[Join[{{Row[{Button[Style["\[LeftPointer]\[LeftPointer]",Medium,Bold,FontFamily->"Helvetica"],tmpdate=DatePlus[tmpdate,{-1,"Year"}],ImageSize->All,Appearance->None],
                     Button[Style["\[LeftPointer]",Medium,Bold,FontFamily->"Helvetica"],tmpdate=DatePlus[tmpdate,{-1,"Month"}],ImageSize->All,Appearance->None]},Spacer[3]],
                     Style[DateString[tmpdate,{"MonthName"," ","Year"}],Bold,FontFamily->"Helvetica",Medium],
                     SpanFromLeft,SpanFromLeft,SpanFromLeft,SpanFromLeft,
                     Row[{Button[Style["\[RightPointer]",Medium,Bold,FontFamily->"Helvetica"],tmpdate=DatePlus[tmpdate,{1,"Month"}],ImageSize->All,Appearance->None],
                     Button[Style["\[RightPointer]\[RightPointer]",Medium,Bold,FontFamily->"Helvetica"],tmpdate=DatePlus[tmpdate,{1,"Year"}],ImageSize->All,Appearance->None]},Spacer[3]]}},
                     {Style[#,FontFamily->"Helvetica",Medium]&/@dayNames[]},
                     monthArray[tmpdate[[1]],tmpdate[[2]]]],Background->{{None},{GrayLevel[0.8]}},Frame->True,Spacings->{.5,.5}],Small,FontFamily->"Helvetica"],
                  WindowMargins->{{mousepos[[1]],Automatic},{Automatic,mousepos[[2]]}},WindowElements->None,WindowFloating->True];
          If[tmpdate=!=$Failed,date=storeddate=tmpdate,tmpdate=date],Method->"Queued",
      Appearance->None]
]