# Splitting dates into groups in half year steps

list = DayRange[{1999, 1, 1}, {2014, 2, 6}]


I want to split this list into sublists one and a half year long, moving a half year forward every time.

That would mean that the first dataset would go from 1999 to 2000 June. Next group would go from June 1999 to 2001 and so on. Last dataset group would not be complete due to the fact that the dates only goes to the 6th of February 2014.

There are two things that I want to point out.The assumption you made was correct about dividing the dates from Jan to the end of June so one. However, I have lists of dates with different length so I would like to be able to map a function over the different lists of dates where this dividing is occurring. So that no matter how long the list is it would divide it as I asked above. Please note, that the lists vary all from 4 to 20 years.

Also some lists are just Business days, so it would mean that in some cases the end of the month is not the last date of that month.

• Do you have a more precise definition for "one and a half year"? Is it 365 + floor/ceiling(365/2) (and sometimes with a 366) or is it a fixed number of days or is it from Jan1 – Jun 30 (next year), regardless of how many days are in Feb? – rm -rf Mar 1 '14 at 12:02
• +1 for DayRange – Chris Degnen Mar 1 '14 at 12:12
• Have a look at the edit I have done. – ALEXANDER Mar 1 '14 at 15:44
• @ALEXANDER I would suggest that you rephrase your question by using different units. Instead of "Year" use "Quarter". dlist = DayRange[{1999, 1, 1}, {2014, 2, 6}]; DateDifference[First[dlist], Last[dlist], "Quarter"]; Your problem is restated as partitions of 6 quarters, offset by 2 quarters. For example DatePlus[DatePlus[First[dlist], {6, "Quarter"}], {-1, "Day"}] – Hans Mar 1 '14 at 21:31
• Looks like an answer has been accepted. But I still believe the definitions in the question are incorrect. It sound like the poster is dealing with business day data. Business love their quarters. So what would this do: Partition[ Map[Function[DateString[#, {"Year", "Quarter"}]], DateRange[{1999, 1, 1}, {2014, 2, 6}, "Quarter"]], 6, 2, {1, 1}, Missing[]] – Hans Mar 2 '14 at 17:00

As rm-rf observes there are a number of possible definitions of half-year. In the following I assume you mean January 1 to June 30 vs July 1 to December 31 (with incomplete last year).

ans = Flatten[
Table[{DayRange[{j, 1, 1}, {j, 6, 30}],
DateRange[{j, 7, 1}, {j, 12, 31}]}, {j, 1999, 2014}], 1];
res = ans[[1 ;; -3]]~Join~{ans[[-2]][[1 ;; 37]]};


Your groupings are in res.

Visualizing:

UPDATE

I am still somewhat uncertain regarding exactly what is desired. If the desire is to filter/ pigeon-hole data into 'six month' bins then AbsoluteTime would be helpful. I post the following as motivation and example. There ae almost certainly more efficient ways. I currently do not have time to refine. If this is still not what is desired I suggest posting a small testdata set and desired result.

I further suggest you look at this post as you may be able to exploit some of the functionality of TemporalData objects.

dateinterv =
Table[Interval[AbsoluteTime /@ {{j, 1, 1}, {j, 6, 30}}], {j, 1999,
2014}]~Join~
Table[Interval[AbsoluteTime /@ {{j, 6, 1}, {j, 12, 31}}], {j, 1999,
2014}];
filter[u_] :=
GatherBy[SortBy[u, #[[1]] &],
Map[Function[x, IntervalMemberQ[x, AbsoluteTime[#[[1]]]]],
dateinterv] &]


The dateinterv sets up pigeon-holes and the filter function performs filtering (in this case assuming date is first column of dataset.

Test data:

testdata =
Thread[{First /@ (RandomSample[#, 1] & /@
res[[RandomInteger[{1, Length[res]}, 50]]]),
RandomInteger[{1, 10}, 50]}];


This is a set of dates and 'values' from the full range.

e.g.

{{{2008, 5, 8}, 7}, {{2008, 1, 9}, 7}, {{2008, 9, 13},
2}, {{2006, 9, 30}, 6}, {{2012, 10, 28}, 1}, {{2006, 3, 7},
7}, {{2000, 2, 10}, 10}, {{2002, 8, 10}, 9}, {{2000, 3, 31},
3}, {{2010, 4, 1}, 10}, {{1999, 2, 16}, 8}, {{2000, 12, 11},
3}, {{2000, 9, 11}, 4}, {{2001, 10, 15}, 9}, {{2008, 7, 22},
9}, {{2010, 9, 7}, 5}, {{1999, 9, 10}, 2}, {{2012, 4, 5},
5}, {{2011, 1, 5}, 1}, {{2013, 5, 21}, 2}, {{2000, 5, 1},
2}, {{2009, 7, 29}, 8}, {{2011, 2, 6}, 4}, {{2004, 10, 19},
1}, {{2006, 4, 24}, 7}, {{2000, 2, 20}, 3}, {{2014, 1, 20},
2}, {{2009, 4, 13}, 5}, {{2010, 7, 19}, 8}, {{2011, 5, 2},
1}, {{2011, 11, 2}, 6}, {{2006, 2, 3}, 7}, {{2004, 9, 10},
3}, {{2013, 3, 15}, 4}, {{2001, 6, 22}, 1}, {{2012, 9, 22},
5}, {{2013, 2, 28}, 7}, {{2011, 4, 18}, 6}, {{2000, 2, 19},
2}, {{2008, 12, 3}, 5}, {{2006, 5, 25}, 5}, {{2007, 8, 18},
3}, {{2003, 1, 20}, 6}, {{2007, 11, 3}, 1}, {{2006, 11, 26},
6}, {{2012, 3, 24}, 2}, {{2002, 1, 14}, 2}, {{2002, 3, 9},
5}, {{2001, 3, 24}, 9}, {{2011, 12, 22}, 6}};


Applying filter:

filter[testdata]


gives:

{{{{1999, 2, 16}, 8}}, {{{1999, 9, 10}, 2}}, {{{2000, 2, 10},
10}, {{2000, 2, 19}, 2}, {{2000, 2, 20}, 3}, {{2000, 3, 31},
3}, {{2000, 5, 1}, 2}}, {{{2000, 9, 11}, 4}, {{2000, 12, 11},
3}}, {{{2001, 3, 24}, 9}}, {{{2001, 6, 22}, 1}}, {{{2001, 10, 15},
9}}, {{{2002, 1, 14}, 2}, {{2002, 3, 9}, 5}}, {{{2002, 8, 10},
9}}, {{{2003, 1, 20}, 6}}, {{{2004, 9, 10}, 3}, {{2004, 10, 19},
1}}, {{{2006, 2, 3}, 7}, {{2006, 3, 7}, 7}, {{2006, 4, 24},
7}, {{2006, 5, 25}, 5}}, {{{2006, 9, 30}, 6}, {{2006, 11, 26},
6}}, {{{2007, 8, 18}, 3}, {{2007, 11, 3}, 1}}, {{{2008, 1, 9},
7}, {{2008, 5, 8}, 7}}, {{{2008, 7, 22}, 9}, {{2008, 9, 13},
2}, {{2008, 12, 3}, 5}}, {{{2009, 4, 13}, 5}}, {{{2009, 7, 29},
8}}, {{{2010, 4, 1}, 10}}, {{{2010, 7, 19}, 8}, {{2010, 9, 7},
5}}, {{{2011, 1, 5}, 1}, {{2011, 2, 6}, 4}, {{2011, 4, 18},
6}, {{2011, 5, 2}, 1}}, {{{2011, 11, 2}, 6}, {{2011, 12, 22},
6}}, {{{2012, 3, 24}, 2}, {{2012, 4, 5}, 5}}, {{{2012, 9, 22},
5}, {{2012, 10, 28}, 1}}, {{{2013, 2, 28}, 7}, {{2013, 3, 15},
4}, {{2013, 5, 21}, 2}}, {{{2014, 1, 20}, 2}}}


Facilitating visualization of the partitioning:

• This is great however could you see my edit and see if you are able to come up with an example? – ALEXANDER Mar 1 '14 at 15:27
• @ALEXANDER see edit – ubpdqn Mar 2 '14 at 6:18
• Perfect thank you! – ALEXANDER Mar 2 '14 at 14:40