4
$\begingroup$

I'd like to create a list with days from the 4th of July to the 4th of October starting in July 1970 to the current date. I tried to use DateRange, but I'm a bit confused cause the documentation is't very clear on this point.

What should I do? Have you ever tried to do such a thing?

$\endgroup$
10
  • 1
    $\begingroup$ You mean from the 4th of July to the 4th of October of every year? $\endgroup$
    – Öskå
    Aug 4, 2014 at 11:02
  • 1
    $\begingroup$ Some important things that you left out from your question: how do you want to results to be formatted and how do you plan to use them later? $\endgroup$
    – m_goldberg
    Aug 4, 2014 at 11:06
  • 1
    $\begingroup$ Does my most recent edit of the title characterize your question correctly? $\endgroup$
    – m_goldberg
    Aug 4, 2014 at 11:18
  • 5
    $\begingroup$ Does this produce your desired result: Flatten[DateRange[{#, 7, 4}, {#, 10, 4}, "Day"] & /@ Range[1974, 2013], 1]? $\endgroup$
    – ubpdqn
    Aug 4, 2014 at 11:20
  • 1
    $\begingroup$ @ubpdqn. I'm reading this as the entire summer after the 7/4 up to the current year. if current date of current year is after 4th but before the end of summer, it ends there, otherwise, to end of most recent summer. $\endgroup$
    – m_goldberg
    Aug 4, 2014 at 11:22

3 Answers 3

2
$\begingroup$

Borrowing from @ubpdqn, my interpretation of the question (which, hopefully, should also be valid in 2015):

td = Today // Normal;
{cy, cm, cd} = Take[td, 3];
days = Flatten[DateRange[{#, 7, 4}, {#, 10, 4}, "Day"] & /@ Range[1970, cy], 1];

Which[
 Today > Interpreter["Date"]["04/October/" <> ToString@cy], days,
 Today < Interpreter["Date"]["04/July/" <> ToString@cy], DeleteCases[days, {cy, __}], True,
 DeleteCases[days, {y_, m_, d_} /; y == cy && m > cm || y == cy && m == cm && d > cd]]
$\endgroup$
3
$\begingroup$

My answer is based on @eldo's and @ubpdqn's answer (thanks guys!). Remove // Flatten[#, 1] & to get the dates grouped into years.

Clear[seismaticaDates]
seismaticaDates[year_,{mfrom_,dfrom_},{mto_,dto_},{cy_,cm_,cd_}]:=
Module[{dateRangeFunc,allDates},
dateRangeFunc=DateRange[{#,mfrom,dfrom},{#,mto,dto}]&;
(* Defining 2 allDates functions to prevent counting days
when the date of the current year hasn't reached the starting date of the interval 
i.e. take the "nearest past summer" *)
allDates[{y_,m_,d_}/;m<mfrom||m==mfrom&&d<dfrom]:=dateRangeFunc/@Range[year,y-1];
allDates[{y_,m_,d_}]:=dateRangeFunc/@Range[year,y];
DeleteCases[allDates[{cy,cm,cd}],{cy,m_,d_}/;m>cm||(m==cm&&d>cd),{2}]//Flatten[#,1]&]

seismaticaDates[1970,{7,4},{10,4},Take[Normal@Today,3]]
{{1970,7,4},{1970,7,5},{1970,7,6},{1970,7,7},{1970,7,8},{1970,7,9},{1970,7,10},{1970,7,11},{1970,7,12},{1970,7,13},{1970,7,14},{1970,7,15},{1970,7,16},{1970,7,17}, ...4096... ,{2014,7,22},{2014,7,23},{2014,7,24},{2014,7,25},{2014,7,26},{2014,7,27},{2014,7,28},{2014,7,29},{2014,7,30},{2014,7,31},{2014,8,1},{2014,8,2},{2014,8,3},{2014,8,4}}

seismaticaDates[1970,{7,4},{10,4},{2015,1,3}]
{{1970,7,4},{1970,7,5},{1970,7,6},{1970,7,7},{1970,7,8},{1970,7,9},{1970,7,10},{1970,7,11},{1970,7,12},{1970,7,13},{1970,7,14},{1970,7,15},{1970,7,16},{1970,7,17}, ...4157... ,{2014,9,21},{2014,9,22},{2014,9,23},{2014,9,24},{2014,9,25},{2014,9,26},{2014,9,27},{2014,9,28},{2014,9,29},{2014,9,30},{2014,10,1},{2014,10,2},{2014,10,3},{2014,10,4}}

Comparison with @eldo's method

My method seems to not require any Internet connection (as compared to @eldo's method), and it seems to run faster as well.

eldoDates=Module[{td,cy,cm,cd,days},
td=Today//Normal;
{cy,cm,cd}=Take[td,3];
days=Flatten[DateRange[{#,7,4},{#,10,4},"Day"]&/@Range[1970,cy],1];
Which[Today>Interpreter["Date"]["04/October/"<>ToString@cy],days,Today<Interpreter["Date"]["04/July/"<>ToString@cy],DeleteCases[days,{cy,__}],True,DeleteCases[days,{y_,m_,d_}/;y==cy&&m>cm||y==cy&&m==cm&&d>cd]]]//AbsoluteTiming;

s1=seismaticaDates[1970,{7,4},{10,4},Take[Normal@Today,3]]//AbsoluteTiming;
First/@{s1,eldoDates}
(* {0.069004,0.776044} *)

Equal[Rest@s1, Rest@eldoDates]
(* True *)
$\endgroup$
1
$\begingroup$

Again with the understanding that an answer has already been accepted. I submit the following only as an exercise:

    Clear[repeatdaterange];
repeatdaterange[startdate_, enddate_] := Module[{startyear, startmonth, startday, endyear, endmonth,endday, curyear, curmonth, curday, stopyear, stepping, lastmonth, listofdates, rangeofdates},
{startyear, startmonth, startday} = startdate;
{ endyear, endmonth,endday} = enddate;
 {curyear, curmonth, curday} = Take[DateList[],3];
stopyear = If[curmonth >=startmonth, curyear, Subtract[curyear,1] ];
stepping = Subtract[endmonth ,startmonth];
lastmonth = If[curmonth>=endmonth &&  curday >= endday,endmonth,curmonth];
listofdates =Table[{i,j,startday}, {i,startyear,stopyear}, {j,startmonth,If[i == stopyear,lastmonth,endmonth],stepping} ];
listofdates = If[First[Dimensions[Last[listofdates] ]] ==  1, ReplacePart[ listofdates, Length[listofdates] -> {Last[listofdates][[1]],{stopyear,lastmonth,curday } }],listofdates ];
rangeofdates = Apply[DateRange, listofdates,1]
]

One can add another parameter to the function for final date instead of current runtime in the DateList[{insert final date here}]. There may be small boundary issues but this runs fairly fast.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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