Calculate days in years and months? - c#

How to calculate days in years and months in c#?
per example :
If
1. days = 385 then I need to display Year= 1.1 (i.e. 1 year 1 month)
2. days= 234 then I need to display year =0.7 (i.e 0 year 7 months)
How can we calculate in c#?
I did for days=234 /365 and result is coming 0.64 (i.e. 0 year 6 months). But actually it is 7 months.
How to get accurate year and months.

You can do:
double temp = (234.0 /365.0) * 12.0;
int years = (int)temp;
int months = (int)(temp - years);
This is because you were getting 0.64, which is 0.64 years. If you want months, you'd need to multiply that times 12.
In the above, you'll get 0 years and 7 months... That being said, I'm not sure exactly how you want to format this:
string yearsString = string.Format("{0}.{1}", years, months);
Just be aware that this will do 3.11 for 11 months, which is going to be odd, though it was your requirement.
Also, if you want to have this be very general, you might want to use 365.25 instead of 365 to represent a single Julian Year, as it will help you reduce issues due to leap years.

If you don't know the actual dates, then you could estimate:
Number of years: x / 365
Number of months: (x % 365) / 30
where % is modulo

Assuming a month of exactly one-twelfth of a year, and that you want ignore partial months (based on your saying you expect 7 from your example with 7.688 months, then:
int days = 234;
double years = (double)days / 365.242199;
int wholeYears = (int)Math.Floor(years);
double partYears = years - wholeYears;
double approxMonths = partYears * 12;
string horribleFormat = string.Concat(wholeYears, ".", approxMonths);

Are you sure you want this format? The result--at least with the current information provided--will be fuzzy since months are inconsistent lengths.
Consider a couple alternatives:
A Year-only representation, such as 1.25 meaning "1 and one quarter years". This doesn't mix months and years, and as such remains simple since a year is 365 days (except for leap years). It also removes ambiguity such as "does 1.10 == 1.1?"
Using a concrete start date which would allow you to use strongly-type dates. You could easily use a .ToString() with date-formatting arguments to quickly and accurately get your result.

Let do some calculations.
1 mon = 0.1
2 mon = 0.2
.
.
9 mon = 0.9
10 mon = 1.0 [WRONG according to you 1 is a year]
fine then 1 / 12 = 0.083, therefore 0.083 is 1 month
Now,
234 / 365 = 0.64 => 0.64 / 0.083 => 7.7 i.e. 7th month
Therefore fx => days / 365 = ans % 0.083 = result.
I have no time to prove other number but you can try around this formula.

My suggestion would be to use DateTime.AddDays: it will give you all you need. You can also add other time units there:
DateTime f = new DateTime(0);
var y = f.AddDays(361);

Pseudo code
ts= TimeSpan.fromDays(385)
Years = ts.days Modulo 365
months = (ts.days remainder 365) modulo 12
days = (ts.days remainder 365) Remainder 12
answer string years + "." + months + "." + days

In VB
Dim d As DateTime = DateTime.MinValue 'year = 0001
d = d.AddYears(DateTime.Now.Year - 1) 'add current year
d = d.AddDays(234) 'add days
Dim yrs As Integer = d.Year - DateTime.Now.Year 'calculate years
Dim mos As Double = d.Month / 12 'calculate months
Dim answer As Double = yrs + mos
answer = .6666666666

I think that's numerically impossible. What would you do about 1 year and 11 months? 1.11? Because that could mean either 1 year and 1 month and something, or 1 year and 11 months.

Related

how to calculate years and month from given number c#

I need to calculate years and months from a given number. how can I do it?
eg:
I am giving: 26
I need to get result: 2 years 2months
please help
Unless you have some more specific requirements, it should be as easy as Integer Division and the Remainder operator %
var input = 26;
var years = input / 12;
var months = input % 12;
Console.WriteLine($"{years} years and {months} months");
Output
2 years and 2 months
or
private static (int Years, int Months) GetYearsAndMonths(int input)
=> (input / 12, input % 12);
...
var result = GetYearsAndMonths(26);
Console.WriteLine($"{result.Years} years and {result.Months} months");
or the little known method Math.DivRem Method as supplied by #Charlieface
Calculates the quotient of two numbers and also returns the remainder
in an output parameter.

Add decimal number to Date - C#

How to convert a decimal number (e.g. 2.5) to year and month (2 years and 6 months) and add it to a given date? I tried DateTime.TryParse and it didn't work.
If you are using it for years then multiply the float you have by 12. 2.5 becomes 30months. Then use the addmonths function. If I enter 5 then it will add 60 months which is 5 years
Usually you could just add a TimeSpan or use one of the Add methods, like this:
decimal yearsToAdd = (decimal)2.5;
int years = (int)Math.Floor(yearsToAdd);
decimal months = yearsToAdd - years;
int actualMonths = (int) Math.Floor(months * 12); // or Ceiling or Round
DateTime x = DateTime.Now.AddYears(years).AddMonths(actualMonths);
The problem is, that when you decimal doesn't yield an exacat number of months, how would you know how long e.g. half a month is?
28.0 / 2, 29.0 / 2, 30.0 / 2 or 31.0 / 2?
Would you take the length of the month you started with or one of the possible two months you end up with?
If you init date is dt than
dt = dt.AddMonths((int)(2.5*12));
decimal x =(decimal)2.5;
int nbYear = Convert.ToInt16(x);
var y = x - Math.Truncate(x);
int nbMonth =Convert.ToInt16 (y*12);
// MessageBox .Show (string.Format (" {0} years and {1} months ",nbYear ,nbMonth ));
DateTime dat=DateTime .Now ; // or given date
DateTime dat2 = dat.AddYears(nbYear).AddMonths(nbMonth);
If month is your smallest unit then the solution is, as pointed by many, to multiply number by 12. A more accurate alternative would be to use ticks.
decimal years=3.14592M; // No idea where this came from.
long ticks = (long)(356.0M * (decimal)TimeSpan.TicksPerDay * years);
DateTime futureDate=DateTime.Today.AddTicks(ticks);
Note that solution will not compensate for leap years. It is not difficult to extend it - you need to calculate number of leap years in the period and use average instead of 356.0M to calculate ticks per year (i.e. avg. number of days per year * ticks per day).

How to determine fortnight number from date

I have a niggling problem that I am having trouble conceptualising a solution.
I have a payroll system that has the following rules:
The Pay period relating to each pay period is 14 days long starting
on Monday and ending on Sunday
Payday is each fortnight on Thursday following the last day of the pay period.
Pay periods are numbered 1 through to 26 (or 27 in some years) with ONE being the first payday in the financial year and 26 (or 27) being the last in the financial year.
Our financial year runs July 1 to June 30
A known pay fortnight was started on 25/06/2012 and ended on 8/07/2012. The pay day for this period was 12/07/2012. So I do have a few start points.
From any date, I can calculate what its pay date is because I have a known start point. I can also calculate the financial year it relates to easily enough. There are many solutions to those problems on SO.
I now need to allow my users to enter a date and have the application show the pay period it relates to.
What I am struggling with is how can I determine which pay period (1 to 26/27) it is in the financial year? Any ideas?
Now your user enters a date, and you can calculate its pay date, right? Let "payDate" be this pay date, and what you want is "which fortnight of the financial year does payDate fall in, numbered starting with one", right?
Then, you first need to determine the beginning of the financial year:
DateTime yearBegin;
if (payDate.Month >= 7)
yearBegin = new DateTime(payDate.Year, 7, 1);
else
yearBegin = new DateTime(payDate.Year - 1, 7, 1);
With this you can calculate how many days are there between payDate and yearBegin:
int delta = (payDate - yearBegin).Days;
Finally you get the answer:
int period = (delta / 14) + 1;
I understood the first pay day from any given year starts at a different day to always match full periods of 14 days. If that is the case, you could try this code:
static DateTime InitialDate = new DateTime(2012, 06, 25);
private static int PayPeriod(DateTime inputDate)
{
int periodStartDay = (inputDate - InitialDate).Days % 14 + 1;
int periodStartMonth = 07;
int periodStartYear = inputDate.Month >= 7 ? inputDate.Year : inputDate.Year - 1;
DateTime periodStartDate = new DateTime(periodStartYear, periodStartMonth, periodStartDay);
int payPeriod = (inputDate - periodStartDate).Days / 14 + 1;
return payPeriod;
}

Errornous calculation of year/month/day between two dates

What I try to do is calculate the number of years, months and days between two dates.
Unfortunately, there is no method of the .NET Framework which can do this.
What I did is basically the following:
http://www.codeproject.com/Articles/28837/Calculating-Duration-Between-Two-Dates-in-Years-Mo
with a few adaptations from the comments of said website:
var monthDay = new[] { 31, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
DayCalculation:
if (fromDate.Day > toDate.Day)
{
increment = monthDay[toDate.Month - 1];
}
if (increment == -1)
{
increment = DateTime.IsLeapYear(toDate.Year) ? 29 : 28;
}
So I have the following effect:
Date1: 1979-01-30
Date2: 2013-03-01
And the output is: 34 Years, 1 Month, -1 Day
The expected output is: 34 Years, 1 Month, 1 Day
This effect happens every time, the Date2 is a date in march.
Do you know what is wrong with this calculation?
Or do you know a better solution how to achieve the desired result?
Thanks in advance
PS: I know that you can calculate the amount of days between two dates, but what I need is the amount of finished years, the amount of finished months, and the amount of finished days
Unfortunately, there is no method of the .NET Framework which can do this.
True, but there is Noda Time instead :) (It's my port of Joda Time to .NET, although there are quite a few differences between the two projects.)
LocalDate start = new LocalDate(1979, 1, 30);
LocalDate end = new LocalDate(2013, 3, 1);
Period period = Period.Between(start, end);
Console.WriteLine("{0} years, {1} months, {2} days",
period.Years, period.Months, period.Days);
Output:
34 years, 1 months, 1 days
Here is a way to calculate the difference without using an external library. Two dates are required. I assume that the first date is no later than the second date. Otherwise you will have to swap them for the calculation to be correct.
var first = new DateTime(1979, 1, 30);
var second = new DateTime(2013, 3, 1);
Here is how to compute the difference. You do not need a table to get the number of days in the month. That information is provided by the DateTime.DaysInMonth function.
var years = second.Year - first.Year;
var months = second.Month - first.Month;
if (months < 0) {
months += 12;
years -= 1;
}
var days = second.Day - first.Day;
if (days < 0) {
var daysInFirstMonth = DateTime.DaysInMonth(first.Year, first.Month);
days += daysInFirstMonth;
months -= 1;
}
Printing the computed values
Console.WriteLine("{0} year(s), {1} month(s), {2} day(s)", years, months, days);
will result in
34 year(s), 1 month(s), 2 day(s)
This produces the same results as the code that you have linked to. However, you expect to get 1 day instead of 2 days. I guess it depends on how you define "days between". If you prefer to count only January 31 as the day between you can subtract 1 from days. Then there will be 0 days between two adjacent days and -1 days "between the same date".

TimeSpan for different years subtracted from a bigger TimeSpan

The language I am using is C#.
I have the folowing dillema.
DateTime A, DateTime B. If A < B then I have to calculate the number of days per year in that timespan and multiply it by a coeficient that corresponds to that year.
My problem is the fact that it can span multiple years.
For example:
Nr of Days in TimeSpan for 2009 * coef for 2009 + Nr of Days in TimeSpan for 2010 * coef for 2010 + etc
You can't do this with a simple TimeSpan, basically. It doesn't know anything about when the span covers - it's just a number of ticks, really.
It sounds to me like there are two cases you need to consider:
A and B are in the same year. This is easy - just subtract one from the other and get the number of days from that
A and B are in different years. There are now either two or three cases:
The number of days after A in A's year. You can work this out by constructing January 1st in the following year, then subtracting A
The number of days in each year completely between A and B (so if A is in 2008 and B is in 2011, this would be 2009 and 2010)
The number of days in B's year. You can work this out by constructing December 31st in the previous year, then subtracting B. (Or possibly January 1st in B's year, depending on whether you want to count the day B is on or not.)
You can use DateTime.IsLeapYear to determine whether any particular year has 365 or 366 days in it. (I assume you're only using a Gregorian calendar, btw. All of this changes if not!)
Here is a little snippet of code that might help
var start = new DateTime(2009, 10, 12);
var end = new DateTime(2014, 12, 25);
var s = from j in Enumerable.Range(start.Year, end.Year + 1 - start.Year)
let _start = start.Year == j ? start : new DateTime(j, 1, 1)
let _end = end.Year == j ? end : new DateTime(j, 12, 31)
select new {
year = j,
days = Convert.ToInt32((_end - _start).TotalDays) + 1
};
If I understood your problem correctly, solving it using Inclusion Exclusion principle would be the best.
Say, if your start date is somewhere in 2008 and the end date is in 2010:
NDAYS(start, end) * coeff_2008
- NDAYS(2009, end) * coeff_2008 + NDAYS(2009, end) * coeff_2009
- NDAYS(2010, end) * coeff_2009 + NDAYS(2010, end) * coeff_2010
Where Ndays computes the number of dates in the interval (TotalDays plus one day).
There is no need to handle leap years specially or compute december 31st.
The details you can work out in a for-loop going over jan first of each year in the span.

Categories