# I'm trying to filter a date range by day of month and day of week - what am I doing wrong?

I am trying to generate a list of dates that match two criteria: they have to all be the first of the month, and they have to be a particular day of the week, Sunday in my case.

The code I have written is this:

Select[DayRange[{1901, 1, 1}, {2000, 12, 31}], DayName[#] == Sunday && # == {_, _, 1} &]

I.e. I want to Select only those days in between the DayRange 1 january 1901 and 31 December 2000 that match the criteria of being a Sunday as well as (&&) being the first of the month ({_, _, 1}).

However, this function just outputs an empty list.

I'm still new to Mathematica, but in as far as I can see everything here should work fine. What am I doing wrong?

• # == {_, _, 1} should use MatchQ instead of ==. Mar 4 '14 at 0:57
• Ah thank you! Is that because the # == {_, _, 1} form cannot interpret patterns?
– Aron
Mar 4 '14 at 1:04
• Think of patterns like regexes. Your expression isn't "equal" to a regex. Your expression "matches" it. Mar 4 '14 at 1:08
• Yes. == is for numbers and equations (i.e. math), === is for testing if expressions are structurally identical (i.e. programming only, no math), MatchQ is for pattern matching. Mar 4 '14 at 1:10
• Got it. Thanks @belisarius! And @Szabolcs, you've been extremely helpful to me the past few days!
– Aron
Mar 4 '14 at 1:10

Select[Cases[DayRange[{1901, 1, 1}, {2000, 12, 31}], {_, _, 1}], DayName[#] == Sunday &]


or more concisely:

Cases[DayRange[{1901, 1, 1}, {2000, 12, 31}], d : {_, _, 1} /; DayName[d] == Sunday]


Does it. If you want to keep it all in a select,

Select[DayRange[{1901, 1, 1}, {2000, 12, 31}], (DayName[#] == Sunday && MatchQ[#, {_, _, 1}]) &]


Does the same, but slower.

By far the faster:

Cases[DayRange[{1901, 1, 1}, {2000, 12, 31}, Sunday], {_, _, 1}]


Edit: Per comment below, with changes in later versions of Mathematica, the last example becomes:

Cases[DayRange[{1900, 1, 1}, {2000, 12, 31}, Sunday], d_ /; DateValue[d, "Day"] == 1]


I will revisit when time permits to include modified versions of other examples and compare performance, along with experimenting with new date function characteristics to determine if a yet more efficient implementation exists.

• Thank you @rasher! This was my first foray into pattern matching - I'm still not clear exactly how patterns and forms work, but your answer (especially the second form) gave me a better understanding
– Aron
Mar 4 '14 at 1:15
• @anon: Take a look also at the docs for DayRange: using the construct of the last in my answer is over 100X faster, since it lets the low-level code of DayRange filter out the "Sunday" requirement...
– ciao
Mar 4 '14 at 1:17
• @rasher just edited typographical error (-> concisely): am learning from and enjoying your answers Mar 4 '14 at 9:38
• @ubpdqn: Thanks for edit & kind words - not so sure there's anything to learn from me other than I'm a pour speller ;-}
– ciao
Mar 4 '14 at 9:43
• @rasher always learning...MSE good diversion from 'real world' at present :) Mar 4 '14 at 9:47

I have voted for rasher's excellent answer but just to illustrate Pick:

With[{dr = DayRange[{1901, 1, 1}, {2000, 12, 31},Sunday]},
Pick[dr, Last@# == 1 & /@ dr]]