Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Does Mathematica have an interactive date input control that lets the user choose a date by browsing to a calendar view and returning the selected date as a date list? For example, something like the Datepicker in jQuery.

share|improve this question
1  
No, it doesn't. But it shouldn't be difficult to build one using the basic controls that are available. –  Sjoerd C. de Vries Dec 18 '12 at 15:35
    
Maybe a starting point here. –  b.gatessucks Dec 18 '12 at 16:05
    
There is also some Wolfram examples with date pickers but looks like @rm -rf has delivered :) –  Mike Honeychurch Dec 18 '12 at 20:52
3  
I don't know if it is smart about about picking dates, but there is this for finding stable marriages. (Or did you mean to pick dates from trees? That part was ambiguous...) –  Daniel Lichtblau Jan 2 '13 at 16:39

3 Answers 3

up vote 22 down vote accepted

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]]
            }]
        ]
    ]
]
share|improve this answer
4  
+1 That's a really nice bit of Mathematica code. And, unlike the Mayan calendar, it doesn't stop in a couple of days. –  cormullion Dec 19 '12 at 9:16
1  
No month rules, leap year stuff and data necessary if you just use DatePlus[date, {{1, "Month"}, {-1, "Day"}}][[3]], with date the first of the month you're interested in. –  Sjoerd C. de Vries Dec 20 '12 at 22:50
    
@SjoerdC.deVries Thanks, that's much better :) Updated –  rm -rf Dec 21 '12 at 4:05

Here's a silly one that works only in version 9:

DynamicModule[{x = 0}, AngularGauge[Dynamic[x], {0, 365}, 
  GaugeFrameStyle -> Black, 
  GaugeFrameSize -> .01,
  ScaleDivisions -> 0,
  GaugeFaceStyle -> Directive[LightGreen, EdgeForm[]], 
  GaugeFaceElementFunction -> "PlateauSector",
  GaugeLabels -> 
   Dynamic[
    Style[
     DateString[
      DatePlus[{2013, 1, 1}, x], {"DayName",   " ", "MonthName", " ", 
       "Day" , ", ", "Year"}], 10 , Bold, Gray]]]]

silly gauge

share|improve this answer

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]
] 
share|improve this answer
    
The appearance and functionality is inspired by Developer`DateSetter[], pointed out to me by @WReach. That function is not documented, and it crashes my front end session quite reliably. –  JxB Jan 2 '13 at 9:33
    
I think that you forgot to include the monthDates definition. –  Gustavo Delfino Jan 2 '13 at 17:56
    
@GustavoDelfino It's there right after the Clear[monthDates]. –  JxB Jan 2 '13 at 18:36
    
Thank you @JxB. I fell victim to the invisible scroll bars in Mac OS X. –  Gustavo Delfino Jan 4 '13 at 16:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.