Home > database >  How to get BiAnnual between two dates using C#. NET
How to get BiAnnual between two dates using C#. NET

Time:01-21

In my C# ASP.NET Core I am trying to get Months, Quarters, BiAnnual (number of 6 months) and Years between two dates (StartDate and EndDate).

I have done TotalMonths, TotalQuarters, TotalYears as shown below and its working:

public static int GetTotalMonth(DateTime startDate, DateTime endDate)
{
    int totalMonth = 12 * (startDate.Year - endDate.Year)   startDate.Month - endDate.Month;
    return Convert.ToInt32(Math.Abs(totalMonth));
}

public static int GetTotalQuarter(DateTime startDate, DateTime endDate)
{
    int firstQuarter = getQuarter(startDate);
    int secondQuarter = getQuarter(endDate);
    return 1   Math.Abs(firstQuarter - secondQuarter);
}

private static int getQuarter(DateTime date)
{
    return (date.Year * 4)   ((date.Month - 1) / 3);
}

public static int GetTotalYear(DateTime startDate, DateTime endDate)
{
    int years = endDate.Year - startDate.Year;

    if (startDate.Month == endDate.Month &&
        endDate.Day < startDate.Day)
    {
        years--;
    }
    else if (endDate.Month < startDate.Month)
    {
        years--;
    }
    return Math.Abs(years);
}

Where I have issue is how to get BiAnnual:

public static int GetTotalBiAnnual(DateTime startDate, DateTime endDate)
{
    return;
}

How do I go about it?

CodePudding user response:

When calculating differences between two dates you normally use the TimeSpan class. This class however does not have Month and Year which has led me to create a class called TimeSpanWithYearAndMonth.

public TimeSpanWithYearAndMonth(DateTime startDate, DateTime endDate)
{
    var span = endDate - startDate;

    TotalMonths = 12 * (endDate.Year - startDate.Year)   (endDate.Month - startDate.Month);
    Years = TotalMonths / 12;
    Months = TotalMonths - (Years * 12);

    if (Months == 0 && Years == 0)
    {
        Days = span.Days;
    }
    else
    {
        var startDateExceptYearsAndMonths = startDate.AddYears(Years);
        startDateExceptYearsAndMonths = startDateExceptYearsAndMonths.AddMonths(Months);
        Days = (endDate - startDateExceptYearsAndMonths).Days;
    }

    Hours = span.Hours;
    Minutes = span.Minutes;
    Seconds = span.Seconds;
}

public int Minutes { get; }
public int Hours { get; }
public int Days { get; }
public int Years { get; }
public int Months { get; }
public int Seconds { get; }
public int TotalMonths { get; }
public int TotalHalfYears => TotalMonths / 6;

I extended it with TotalHalfYears ("bi annual") using a simple integer division (you can of course use only this part with your existing TotalMonths calculation if you like).

Here are some unit tests to demonstrate how it works;

[TestFixture]
public class TimeSpanWithYearAndMonthTests
{
    [Test]
    public void Calculates_correctly()
    {
        new TimeSpanWithYearAndMonth(new DateTime(2019, 5, 1), new DateTime(2019, 5, 2)).Days.Should().Be(1);

        new TimeSpanWithYearAndMonth(new DateTime(2019, 5, 28), new DateTime(2020, 5, 28)).Years.Should().Be(1);

        new TimeSpanWithYearAndMonth(new DateTime(2019, 5, 28), new DateTime(2021, 5, 28)).Years.Should().Be(2);

        new TimeSpanWithYearAndMonth(new DateTime(2019, 5, 28), new DateTime(2021, 5, 28)).Years.Should().Be(2);

        new TimeSpanWithYearAndMonth(new DateTime(2019, 1, 1), new DateTime(2021, 1, 1)).TotalHalfYears.Should().Be(4);
        new TimeSpanWithYearAndMonth(new DateTime(2019, 1, 1), new DateTime(2021, 1, 2)).TotalHalfYears.Should().Be(4);
        new TimeSpanWithYearAndMonth(new DateTime(2019, 1, 1), new DateTime(2021, 6, 1)).TotalHalfYears.Should().Be(4);
        new TimeSpanWithYearAndMonth(new DateTime(2019, 1, 1), new DateTime(2021, 7, 1)).TotalHalfYears.Should().Be(5);

        var span = new TimeSpanWithYearAndMonth(new DateTime(2019, 5, 28), new DateTime(2021, 8, 28));
        span.Years.Should().Be(2);
        span.Months.Should().Be(3);
        span.TotalMonths.Should().Be(27);

        span = new TimeSpanWithYearAndMonth(new DateTime(2010, 5, 28), new DateTime(2020, 5, 29));
        span.Years.Should().Be(10);
        span.Months.Should().Be(0);
        span.Days.Should().Be(1);
        span.TotalMonths.Should().Be(120);
    }
}

CodePudding user response:

I assume from your existing code that you need to calculate from which biannual the startDate and endDate are in and calculate the difference. The code can be similar to GetTotalQuarter like this

public static int GetTotalBiannual(DateTime startDate, DateTime endDate)
{
    int first = GetBiannual(startDate);
    int second = GetBiannual(endDate);
    return 1   Math.Abs(first - second);
}

private static int GetBiannual(DateTime date)
{
    return (date.Year * 2)   ((date.Month - 1) / 6);
}

CodePudding user response:

I would suggest that instead of calculating this yourself, you use NodaTime library instead.

Then you can do something like this:

Period period = Period.Between(start, end, PeriodUnits.Months);

This will then work for various different periods of time. You can wrap this in your own class if it is easier for you.

For your BiAnnual, then you can expand this to take the period Month value and round down for 6 month periods.

CodePudding user response:

Try

Math.Floor(GetTotalMonth(startDate, endDate) / 6)

you also have coded a function that does half your work, use it ;)

  •  Tags:  
  • Related