How to convert number of days to years,months and days [duplicate] - c#

This question already has answers here:
How can I calculate the age of a person in year, month, days?
(13 answers)
Closed 9 years ago.
If i have Two dates then i get the difference between them in days Like this Post.
How to detail that in the following view :
convert the days to (number of years,number of months and the rest in the number of days)

There is no out-of-the-box solution for this. The problem is the data isn't "fixed" e.g. not all years are 365 days (366 on a leap year) and not every month can be assumed to be standard 30 days.
It's very difficult to calculate this sort of information without context. You have a duration in days, however, to accurately calculate the number of years/months you need to know exactly when these days fall i.e. on what month and of what year - this would allow you to determine the exact days in the month and/or year.
Based on your comments and the following conditions
1 year = 365 days
1 month = 30 days
Then the following code would do the job
DateTime startDate = new DateTime(2010, 1, 1);
DateTime endDate = new DateTime(2013, 1, 10);
var totalDays = (endDate - startDate).TotalDays;
var totalYears = Math.Truncate(totalDays / 365);
var totalMonths = Math.Truncate((totalDays % 365) / 30);
var remainingDays = Math.Truncate((totalDays % 365) % 30);
Console.WriteLine("Estimated duration is {0} year(s), {1} month(s) and {2} day(s)", totalYears, totalMonths, remainingDays);

You can't because it depends on the start date
i.e. 30 days may be 1 month 1 day, or 1 month 2 days, or less than a month or
365 days will be less than a year if it's a leap year

As mentioned in previous answers, it is very difficult to work this out from just a number of days. There is problems with leap years, and the number of days in months. If you start with the original two datetimes you can use code similar to the following:
DateTime date1 = new DateTime(2010, 1, 18);
DateTime date2 = new DateTime(2013, 2, 22);
int oldMonth = date2.Month;
while (oldMonth == date2.Month)
{
date1 = date1.AddDays(-1);
date2 = date2.AddDays(-1);
}
int years = 0, months = 0, days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0;
// getting number of years
while (date2.CompareTo(date1) >= 0)
{
years++;
date2 = date2.AddYears(-1);
}
date2 = date2.AddYears(1);
years--;
// getting number of months and days
oldMonth = date2.Month;
while (date2.CompareTo(date1) >= 0)
{
days++;
date2 = date2.AddDays(-1);
if ((date2.CompareTo(date1) >= 0) && (oldMonth != date2.Month))
{
months++;
days = 0;
oldMonth = date2.Month;
}
}
date2 = date2.AddDays(1);
days--;
TimeSpan difference = date2.Subtract(date1);
Console.WriteLine("Difference: " +
years.ToString() + " year(s)" +
", " + months.ToString() + " month(s)" +
", " + days.ToString() + " day(s)");
Output is:Difference: 3 year(s), 1 month(s), 4 day(s)

Related

c# windows form Application for employee management [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In a C# windows form based application. I used two dateTime pickers,one for From and another for To.
if a employee selecting his leave from may 30 in dateTime picker1 and selecting june 2 in datetime picker2, that makes 4 days of leave.
My question is how can i findout how many days he took leave in may and how many days he took leave in june?
Update
I know this, and stuck further
DateTime start = dateTimePicker1.Value.Date;
DateTime end = dateTimePicker2.Value.Date;
int a = int.Parse(Convert.ToInt32(end.Subtract(start).Days).ToString());
you can try this code,
here at the end you will get a Dictionary (tabular form) where key will be month number and value is days of in month (here in your question, how many days employee has taken leave)
DateTime startDate = new DateTime(2018, 06, 25); //date time picker's date
DateTime endDate = new DateTime(2018, 07, 05); //date time picker's date
Dictionary<int, int> daysInMonth = new Dictionary<int, int>();
while(true)
{
DateTime thisMonthEndDate = new DateTime(startDate.Year, startDate.Month, DateTime.DaysInMonth(startDate.Year, startDate.Month));
if (thisMonthEndDate > endDate)
{
thisMonthEndDate = endDate;
daysInMonth.Add(startDate.Month, (int)(thisMonthEndDate - startDate).TotalDays + 1);
break;
}
daysInMonth.Add(startDate.Month, (int)(thisMonthEndDate - startDate).TotalDays + 1);
startDate = thisMonthEndDate.AddDays(1);
}
and output printing will be
foreach(KeyValuePair<int, int> keyVal in daysInMonth)
{
Console.WriteLine("For Month:" + keyVal.Key + " leave count:" + keyVal.Value);
}
To get days per month in a timespan.
for (DateTime date = start; date < end; date = date.AddMonths(1))
{
DateTime this_date_start = new DateTime(date.Year, date.Month, 1);
DateTime this_date_end = this_date_start.AddMonths(1).AddDays(-1);
TimeSpan duration = this_date_end.Subtract(date);
Console.WriteLine("duration " + date.Month + " = " + duration.Days + "days");
}
NB: this loop is incomplete: then you have to do this once again outside the loop (this will also catch any shorter than one month spans)
LINQ make it simple and readable:
var from = new DateTime(2018, 5, 28);
var to = new DateTime(2018, 6, 4);
var result = Enumerable.Range(0, int.MaxValue)
.Select(i => from.Date.AddDays(i))
.TakeWhile(date => date <= to.Date)
.GroupBy(date => date.Month)
.Select(range => (Month: range.Key, Days: range.Count()));
foreach (var month in result)
{
Console.WriteLine($"Month: {month.Month}, Seek days: {month.Days}");
}
// result:
// Month: 5, Seek days: 4
// Month: 6, Seek days: 4
If you need amount of seek days for specific month, make it Dictionary
var seekDays = result.ToDictionary(month => month.Month, month => month.SeekDays);
var seekDaysOfMay = seekDays.GetValueOrDefault(5, 0);

Shift date by months but keep the same day

I am trying to shift a date by a number of given months, but also to keep the same day (for example, if the day of the date is Monday, and after shifting with x months the day is Thursday, I want also to subtract 3 days from the new obtained date. This algorithm should add/subtract days depending on the new obtained date, basically providing the closest date that represents the same day of week). As an example, if I have the start date 10.08.2016(Wednesday), and I add 3 months, I will get 10.11.2016(Thursday), so the closest Wednesday to that day is 09.11.2016.
What I managed to make till now looks something like this:
int startDayOfWeek = ((int)startDay.DayOfWeek) == 0 ? 7 : (int)startDay.DayOfWeek;
int newStartDayOfWeek = ((int)startDay.AddMonths(period).DayOfWeek) == 0 ? 7 : (int)startDay.AddMonths(period).DayOfWeek;
int shiftingDays = startDayOfWeek - newStartDayOfWeek;
if (shiftingDays > 3)
shiftingDays -= 7;
where startDay is the start date, and period is the number of months I want to shift to.
But this still fails some times, so any tips would be greately appreciated.
An example when this code fails would be:
startDate = 01.08.2016 (Monday) and period would be 5
After adding 5 months, I get 01.01.2017, which is Sunday, and the closest Monday would be on 02.01.2017, but I get -6 days.
Use this code. The idea is to divide the days by 7, round it, and multiply by 7.
DateTime endDate = startDay.AddMonths((int)period);
endDate = startDay.AddDays((int)Math.Round((double)(endDate - startDay ).Days / 7)*7);
Is that what you are looking for ?
static void Main( string[] args )
{
//DateTime startDay = DateTime.Now;
DateTime startDay = new DateTime( 2016, 8, 1 );
//DateTime startDay = new DateTime( 2016, 8, 10 );
DateTime newDay = startDay.AddMonths( 5 );
int startDayOfWeek = (int)startDay.DayOfWeek;
int newDayOfWeek = (int)newDay.DayOfWeek;
int shift1 = (7 + startDayOfWeek - newDayOfWeek) % 7;
int shift2 = (7 + newDayOfWeek - startDayOfWeek) % 7;
DateTime test = newDay + ((shift1 > shift2) ? - TimeSpan.FromDays( shift2 ) : TimeSpan.FromDays( shift1 ));
}

Get the Date of Months Week Number

I have a code 2014P07W4 which means:
2014 = year
P07 = 7th month of the year
W4 = 4th week of the month.
I would like to work out the date of the First day of the 4th week in July 2014. In this example I would expect to see a date of 21/7/2014.
July 2014 weeks
Week 1 - 1st to 6th
Week 2 - 7th to 13th
Week 3 - 14th to 20th
Week 4 - 21st to 27th
Week 5 - 28th to 31st
From the code I know the week no = 4 then I want to be able to calculate the date 21/7/2014. I am assuming the first day of the week is a Monday
I am asking how to read that code and get the first day of the week specified
Hope this is clearer it has been a long day
You need to parse the code and extract the year, month, and weekNo an numbers.
Then, you can use this method to get the start day of the week:
int WeekStartDay(int year, int month, int weekNo)
{
DateTime monthStart = new DateTime(year, month, 1);
int monthStart_DayOfWeek = ((int)monthStart.DayOfWeek + 6) % 7;
int weekStart_DayOfMonth = 1;
if (1 < weekNo) {
weekStart_DayOfMonth += 7 - monthStart_DayOfWeek;
}
if (2 < weekNo) {
weekStart_DayOfMonth += 7 * (weekNo - 2);
}
return weekStart_DayOfMonth;
}
Take first day of month (2014/07/01), find next Monday (first day of 2nd week), add 14 days (first day of 4th week).
DateTime date = new DateTime(2014, 7, 1);
int daysToFirstDayOf2ndWeek = date.DayOfWeek == DayOfWeek.Monday
? 7
: ((int)DayOfWeek.Monday - (int)date.DayOfWeek + 7) % 7;
DateTime firstDayOf2ndWeek = date.AddDays(daysToFirstDayOf2ndWeek);
DateTime firstDayOf4thWeek = firstDayOf2ndWeek.AddDays(14);
may be this will works
string code = "2014P07W4";
int yr = int.Parse(code.Substring(0, 4));
int mnth = int.Parse(code.Substring(5, 2));
int week = int.Parse(code.Substring(8));
DateTime dt = new DateTime(yr, mnth, 1);
if (dt.DayOfWeek == DayOfWeek.Monday)
{
DateTime newdate = dt.AddDays((week - 1) * 7);
}
else
{
DateTime newdate = dt.AddDays((8 - (int)dt.DayOfWeek) % 7 + ((week - 2) * 7));
}

C# subtract time (hours minutes)

Hello Everyone I have some interesting situation.
I want to count how many hours (in minutes) is from 20:00 to 01:00 AM, but i Don't know how, because what i have done is:
pabaigosLaikoLaukelis = 01:00;
pradziosLaikoLaukelis = 20:00;
TimeSpan dt = Convert.ToDateTime(pabaigosLaikoLaukelis)- Convert.ToDateTime(pradziosLaikoLaukelis);
int minutes = (int)dt.TotalMinutes;
And i get result -> -1140 minutes, but I need that answer to be just 5 hours from 20:00 to 01:00.
I know that it is quite easy, but i have no idea how to do it.
you could do something like this
//Datetime(Year,month,day,hour,min,sec)
DateTime date1 = new DateTime(2012, 1, 1, 20, 0, 0);
DateTime date2 = new DateTime(2012, 1, 2, 1, 0, 0);
string minutes = (date2.Subtract(date1).TotalMinutes).ToString();
Tested and works 300 minutes (5 hours)
Use full date time strings that contain day part, to show that 01:00 AM is one day later than 20:00 - like following:
int minutes = Convert.ToDateTime("01/02/2012 01:00").Substract(Convert.ToDateTime("01/01/2012 20:00")).TotalMinutes;
You need to specify the Day, you are subracting (Today 1:00 AM) - (Today 8:00 PM)
I think you need to subract (Tommorrow 1:00 AM) - (Today 8:00 PM)
Be careful with adding one day to the endTime, because then the difference between 20:00 and 22:00 will be 26 hours instead of 2!
Just check whether the difference is positive (same day) or negative (next day)
string pabaigosLaikoLaukelis = "01:00";
string pradziosLaikoLaukelis = "20:00";
// This should be 5 hours
TimeSpan dt = Convert.ToDateTime(pabaigosLaikoLaukelis) - Convert.ToDateTime(pradziosLaikoLaukelis);
int hours = (int)dt.TotalHours;
hours = hours < 0 ? 24 + hours : hours;
// This should be 19 hours
dt = Convert.ToDateTime(pradziosLaikoLaukelis) - Convert.ToDateTime(pabaigosLaikoLaukelis);
hours = (int)dt.TotalHours;
hours = hours < 0 ? 24 + hours : hours;
A bit of preparation of the two string variables is required before attempting data calculations
string pabaigosLaikoLaukelis = "01:00";
string pradziosLaikoLaukelis = "20:00";
pabaigosLaikoLaukelis = DateTime.Today.ToString("dd/MM/yyyy") + " " + pabaigosLaikoLaukelis;
pradziosLaikoLaukelis = DateTime.Today.AddDays(-1).ToString("dd/MM/yyyy") + " " + pradziosLaikoLaukelis;
TimeSpan dt = Convert.ToDateTime(pabaigosLaikoLaukelis) - Convert.ToDateTime(pradziosLaikoLaukelis);
Console.WriteLine("{0:D2}:{1:D2}", dt.Hours, dt.Minutes);
You need to add a day to the first TimeSpan and use TotalHours.
var pabaigosLaikoLaukelis = "01:00";
var pradziosLaikoLaukelis = "20:00";
var oneDayTimeSpan = new TimeSpan(1, 0, 0, 0);
TimeSpan dt = TimeSpan.Parse(pabaigosLaikoLaukelis).Add(oneDayTimeSpan) - TimeSpan.Parse(pradziosLaikoLaukelis);
int minutes = (int)dt.TotalHours; // 5 hours
Using associative operations:
var pabaigosLaikoLaukelis = "21:00";
var pradziosLaikoLaukelis = "20:00";
var leftHours = (int)TimeSpan.Parse(pabaigosLaikoLaukelis).TotalHours;
var rightHours = (int)TimeSpan.Parse(pradziosLaikoLaukelis).TotalHours;
// Now we do a Modulus operation which will assure
// 23 > hours > 0
// Make sure to check that leftHours != 0 or rightHours != 0
int hours = (Math.Abs(leftHours * rightHours) + leftHours) % rightHours; //Modulus
var hoursTimeSpan = TimeSpan.FromHours(hours);
How about this:
pabaigosLaikoLaukelis = 01:00;
pradziosLaikoLaukelis = 20:00;
TimeSpan startTime = Convert.ToDateTime(pradziosLaikoLaukelis).TimeOfDay;
TimeSpan endTime = Convert.ToDateTime(pabaigosLaikoLaukelis).TimeOfDay;
TimeSpan diff = endTime > startTime ? endTime - startTime : endTime - startTime + TimeSpan.FromDays(1);
int minutes = (int)diff.TotalMinutes;

how to find year and month difference between two dates?

DateTime dayStart;
DateTime dateEnd;
TimeSpan ts = dateEnt - dateStart;
Print : ... Year(s) and ... Month(s)
how can I calculate it?
.net framework 2.0
c#
asp.net project.
You should first read this article from Jon Skeet, specially from the text "Introducing periods and period arithmetic" it gets interesting for you.
So, you have to define when a certain period is a change in month, in year etc.
Noda-time already contains a lot of functions for this. But I don't think it is released yet.
Following will calculate the age in years, months, days
DateTime dob = "10/18/1981"; // date of birth
DateTime now = DateTime.Now;
// Swap them if one is bigger than the other
if (now < dob)
{
DateTime date3 = now;
now = dob;
dob = date3;
}
TimeSpan ts = now - dob;
//Debug.WriteLine(ts.TotalDays);
int years = 0;
int months = 0, days=0;
if ((now.Month <= dob.Month) && (now.Day < dob.Day)) // i.e. now = 03Jan15, dob = 23dec14
{
// example: March 2010 (3) and January 2011 (1); this should be 10 months. // 12 - 3 + 1 = 10
years = now.Year - dob.Year-1;
months = 12 - dob.Month + now.Month-1;
days = DateTime.DaysInMonth(dob.Year, dob.Month) - dob.Day + now.Day;
if(months==12)
{
months=0;
years +=1;
}
}
else if ((now.Month <= dob.Month) && (now.Day >= dob.Day)) // i.e. now = 23Jan15, dob = 20dec14
{
// example: March 2010 (3) and January 2011 (1); this should be 10 months. // 12 - 3 + 1 = 10
years = now.Year - dob.Year - 1;
months = 12 - dob.Month + now.Month;
days = now.Day - dob.Day;
if (months == 12)
{
months = 0;
years += 1;
}
}
else if ((now.Month > dob.Month) && (now.Day < dob.Day)) // i.e. now = 18oct15, dob = 22feb14
{
years = now.Year - dob.Year;
months = now.Month - dob.Month-1;
days = DateTime.DaysInMonth(dob.Year, dob.Month) - dob.Day + now.Day;
}
else if ((now.Month > dob.Month) && (now.Day >= dob.Day)) // i.e. now = 22oct15, dob = 18feb14
{
years = now.Year - dob.Year;
months = now.Month - dob.Month;
days = now.Day - dob.Day;
}
Debug.WriteLine("Years: {0}, Months: {1}, Days: {2}", years, months, days);
That depends on what you want to calculate exactly.
You can't translate the value in a TimeSpan to exact years and months, as the length of years and months varies. You can calculate approximate years and months like this:
int years = ts.Days / 365;
int months = (ts.Days % 365) / 31;
If you want the exact difference, you have to compare the DateTime values.
I think something like this would do it:
DateTime date1 = new DateTime(1973, 07, 20);
DateTime date2 = new DateTime(2010, 01, 10);
// Swap them if one is bigger than the other
if (date2 < date1)
{
DateTime date3 = date2;
date2 = date1;
date1 = date3;
}
// Now date2 >= date1.
TimeSpan ts = date2 - date1;
// Total days
Console.WriteLine(ts.TotalDays);
// Total years
int years = date2.Year - date1.Year;
int months = 0;
// Total monts
if (date2.Month < date1.Month)
{
// example: March 2010 (3) and January 2011 (1); this should be 10 monts
// 12 - 3 + 1 = 10
// Take the 12 months of a year into account
months = 12 - date1.Month + date2.Month;
}
else
{
months = date2.Month - date1.Month;
}
Console.WriteLine("Years: {0}, Months: {1}", years, months);
Edit To clarify: There's no need for complicated date algorhitms or any of that kind of stuff, because there are always 12 months in a year (at least in our calendar).

Categories

Resources