Question

What is the C# optimised version of the following, without using .Net's Timespan or DateTime. How would I NUnit test it?

TimeSpan ts = Date1 - Date2;
int numberOfDays = ts.Days;
Was it helpful?

Solution

You could convert the dates to ticks, substract, then convert the ticks back to days. Though exactly why can't you use TimeSpan? It's likely doing just that.

Something like this:

      DateTime a = DateTime.Now;
      DateTime b = a.AddDays(2);

      // ticks are in hns
      long ticks = b.Ticks - a.Ticks;
      long seconds = ticks / 10000000;
      long minutes = seconds / 60;
      long hours = minutes / 60;
      long days = hours / 24;

I get back "2" for days.

OTHER TIPS

Date1 and Date2 are what type? In your exameple it looks to be DateTime. You want your Date in what variable if it's not DateTime? You can always have your Date1 and Date2 in String and play with SubString() to get Year, Month and days but that would be a real pain to work with.

The optimized way to do your problem of:

TimeSpan ts = Date1 - Date2;
int numberOfDays = ts.Days;

is

DateTime Date1 = new DateTime(2008,12,01);
DateTime Date2 = new DateTime(2008,12,25);
int numberOfDayBetweenDateThatShouldBe = 25;
Assert.IsTrue((Date2-Date1).TotalDays == numberOfDayBetweenDateThatShouldBe);

thanks, this is homework (asp.net)

The task is to write an asp.net application in c# that takes 2 dates as input from the user, works out the number of days between them and displays that number back to the user. This should not use any of the in-built .net framework DateTime or TimeSpan classes.

and alas my most elegant implementation at production strength

private int CalculateDays(DateTime start, DateTime end )
{
   DateTime origin = new DateTime(); 
   return (end - origin).Days - (start - origin).Days;
}

protected void Button1_Click(object sender, EventArgs e)
{
    // Parse dates for correctness and range errors, warn as necessary
    DateTime start;
    DateTime end;

    // rough error implement error handling implementation   
    string errors = string.Empty;

         if(!DateTime.TryParse(txt_start_date.Text.Trim(), out start))   errors+="Start date was incorrect";
    else if(!DateTime.TryParse(txt_end_date.Text.Trim(), out end))   errors+= (errors.Length>0? errors+= "\n":"") + "End date was incorrect" ; 
    else if ((end.Day - start.Day) <= 0) errors+= (errors.Length>0? errors+= "\n":"" ) + "End date must be greater than the Start date" ;         //CultureInfo.InvariantCulture
    else 
    {
        Response.Write(CalculateDays(start, end)); 
    }
    Debug.Assert(errors.Length <= 0, errors); 
}

Reason being am unable to see how to do this without touching DateTime.Days at least.


edit okay thought over again and a bit of monkey work, however, no use of DateTime or Timespan anywhere

public static class PrimitiveCal
{
    // incremental total days a normal year 
    private static int[] DaysInYr = new int[] {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };

    // incremental total days in a leap year 
    private static int[] DaysInLeapYr = new int[] { 0,31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };


    public static long GetDays(int[] dt_start, int[] dt_end)
    {

        int day_diff = dt_end[0] - dt_start[0];
        int s_mth = dt_start[1];
        int e_mth = dt_end[1];
        int s_year = dt_start[2];
        int e_year = dt_end[2];
        int yr_diff = e_year - s_year;

        return day_diff + (yr_diff > 0 ?
                         // use months as boundaries, cater for leap years
                         (YrType(e_year)[e_mth - 1] +
                         (YrType(s_year)[YrType(s_year).Length - 1] - YrType(s_year)[s_mth - 1])) +
                         (yr_diff == 1 ? 0 : AddMiddleYears(s_year, e_year))

                         // get month sums in same year 
                         : YrType(e_year)[e_mth - 1] - YrType(e_year)[s_mth - 1]);
    }

    private static int AddMiddleYears(int s_year, int e_year)
    {
        int total_days = 0;
        for (int i = s_year + 1; i <= e_year - 1; i++) total_days += YrType(i)[YrType(i).Length - 1];
        return total_days;
    }

    private static int[] YrType(int year)
    {
        return (year % 4  == 0 &&  year%100!=0) || year % 400 ==0 ? DaysInLeapYr : DaysInYr;
    }
}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top