Timespan difference not calculating correctly - c#

I am building a web form in C#. I have 3 drops downs for Start Time (Start Hour, Start Minute, and Start Time of Day (AM or PM) and 3 for finish time. My goal is to calculate the difference. Everything works fine until I choose noon or midnight. When I choose noon and debug, the value shows as 1. Here is my code.
var startHourDDL = ddlStartHour.SelectedValue;
var startMinuteDDL = ddlStartMinute.SelectedValue;
var startTOD = ddlStartTOD.SelectedValue;
int startHour = Convert.ToInt32(startHourDDL);
int startMinute = Convert.ToInt32(startMinuteDDL);
var finishHourDDL = ddlFinishHour.SelectedValue;
var finishMinuteDDL = ddlFinishMinute.SelectedValue;
var finishTOD = ddlFinishTOD.SelectedValue;
int finishHour = Convert.ToInt32(finishHourDDL);
int finishMinute = Convert.ToInt32(finishMinuteDDL);
if (startTOD == "PM")
{
startTime = new TimeSpan(startHour + 12, startMinute, 0);
}
else
{
startTime = new TimeSpan(startHour, startMinute, 0);
}
if (finishTOD == "PM")
{
finishTime = new TimeSpan(finishHour + 12, finishMinute, 0);
}
else
{
finishTime = new TimeSpan(finishHour, finishMinute, 0);
}
TimeSpan diff = finishTime - startTime;
string time = String.Format(diff.Hours + " Hours, " + diff.Minutes + " Minutes");
lblDurAmount.Text = time;
So if I choose 2:00 PM for start time and 4:00 PM for finish time, the label shows 2 hours. However, if I choose 12:00 PM for start time and 2:00 PM for finish time I get -10 hours.
This is what I get for start time when I debug at 12:00 PM.
{1.00:00:00}
Here is what I get when I choose 5:00 PM
{17:00:00}
I can't figure out why it won't set noon to 24. I even tried adding an if statement
if (startHour == 12 && startTOD)
{
startTime = new TimeSpan(24, startMinute, 0);
}
But that didn't work either. Value was still 1.00.

A TimeSpan is for storing a duration of time, not a time during the day.
As such, while you believe you are storing "12PM", what you are actually storing is a 24 hour time period. And "2PM" is a 14 hour time period.
Thus "2PM" - "12PM" = 14 hours - 24 hours (i.e. -10 hours).
To solve this, you need to store date/time in DateTime, not TimeSpan.

Your operations works only if the startTime is less than the finishTime otherwise all the results will come back as negatives. In your example 12 PM comes after 2 PM so when you subtract 2 PM - 12 PM you get then -10 hours.
You need to check if startTime is after finishTime and swap the two values if true
if (finishTime < startTime)
{
TimeSpan swap = finishTime;
finishTime = startTime;
startTime = swap;
}
TimeSpan diff = finishTime - startTime;
string time = String.Format(diff.TotalHours + " Hours, " + diff.Minutes + " Minutes");

Related

Seconds left for the time in the future?

I have the following Code:
var enteredDate = Convert.ToDateTime("17:45");
var todaysDateTime = DateTime.Now;
var span = enteredDate.Subtract(todaysDateTime);
double totalMins = Math.Ceiling(span.TotalMinutes);
string timeCond;
if (totalMins > 0)
{
if (totalMins < 5)
{
timeCond = Math.Ceiling(span.TotalSeconds) + " seconds left.";
}
else
{
timeCond = totalMins + " minutes left.";
}
}
Given that the time now would be 17:50 the returned second would be a negative figure, I would like to be able to return the seconds or minutes in relation to the code for the next time the time would be 17:45, is this possible?
You could always just add a day:
var span = enteredDate - todaysDateTime;
if (span < TimeSpan.Zero)
{
span += TimeSpan.FromDays(1);
}
(Note that this assumes there are 24 hours between today's 17:45 and tomorrow's 17:45. That isn't true around daylight saving transitions; accommodating for that is feasible, but would make life somewhat more complicated.)
try
var span = Convert.ToDateTime("17:45") > DateTime.Now ? Convert.ToDateTime("17:45") - DateTime.Now : Convert.ToDateTime("17:45").AddDays(1) - DateTime.Now

Find time occurence and duration in certain time range

I made a little parking application in C#. There are some different pricings depending on vehicle type and time zone. Day can be divided into time zones (for example morning, day, evening and night). Now if customer stops parking I want to calculate in which time zones customer has parked and how long.
For example morning time zone starts at 6:00 and ends 12:00, day time zone starts at 12:00 and ends 16:00, evening time zone starts at 16:00 and ends at 23:00 and night time zone starts at 23:00 and ends at 6:00. Customer started parking his car at 00:30 and ends parking at 6:32. Currently I have 4 variables for that: parking start time, parking end time and timezone starting time and timezone ending time.
Second example would be like customer parks 24H, then the parking time has all time zones covered.
How is the simplest way to calculate how many hours and minutes customer parked his car in different time zones?
Regards,
evilone
EDIT:
Got this answer from MSDN and post it here so others can learn from it too.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DateTime start = new DateTime(2011, 7, 25, 0, 30, 0);
DateTime end = new DateTime(2011, 7, 26, 6, 32, 0);
List<DateTime> listTimeZones = CalculateTotalTime(start, end);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < listTimeZones.Count; i++)
{
sb.AppendLine(String.Format("{0}. {1}: from {2} to {3}",
i + 1,
GetZoneInWords(listTimeZones[i].Hour),
String.Format("{0:dd.MM.yyyy hh:mm}", listTimeZones[i]),
(i + 1) < listTimeZones.Count
? String.Format("{0:dd.MM.yyyy hh:mm}", listTimeZones[i + 1])
: "Parking ended"));
}
MessageBox.Show(sb.ToString());
}
private List<DateTime> CalculateTotalTime(DateTime start, DateTime end)
{
DateTime temp = start;
int hour = start.Hour;
int minute = start.Minute;
int morning = 6;
int day = 12;
int evening = 17;
int night = 23;
List<DateTime> timeZones = new List<DateTime>();
do
{
temp = temp.AddHours(1);
if (temp.Hour == morning || temp.Hour == day ||
temp.Hour == evening || temp.Hour == night)
{
timeZones.Add(temp);
}
} while (temp < end);
return timeZones;
}
private string GetZoneInWords(int time)
{
string timeOfDay = "";
if (time.Equals(6))
timeOfDay = "Morning";
else if (time.Equals(12))
timeOfDay = "Day";
else if (time.Equals(17))
timeOfDay = "Evening";
else if (time.Equals(23))
timeOfDay = "Night";
return timeOfDay + " parking";
}
}
Iterate through all the "time zones" and for each, work out the overlap between that and the customer's parking. For example, as pseudo-code:
private static TimeSpan FindOverlap(ParkingTime parkingTime, TimeZone timeZone)
{
// Handle wraparound zones like 23-6. Note that this doesn't attempt
// to handle *parking* which starts at 11.30pm etc.
if (timeZone.Start > timeZone.End)
{
return FindOverlap(parkingTime,
new TimeZone(timeZone.Start.Date, timeZone.End)
+ FindOverlap(parkingTime,
new TimeZone(timeZone.End, timeZone.Start.Date.AddDays(1));
}
DateTime overlapStart = Max(parkingTime.Start, timeZone.Start);
DateTime overlapEnd = Min(parkingTime.End, timeZone.End);
TimeSpan overlap = overlapEnd - overlapStart;
// If the customer arrived after the end or left before the start,
// the overlap will be negative at this point.
return overlap < TimeSpan.Zero ? TimeSpan.Zero : overlap;
}
private static DateTime Min(DateTime x, DateTime y)
{
return x < y ? x : y;
}
private static DateTime Max(DateTime x, DateTime y)
{
return x > y ? x : y;
}
By the way, I would strongly encourage you to rename your "time zone" concept, given that it already has a well-known (if not well-understood :) meaning.
Perhaps you should call it ParkingInterval? Or ParkingPriceInterval if the difference is really in terms of cost?

How to Compare DateTime C# Months and weeks

I need to compare a date in C#
if the date is less than 12 months,i need to set a boolean value
My Code is
String d = "26/06/10";
DateTime dt = DateTime.ParseExact(d, "dd/MM/yy", null);
if ((dt > DateTime.Now.AddMonths(-12) ) )
{
Console.WriteLine("It is less than 12 months");
}
else
{
Console.WriteLine("It is more than 12 months");
}
Is the best way to compare date in c#.
similarly i need to compare date is less than two weeks or not
Any help appreciated
Thanks
sup
You could use TimeSpan to get the difference between two DateTime values
String d = "26/06/10";
DateTime dt = DateTime.ParseExact(d, "dd/MM/yy", null);
DateTime dt2 = DateTime.Now.AddMonths(-12);
TimeSpan ts = dt - dt2;
You can use ts.Days to compare
You could do
DateTime date2 = DateTime.Now.AddMonths(-12);
//Or if you want to neglect the time part you could do
DateTime date2 = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,0,0,0).AddMonths(-12);
String d = "26/06/10";
DateTime date1 = DateTime.ParseExact(d, "dd/MM/yy", null);
int result = DateTime.Compare(date1, date2);
string res;
if (result < 0)
Console.WriteLine("It is less than 12 months");
else if (result == 0)
res = "is the equal";
else
Console.WriteLine("It is more than 12 months");
The problem with your code snippet is that it will output "It is more than 12 months" even if the date is equal.
For two weeks:
if (dt1.Subtract(dt2).Days > 14)
{
...
}
For 12 Months(one year) (Considering day of the month is not important):
var monthDifference = ((dt1.Year - dt2.Year) * 12) + dt1.Month - dt2.Month
For a clearer understanding: you do not want to compare two dates (or DateTimes) but two TimeSpans. Namely the difference in time between now and the date you supplied - and the a time span of 12 months.
String d = "26/06/10";
DateTime dt = DateTime.ParseExact(d, "dd/MM/yy", CultureInfo.InvariantCulture);
TimeSpan deltaTimeSpan = dt - DateTime.Now; // get the time difference between now and the time given
TimeSpan twelveMonths = new TimeSpan(365,0,0,0); // get a time span of 12 months
// round the amount of days down and always supply a positive number of days
int deltaTime = Convert.ToInt32(Math.Abs(Math.Floor(deltaTimeSpan.TotalDays)));
if (twelveMonths.TotalDays > deltaTime)
{
Console.WriteLine(string.Format("It is less than 12 months ({0} days).", deltaTime));
}
else if (twelveMonths.TotalDays < deltaTime)
{
Console.WriteLine(string.Format("It is more than 12 months ({0} days).", deltaTime));
}
else
{
Console.WriteLine(string.Format("The difference in time is exactly 12 months. ({0} days).", deltaTime);
}
Take note that this example certainly does not take in account leap years. The code does take in account weather the year to compare with lies in the past or the future (by converting the TimeSpan into a positive value and comparing against that one).
Adjusting the above code to do the same for two weeks or any other time span should be simple enough. Just change the TimeSpan I named "twelveMonths".
DateTime date1 = DateTime.Now.AddMonths(-12)
if(DateTime.Compare(dt, date1 )
{
//provided date is within 12 months
}
else
{
//provided date is after 12 months
}

Converting AM/PM time to standard time format hh:mm in C#

In my ASP.NET web form I have 3 fields - hour, minute and am/pm drop down. How can I get the values of those 3 fields into one variable and then convert the am/pm hour to standard 24 hour time like 05:20PM = 17:20. This needs to be done in C#.
Thanks for the help beforehand.
var hour = int.Parse(ddlHour.SelectedValue);
var min = int.Parse(ddlMin.SelectedValue);
var ampm = ddlAmPm.SelectedValue;
hour = ampm == "AM" ? hour : (hour % 12) + 12; //convert 12-hour time to 24-hour
var dateTime = new DateTime(0,0,0, hour, min, 0);
var timeString = dateTime.ToString("HH:mm");
Are you saying your starting out with separate values for hour, minute, and am/pm?
public string Get24HourTime(int hour, int minute, string ToD)
{
int year = DateTime.Now.Year;
int month = DateTime.Now.Month;
int day = DateTime.Now.Day;
if (ToD.ToUpper() == "PM") hour = (hour % 12) + 12;
return new DateTime(year, month, day, hour, minute, 0).ToString("HH:mm");
}
You can put dummy year, month and day if only time is needed.
DateTime time = new DateTime(year, month, day, hour, minute, second);
string time = time.ToString("HH:mm");
string hour = hourField.Text
string minute = minuteField.Text
string AMPM = ddl.SelectedItem.ToString();
//AMPM is either "AM" or "PM"
timeString = hour + ":" + minute + " " + AMPM
//the procued string in timeString is e.g. "10:45 PM"
DateTime time = DateTime.Parse(timeString);
You have to observe that 12:00AM is midnight and should produce 00:00. The fact that 12:00AM is one hour before 1:00AM, using modulo you would have to do it like:
if(hour == 12)hour = 0;
if(AMPM == "PM") hour = (hour % 12) + 12;

How to calculate actual months difference (calendar year not approximation) between two given dates in C#?

Example: given two dates below, finish is always greater than or equal to start
start = 2001 Jan 01
finish = 2002 Mar 15
So from 2001 Jan 01 to the end of 2002 Feb
months = 12 + 2 = 14
For 2002 March
15/30 = 0.5
so grand total is 14.5 months difference.
It's very easy to work out by hand but how do I code it elegantly? At the moment I have the combination of a lot of if else and while loops to achieve what I want but I believe there are simpler solutions out there.
Update: the output needs to be precise (not approximation) for example:
if start 2001 Jan 01 and finish 2001 Apr 16, the output should be 1 + 1 + 1= 3 (for Jan, Feb and Mar) and 16 / 31 = 0.516 month, so the total is 3.516.
Another example would be if I start on 2001 Jul 5 and finish on 2002 Jul 10, the output should be 11 month up to the end of June 2002, and (31-5)/31 = 0.839 and 10/31 = 0.323 months, so the total is 11 + 0.839 + 0.323 = 12.162.
I extended Josh Stodola's code and Hightechrider's code:
public static decimal GetMonthsInRange(this IDateRange thisDateRange)
{
var start = thisDateRange.Start;
var finish = thisDateRange.Finish;
var monthsApart = Math.Abs(12*(start.Year - finish.Year) + start.Month - finish.Month) - 1;
decimal daysInStartMonth = DateTime.DaysInMonth(start.Year, start.Month);
decimal daysInFinishMonth = DateTime.DaysInMonth(finish.Year, finish.Month);
var daysApartInStartMonth = (daysInStartMonth - start.Day + 1)/daysInStartMonth;
var daysApartInFinishMonth = finish.Day/daysInFinishMonth;
return monthsApart + daysApartInStartMonth + daysApartInFinishMonth;
}
I gave an int answer before, and then realized what you asked for a more precise answer. I was tired, so I deleted and went to bed. So much for that, I was unable to fall asleep! For some reason, this question really bugged me, and I had to solve it. So here you go...
static void Main(string[] args)
{
decimal diff;
diff = monthDifference(new DateTime(2001, 1, 1), new DateTime(2002, 3, 15));
Console.WriteLine(diff.ToString("n2")); //14.45
diff = monthDifference(new DateTime(2001, 1, 1), new DateTime(2001, 4, 16));
Console.WriteLine(diff.ToString("n2")); //3.50
diff = monthDifference(new DateTime(2001, 7, 5), new DateTime(2002, 7, 10));
Console.WriteLine(diff.ToString("n2")); //12.16
Console.Read();
}
static decimal monthDifference(DateTime d1, DateTime d2)
{
if (d1 > d2)
{
DateTime hold = d1;
d1 = d2;
d2 = hold;
}
int monthsApart = Math.Abs(12 * (d1.Year-d2.Year) + d1.Month - d2.Month) - 1;
decimal daysInMonth1 = DateTime.DaysInMonth(d1.Year, d1.Month);
decimal daysInMonth2 = DateTime.DaysInMonth(d2.Year, d2.Month);
decimal dayPercentage = ((daysInMonth1 - d1.Day) / daysInMonth1)
+ (d2.Day / daysInMonth2);
return monthsApart + dayPercentage;
}
Now I shall have sweet dreams. Goodnight :)
What you want is probably something close to this ... which pretty much follows your explanation as to how to calculate it:
var startofd1 = d1.AddDays(-d1.Day + 1);
var startOfNextMonthAfterd1 = startofd1.AddMonths(1); // back to start of month and then to next month
int daysInFirstMonth = (startOfNextMonthAfterd1 - startofd1).Days;
double fraction1 = (double)(daysInFirstMonth - (d1.Day - 1)) / daysInFirstMonth; // fractional part of first month remaining
var startofd2 = d2.AddDays(-d2.Day + 1);
var startOfNextMonthAfterd2 = startofd2.AddMonths(1); // back to start of month and then to next month
int daysInFinalMonth = (startOfNextMonthAfterd2 - startofd2).Days;
double fraction2 = (double)(d2.Day - 1) / daysInFinalMonth; // fractional part of last month
// now find whole months in between
int monthsInBetween = (startofd2.Year - startOfNextMonthAfterd1.Year) * 12 + (startofd2.Month - startOfNextMonthAfterd1.Month);
return monthsInBetween + fraction1 + fraction2;
NB This has not been tested very well but it shows how to handle problems like this by finding well known dates at the start of months around the problem values and then working off them.
While loops for date time calculations are always a bad idea: see http://www.zuneboards.com/forums/zune-news/38143-cause-zune-30-leapyear-problem-isolated.html
Depending on how exactly you want your logic to work, this would at least give you a decent approximation:
// 365 days per year + 1 day per leap year = 1461 days every 4 years
// But years divisible by 100 are not leap years
// So 1461 days every 4 years - 1 day per 100th year = 36524 days every 100 years
// 12 months per year = 1200 months every 100 years
const double DaysPerMonth = 36524.0 / 1200.0;
double GetMonthsDifference(DateTime start, DateTime finish)
{
double days = (finish - start).TotalDays;
return days / DaysPerMonth;
}
One way to do this is that you'll see around quite a bit is:
private static int monthDifference(DateTime startDate, DateTime endDate)
{
int monthsApart = 12 * (startDate.Year - endDate.Year) + startDate.Month - endDate.Month;
return Math.Abs(monthsApart);
}
However, you want "partial months" which this doesn't give. But what is the point in comparing apples (January/March/May/July/August/October/December) with oranges (April/June/September/November) or even bananas that are sometimes coconuts (February)?
An alternative is to import Microsoft.VisualBasic and do this:
DateTime FromDate;
DateTime ToDate;
FromDate = DateTime.Parse("2001 Jan 01");
ToDate = DateTime.Parse("2002 Mar 15");
string s = DateAndTime.DateDiff (DateInterval.Month, FromDate,ToDate, FirstDayOfWeek.System, FirstWeekOfYear.System ).ToString();
However again:
The return value for
DateInterval.Month is calculated
purely from the year and month parts
of the arguments
[Source]
Just improved Josh's answer
static decimal monthDifference(DateTime d1, DateTime d2)
{
if (d1 > d2)
{
DateTime hold = d1;
d1 = d2;
d2 = hold;
}
decimal monthsApart = Math.Abs((12 * (d1.Year - d2.Year)) + d2.Month - d1.Month - 1);
decimal daysinStartingMonth = DateTime.DaysInMonth(d1.Year, d1.Month);
monthsApart = monthsApart + (1-((d1.Day - 1) / daysinStartingMonth));
// Replace (d1.Day - 1) with d1.Day incase you DONT want to have both inclusive difference.
decimal daysinEndingMonth = DateTime.DaysInMonth(d2.Year, d2.Month);
monthsApart = monthsApart + (d2.Day / daysinEndingMonth);
return monthsApart;
}
The answer works perfectly and while the terseness of the code makes it very small I had to break everything apart into smaller functions with named variables so that I could really understand what was going on... So, basically I just took Josh Stodola's code and Hightechrider's mentioned in Jeff's comment and made it smaller with comments explaining what was going on and why the calculations were being made, and hopefully this may help someone else:
[Test]
public void Calculate_Total_Months_Difference_Between_Two_Dates()
{
var startDate = DateTime.Parse( "10/8/1996" );
var finishDate = DateTime.Parse( "9/8/2012" ); // this should be now:
int numberOfMonthsBetweenStartAndFinishYears = getNumberOfMonthsBetweenStartAndFinishYears( startDate, finishDate );
int absMonthsApartMinusOne = getAbsMonthsApartMinusOne( startDate, finishDate, numberOfMonthsBetweenStartAndFinishYears );
decimal daysLeftToCompleteStartMonthPercentage = getDaysLeftToCompleteInStartMonthPercentage( startDate );
decimal daysCompletedSoFarInFinishMonthPercentage = getDaysCompletedSoFarInFinishMonthPercentage( finishDate );
// .77 + .26 = 1.04
decimal totalDaysDifferenceInStartAndFinishMonthsPercentage = daysLeftToCompleteStartMonthPercentage + daysCompletedSoFarInFinishMonthPercentage;
// 13 + 1.04 = 14.04 months difference.
decimal totalMonthsDifference = absMonthsApartMinusOne + totalDaysDifferenceInStartAndFinishMonthsPercentage;
//return totalMonths;
}
private static int getNumberOfMonthsBetweenStartAndFinishYears( DateTime startDate, DateTime finishDate )
{
int yearsApart = startDate.Year - finishDate.Year;
const int INT_TotalMonthsInAYear = 12;
// 12 * -1 = -12
int numberOfMonthsBetweenYears = INT_TotalMonthsInAYear * yearsApart;
return numberOfMonthsBetweenYears;
}
private static int getAbsMonthsApartMinusOne( DateTime startDate, DateTime finishDate, int numberOfMonthsBetweenStartAndFinishYears )
{
// This may be negative i.e. 7 - 9 = -2
int numberOfMonthsBetweenStartAndFinishMonths = startDate.Month - finishDate.Month;
// Absolute Value Of Total Months In Years Plus The Simple Months Difference Which May Be Negative So We Use Abs Function
int absDiffInMonths = Math.Abs( numberOfMonthsBetweenStartAndFinishYears + numberOfMonthsBetweenStartAndFinishMonths );
// Subtract one here because we are going to use a perecentage difference based on the number of days left in the start month
// and adding together the number of days that we've made it so far in the finish month.
int absMonthsApartMinusOne = absDiffInMonths - 1;
return absMonthsApartMinusOne;
}
/// <summary>
/// For example for 7/8/2012 there are 24 days left in the month so about .77 percentage of month is left.
/// </summary>
private static decimal getDaysLeftToCompleteInStartMonthPercentage( DateTime startDate )
{
// startDate = "7/8/2012"
// 31
decimal daysInStartMonth = DateTime.DaysInMonth( startDate.Year, startDate.Month );
// 31 - 8 = 23
decimal totalDaysInStartMonthMinusStartDay = daysInStartMonth - startDate.Day;
// add one to mark the day as being completed. 23 + 1 = 24
decimal daysLeftInStartMonth = totalDaysInStartMonthMinusStartDay + 1;
// 24 / 31 = .77 days left to go in the month
decimal daysLeftToCompleteInStartMonthPercentage = daysLeftInStartMonth / daysInStartMonth;
return daysLeftToCompleteInStartMonthPercentage;
}
/// <summary>
/// For example if the finish date were 9/8/2012 we've completed 8 days so far or .24 percent of the month
/// </summary>
private static decimal getDaysCompletedSoFarInFinishMonthPercentage( DateTime finishDate )
{
// for septebmer = 30 days in month.
decimal daysInFinishMonth = DateTime.DaysInMonth( finishDate.Year, finishDate.Month );
// 8 days divided by 30 = .26 days completed so far in finish month.
decimal daysCompletedSoFarInFinishMonthPercentage = finishDate.Day / daysInFinishMonth;
return daysCompletedSoFarInFinishMonthPercentage;
}
This solution calculates whole months and then adds the partial month based on the end of the time period. This way it always calculates full months between the dates' day-of-month and then calculates the partial month based on the number of remaining days.
public decimal getMonthDiff(DateTime date1, DateTime date2) {
// Make parameters agnostic
var earlyDate = (date1 < date2 ? date1 : date2);
var laterDate = (date1 > date2 ? date1 : date2);
// Calculate the change in full months
decimal months = ((laterDate.Year - earlyDate.Year) * 12) + (laterDate.Month - earlyDate.Month) - 1;
// Add partial months based on the later date
if (earlyDate.Day <= laterDate.Day) {
decimal laterMonthDays = DateTime.DaysInMonth(laterDate.Year, laterDate.Month);
decimal laterPartialMonth = ((laterDate.Day - earlyDate.Day) / laterMonthDays);
months += laterPartialMonth + 1;
} else {
var laterLastMonth = laterDate.AddMonths(-1);
decimal laterLastMonthDays = DateTime.DaysInMonth(laterLastMonth.Year, laterLastMonth.Month);
decimal laterPartialMonth = ((laterLastMonthDays - earlyDate.Day + laterDate.Day) / laterLastMonthDays);
months += laterPartialMonth;
}
return months;
}
The calculation below is one that is according the way the Dutch Tax Authority wants months calculated. This means that when the starts day is for example feb 22, march 23 should be result in something above 1 and not just something like 0.98.
private decimal GetMonthDiffBetter(DateTime date1, DateTime date2)
{
DateTime start = date1 < date2 ? date1 : date2;
DateTime end = date1 < date2 ? date2 : date1;
int totalYearMonths = (end.Year - start.Year) * 12;
int restMonths = end.Month - start.Month;
int totalMonths = totalYearMonths + restMonths;
decimal monthPart = (decimal)end.Day / (decimal)start.Day;
return totalMonths - 1 + monthPart;
}`
This should get you where you need to go:
DateTime start = new DateTime(2001, 1, 1);
DateTime finish = new DateTime(2002, 3, 15);
double diff = (finish - start).TotalDays / 30;
the framework as a TimeSpan object that is a result of subtracting two dates.
the subtraction is already considering the various option of February(28/29 days a month) so in my opinion this is the best practice
after you got it you can format it the way you like best
DateTime dates1 = new DateTime(2010, 1, 1);
DateTime dates2 = new DateTime(2010, 3, 15);
var span = dates1.Subtract(dates2);
span.ToString("your format here");
private Double GetTotalMonths(DateTime future, DateTime past)
{
Double totalMonths = 0.0;
while ((future - past).TotalDays > 28 )
{
past = past.AddMonths(1);
totalMonths += 1;
}
var daysInCurrent = DateTime.DaysInMonth(future.Year, future.Month);
var remaining = future.Day - past.Day;
totalMonths += ((Double)remaining / (Double)daysInCurrent);
return totalMonths;
}

Categories