How to get difference between two days in .NET - c#

I want to find the service period of the employee ,i already get the employee join date from database its like that
ex - join Date: 2007/03/24
Now I need to find the difference between system date and join date if any one can have idea about that please help me thanks.
sample code which i wrote to get answer ,but it not work correctly
public TimeSpan periodOfService
{
get
{
//DateOfJoin-->which i get from my database
DateTime JoinDate = Convert.ToDateTime(DateOfJoin);
DateTime TodayData = DateTime.Now;
TimeSpan servicePeriod = JoinDate - TodayData;
return servicePeriod;
}
}
out put format - >2 years, 3 months
How can I do this in Asp.net MVC 4?

First of all, swap the dates around.
You want to subtract JoinDate from TodayData (also revise spellings and naming conventions):
public TimeSpan periodOfService
{
get
{
//DateOfJoin-->which i get from my database
DateTime JoinDate = Convert.ToDateTime(DateOfJoin);
DateTime TodayData = DateTime.Now;
TimeSpan servicePeriod = TodayData - JoinDate;
return servicePeriod;
}
}
Unfortunately, OP, outputting this TimeSpan value in the format you'd like is a lot trickier than you'd initially think, see the following article for how to achieve that:
http://joelfillmore.com/years-and-months-between-dates/
I'd recommend you read up on the solution it suggests and then look into using the method:
public DateSpan(DateTime startDate, DateTime endDate)

Normally you will use a TimeSpan to represent the difference between to dates but your requirement to display the difference as years and months makes TimeSpan unsuitable. Instead you can create a class to represent the difference:
class DateDifference {
public DateDifference(Int32 years, Int32 months) {
Years = years;
Months = months;
}
public Int32 Years { get; private set; }
public Int32 Months { get; private set; }
}
You can the calculate the difference between two dates using simple arithmetic:
DateDifference GetDateDifference(DateTime first, DateTime second) {
if (second < first)
throw new ArgumentOutOfRangeException("second", "The second date cannot occur before the first.");
var years = second.Year - first.Year;
var months = second.Month - first.Month;
if (second.Month < first.Month) {
years -= 1;
months += 12;
}
return new DateDifference(years, months);
}
You can then use the function in your code:
var dateDifference = GetDateDifference(JoinDate, TodayDate);

This will get you the difference between the two dates, regardless of if it's in the future or in the past.
If it's an invalid date, a zero span is returned
public TimeSpan periodOfService
{
get
{
DateTime JoinDate;
if (DateTime.TryParse(DateOfJoin, out JoinDate))
{
return DateTime.Now > JoinDate ? DateTime.Now - JoinDate : JoinDate - DateTime.Now;
}
return TimeSpan.Zero;
}
}

You Can Get Total Day Diff And Convert it To Month And Year
a Simple Sample is here
TimeSpan servicePeriod = TodayData - JoinDate;
string result = string.Format("{0} Years, {1} Months, {2} Days", servicePeriod.TotalDays / 365, servicePeriod.TotalDays / 30, servicePeriod.TotalDays);
you Can Return a string not a timespan

Related

How to properly convert DateofBirth to age inside a viewmodal [duplicate]

This question already has answers here:
How do I calculate someone's age based on a DateTime type birthday?
(74 answers)
Closed 2 years ago.
I'm trying to convert a personnel's date of birth to their actual age within a ViewModel inside of another viewmodel I plan on calling in the front end.
I've managed to create public DateTime? PersonnelDOB { get; set; } and it's bringing back their Date of Birth I.E 6/12/1972
I need to convert this to their actual age so instead of 6/12/1972, it'll be "48 years old"
the issue to this current problem is that 'dob' is a DateTime and 'today.year' is an int. I can't subtract a DateTime from an int. I need to also make sure I account for leapyears and for it to actually accurately output their age. I also will want to check that dob isn't null. I dont have to do this within a viewmodel I created, it was just an avenue I was exploring.
Thank you all for your help!
public DateTime? PersonnelDOB { get; set; }
public PersonnelDOBViewModel()
{
var dob = PersonnelDOB;
// Save today's date.
var today = DateTime.Today;
// Calculate the age.
var age = today.Year - dob;
// Go back to the year the person was born in case of a leap year
if (dob > today.AddYears(-age)) age--;
return age;
}
** A coworker helped me out and for those of you interested in the right answer - here it is
public DateTime? PersonnelDOB { get; set; }
public int? PersonnelAge
{
get
{
if (!PersonnelDOB.HasValue)
return null;
DateTime today = DateTime.Today;
int years = today.Year - PersonnelDOB.Value.Year;
years -= (today.Month < PersonnelDOB.Value.Month || (today.Month == PersonnelDOB.Value.Month && today.Day < PersonnelDOB.Value.Day)) ? 1 : 0;
return years;
}
}
If it were me, I'd lean on NodaTime for this since you can calculate the Period between the date-of-birth and "today".
Per NodaTime's documentation:
A Period is a number of years, months, weeks, days, hours and so on, which can be added to (or subtracted from) a LocalDateTime, LocalDate or LocalTime. The amount of elapsed time represented by a Period isn't fixed: a period of "one month" is effectively longer when added to January 1st than when added to February 1st, because February is always shorter than January.
There's even a "recipe" for what you're trying to do within the documentation.
Adapted to your view model, it could look something like this:
public class PersonnelDOBViewModel
{
private readonly ZonedClock _clock;
public PersonnelDOBViewModel()
{
// Depending on your goals, you may want to use a user-defined
// time zone here
var timezone = DateTimeZoneProviders.Tzdb.GetSystemDefault();
_clock = SystemClock.Instance.InZone(timezone);
}
public DateTime? PersonnelDOB { get; set; }
public int? Age
{
get
{
if (PersonnelDOB == null)
{
return null;
}
var dob = LocalDate.FromDateTime(PersonnelDOB.Value);
var today = _clock.GetCurrentDate();
return Period.Between(dob, today).Years;
}
}
}
Try using DateTime.Now (or DateTime.UtcNow) instead of DateTime.Today.Year.
Also keep in mind that age calculations get tricky when you take time zone into account.
var age = dob.HasValue ? GetAge(dob.Value, DateTime.Now) : (int?)null;
private int GetAge(DateTime dob, DateTime currentTime)
{
var years = currentTime.Year - dob.Year;
if (currentTime.Month < dob.Month || (currentTime.Month == dob.Month && currentTime.Day < dob.Day))
{
years--;
}
return years;
}

How could I get months week number based on year week number (i.e week 33)

I'm wondering how can I calculate what is the week of the month based on the ordinal number of the week of the year. For example I'm dealing with week 33, I should know that's Week 2 in august.
I allready calculated months but now I'm dealing with weeks.
I allready have a solution, but it seems dirty to me..
Here's the code:
var data = query.GroupBy(x => CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(x.CreatedDate ?? DateTime.UtcNow, CalendarWeekRule.FirstDay, DayOfWeek.Monday))
.Select(article => new ArticleSimpleObject
{
Week = GetWeekNumberOfMonth(article.FirstOrDefault().CreatedDate.Value),
Amount = article.Sum(x => x.Amount),
Month = article.FirstOrDefault().CreatedDate.Value.Month
});
And here's the method which I used to get week numbers:
private static int GetWeekNumberOfMonth(DateTime date)
{
date = date.Date;
DateTime firstMonthDay = new DateTime(date.Year, date.Month, 1);
DateTime firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
if (firstMonthMonday > date)
{
firstMonthDay = firstMonthDay.AddMonths(-1);
firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
}
return (date - firstMonthMonday).Days / 7 + 1;
}
As I wrote guys, this solutions works,
but I personally don't like it, I guess there is more elegant solution, and that's why I posted this question to help to myself and to future readers if some experienced person helps us to solve this :)
Maybe this could be solved based on Calendar class https://learn.microsoft.com/en-us/dotnet/api/system.globalization.calendar?view=netframework-4.8
I've tried some variant but I was not even close to solve it..
Thanks guys
Cheers
One approach is to subtract the week of the year of the 1st day of the month of the date from the week of the year of the date. Like so:
void Main()
{
Console.WriteLine(DateTime.Now.GetWeekOfMonth());
}
public static class MyDateTimeExtensions
{
private static GregorianCalendar _calendar = new GregorianCalendar();
public static int GetWeekOfMonth(this DateTime date)
{
return
date.GetWeekOfYear()
- new DateTime(date.Year, date.Month, 1).GetWeekOfYear()
+ 1;
}
private static int GetWeekOfYear(this DateTime date)
{
return _calendar.GetWeekOfYear(
date,
CalendarWeekRule.FirstDay,
DayOfWeek.Sunday);
}
}
This outputs 4 for the current date: Sept. 23rd, 2019.
You can write a couple of general extensions to compute this a little bit simpler.
First, you need the first date of the week starting on a particular day of week for a date:
public static DateTime FirstDateOfWeekStarting(this DateTime aDate, DayOfWeek dow) => aDate.Date.AddDays((int)dow - (int)aDate.DayOfWeek);
Then, you can easily convert the day of month of that first date to the Week Number in the month:
public static int WeekStartingDOWNumOfMonth(this DateTime aDate, DayOfWeek dow) => (aDate.FirstDateOfWeekStarting(dow).Day-1) / 7 + 1;
And, for your specific case of weeks beginning with Monday,
public static int WeekStartingMonNumOfMonth(this DateTime aDate) => aDate.WeekStartingDOWNumOfMonth(DayOfWeek.Monday);

Calculate number of nights between 2 DateTimes [duplicate]

This question already has an answer here:
How can I calculate how many nights are there in a date range?
(1 answer)
Closed 7 years ago.
I have a start DateTime and an end DateTime and need to calculate the number of nights (not days) between the two with a default/minimum value being 1.
I've got
int NumberOfDays = Convert.ToInt32((EndDateTime - StartDateTime).Days)
Which returns the number of days so is always over by 1. I'm not sure that subtracting 1 from the result is an appropriate solution.
I have also tried
int NumberOfDays = Convert.ToInt32((EndDateTime - StartDateTime).ToDays)
Which also returns the same result.
Is there a smarter solution other than subtracting 1 every time and making sure it never returns a 0?
You can use extension method to make it simply reuse everywhere.
public static class DateTimeExtensions
{
public static int NumberOfNights(this DateTime date1, DateTime date2)
{
//feel free to make here better
var frm = date1 < date2 ? date1 : date2;
var to = date1 < date2 ? date2 : date1;
var totalDays = (int)(to-frm).TotalDays;
return totalDays > 1 ? totalDays : 1;
}
}
And use it like
var to = DateTime.Now.AddDays(3);
var frm = DateTime.Now;
frm.NumberOfNights(to)

Method to work out first day of financial year based on year parameter

Im trying to produce a simple method which can receive a financial year period in the following format:
2014-2015
I need the method to return a DateTime object, specifically the first day of that financial period, in the above case this would be 01/04/2014 00:00:00.000
I will also need to ultimately be able to work out the last day of that financial period but im not sure whether or not this should be a different method all together or in the same method with an additional parameter to indicate which date is required.
So far all I have been able to come up with is:
public static DateTime PermitValidFrom (string financialYear)
{
string startFinancialYear;
string endFinancialYear;
DateTime startOfFinancialYear;
startFinancialYear = financialYear.Substring(1, 4);
endFinancialYear = financialYear.Substring(6, 4);
//need to work out start of the financial year based on this period
return startOfFinancialYear;
}
I just don't know how to approach giving startOfFinancialYear a value, or even if there is a better way of going about doing this all together.
Apologies if this has been answered previously, but all I can find is examples which work out the start of a financial year based on the current DateTime.Now value, in my case this value may be different every time the method is invoked.
To clarify my question, the facts surrounding my task were the following:
Financial Year Start in this scenario will ALWAYS be 01/04 (the first of April)
Financial Year End in this scenario will ALWAYS be the last day of March.
If this is a Saturday, Sunday or any other day in this scenario is irrelevant.
All I have to go on is two years separated by a hyphen, from this I need the start of that financial year and the end of that financial year. I think the facts are pretty straight forward.
Anyway, seen as I received down votes and no real constructive feedback I ended up coming up with my own solution, and thought I would post it in case it helps anyone else.
public static DateTime FinancialPeriods(string financialYear, bool end)
{
string startFinancialYear;
string endFinancialYear;
DateTime startOfFinancialYear;
DateTime endOfFinancialYear;
startFinancialYear = financialYear.Substring(0, 4);
endFinancialYear = financialYear.Substring(5, 4);
startOfFinancialYear = new DateTime(int.Parse(startFinancialYear), 4, 1);
endOfFinancialYear = new DateTime(int.Parse(endFinancialYear), 4, 1).AddDays(-1);
if (end == false)
{
return startOfFinancialYear;
}
else
{
return endOfFinancialYear;
}
}
I would roll your own type, something like this:-
using System;
using System.Text.RegularExpressions;
public class FinancialPeriod
{
const string PATTERN = #"^([0-9]{4})\s?-\s?([0-9]{4})$";
public FinancialPeriod()
{
this.Year = DateTime.Today.Year;
if (DateTime.Today.Month > 3)
{
this.From = new DateTime(Year, 4, 1);
this.To = new DateTime(Year + 1, 3, DaysInMarch(Year + 1));
}
else
{
this.From = new DateTime(Year - 1, 4, 1);
this.To = new DateTime(Year, 3, DaysInMarch(Year));
}
}
public FinancialPeriod(string period) : this()
{
Match m = Regex.Match(period, PATTERN);
this.From = new DateTime(Int32.Parse(m.Groups[1].Value), 4, 1);
this.To = new DateTime(Int32.Parse(m.Groups[2].Value), 3, DaysInMarch(Int32.Parse(m.Groups[2].Value)));
}
private DateTime From { get; set; }
private DateTime To { get; set; }
private int Year { get; set; }
public string period
{
get
{
return string.Format("{0} - {1}", this.From.Year, this.To.Year);
}
}
private int DaysInMarch(int yr)
{
return DateTime.DaysInMonth(yr, 03);
}
}
Fiddle here

Get date of first Monday of the week? [duplicate]

This question already has answers here:
How can I get the DateTime for the start of the week?
(34 answers)
Closed 8 years ago.
I was wondering if you guys know how to get the date of currents week's monday based on todays date?
i.e 2009-11-03 passed in and 2009-11-02 gets returned back
/M
This is what i use (probably not internationalised):
DateTime input = //...
int delta = DayOfWeek.Monday - input.DayOfWeek;
DateTime monday = input.AddDays(delta);
The Pondium answer can search Forward in some case. If you want only Backward search I think it should be:
DateTime input = //...
int delta = DayOfWeek.Monday - input.DayOfWeek;
if(delta > 0)
delta -= 7;
DateTime monday = input.AddDays(delta);
Something like this would work
DateTime dt = DateTime.Now;
while(dt.DayOfWeek != DayOfWeek.Monday) dt = dt.AddDays(-1);
I'm sure there is a nicer way tho :)
public static class DateTimeExtension
{
public static DateTime GetFirstDayOfWeek(this DateTime date)
{
var firstDayOfWeek = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
while (date.DayOfWeek != firstDayOfWeek)
{
date = date.AddDays(-1);
}
return date;
}
}
International here. I think as extension it can be more useful.
What about:
CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek
Why don't use native solution?
var now = System.DateTime.Now;
var result = now.AddDays(-((now.DayOfWeek - System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 7) % 7)).Date;
Probably will return you with Monday. Unless you are using a culture where Monday is not the first day of the week.
Try this:
public DateTime FirstDayOfWeek(DateTime date)
{
var candidateDate=date;
while(candidateDate.DayOfWeek!=DayOfWeek.Monday) {
candidateDate=candidateDate.AddDays(-1);
}
return candidateDate;
}
EDIT for completeness: overload for today's date:
public DateTime FirstDayOfCurrentWeek()
{
return FirstDayOfWeek(DateTime.Today);
}

Categories

Resources