-3

Given a start and end DateTime how can i get the most complete intervals in terms of "natural" years, months, days, instantaneous ?

Thanks for your help!

[TestMethod]
    public void MoreThanOneYear()
    {
        var start = new DateTime(2013, 1, 5, 2, 0, 0);
        var end = new DateTime(2015, 5, 5, 19, 0, 0);

        var intervals = DateTimeUtis.GetPeriods(start, end).ToList();

        Assert.IsTrue(intervals.Count() == 7);

        Assert.IsTrue(intervals[0].Granularity == Granularity.Instantaneous);
        Assert.IsTrue(intervals[0].Interval.Start == new DateTime(2013, 1, 5, 2, 0, 0));
        Assert.IsTrue(intervals[0].Interval.End == new DateTime(2013, 1, 6, 0, 0, 0));

        Assert.IsTrue(intervals[1].Granularity == Granularity.Daily);
        Assert.IsTrue(intervals[1].Interval.Start == new DateTime(2013, 1, 6, 0, 0, 0));
        Assert.IsTrue(intervals[1].Interval.End == new DateTime(2013, 2, 1, 0, 0, 0));

        Assert.IsTrue(intervals[2].Granularity == Granularity.Montly);
        Assert.IsTrue(intervals[2].Interval.Start == new DateTime(2013, 2, 1, 0, 0, 0));
        Assert.IsTrue(intervals[2].Interval.End == new DateTime(2014, 1, 1, 0, 0, 0));

        Assert.IsTrue(intervals[3].Granularity == Granularity.Yearly);
        Assert.IsTrue(intervals[3].Interval.Start == new DateTime(2014, 1, 1, 0, 0, 0));
        Assert.IsTrue(intervals[3].Interval.End == new DateTime(2015, 1, 1, 0, 0, 0));

        Assert.IsTrue(intervals[4].Granularity == Granularity.Montly);
        Assert.IsTrue(intervals[4].Interval.Start == new DateTime(2015, 1, 1, 0, 0, 0));
        Assert.IsTrue(intervals[4].Interval.End == new DateTime(2015, 5, 1, 0, 0, 0));

        Assert.IsTrue(intervals[5].Granularity == Granularity.Daily);
        Assert.IsTrue(intervals[5].Interval.Start == new DateTime(2015, 5, 1, 0, 0, 0));
        Assert.IsTrue(intervals[5].Interval.End == new DateTime(2015, 5, 5, 0, 0, 0));

        Assert.IsTrue(intervals[6].Granularity == Granularity.Instantaneous);
        Assert.IsTrue(intervals[6].Interval.Start == new DateTime(2015, 5, 5, 0, 0, 0));
        Assert.IsTrue(intervals[6].Interval.End == new DateTime(2015, 5, 5, 19, 0, 0));
    }

Edit

What I'm trying to achieve is to the get the biggest adjacent intervals possible between the two dates. Complete years interval > Months > Days > Instantaneous.

Edit 2

The business scenario is that I have an SQL table with raw data with a 1 minute frequency and 3 other tables with consolidated data (by year, month and day). So for a start and end date I need to get the date, time intervals that allow me to optimize the queries. If I have full years between the start and end date I can get data from the consolidate year table, if not, I try to get data from the month's table and so on.

Jon
  • 1
  • 2
  • Not terribly clear what you're asking. Does DateTime's `.Subtract()` method not do what you want? – Arin Jul 27 '15 at 21:15
  • possible duplicate of [Difference in months between two dates](http://stackoverflow.com/questions/4638993/difference-in-months-between-two-dates) – Alex Netkachov Jul 27 '15 at 21:19
  • Subtract will give the Time Span between the two dates, not the periods I'm looking for. I added the test with the hope it would explain better than my words :) – Jon Jul 27 '15 at 21:22
  • Maybe this is what you are looking for: https://github.com/MehdiK/Humanizer#humanize-timespan – Alex Netkachov Jul 27 '15 at 21:57
  • Not quite, but that's a really cool string extension collection :) I think my last edit explains better what I'm trying to do. – Jon Jul 28 '15 at 04:49

1 Answers1

2

Generally, you cannot. Simply because there is no standard for year and month. The best approximation you can do is to decide what will be the most appropriate year in your case (365 days, 365.25 days, or maybe some other rule) and use TimeSpan.TotalDays/numberOfDaysInYear.

See also: Difference in months between two dates

Community
  • 1
  • 1
Alex Netkachov
  • 13,172
  • 6
  • 53
  • 85