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$
  • 1
    $\begingroup$ You mean from the 4th of July to the 4th of October of every year? $\endgroup$ – Öskå Aug 4 '14 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 '14 at 11:06
  • 1
    $\begingroup$ Does my most recent edit of the title characterize your question correctly? $\endgroup$ – m_goldberg Aug 4 '14 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 '14 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 '14 at 11:22
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]]
| improve this answer | |
$\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 *)
| improve this answer | |
$\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.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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