-3

How to accurately get difference(in years) between two DateTime objects in "Years"?

DateTime.Subtract() gives difference in TimeSpan and the maximum denomination is Days.

So, if I would want to get accurately, the difference between Today and a day in 1988(say 29th March 1988), is there an "easier" way to get the accurate age of this person?

What I've tried is:

DateTime March291988 = DateTime.Parse("29/03/1988");
TimeSpan ts = DateTime.Now.Subtract(March291988);
int years = (ts.Days/365);

More importantly, the question is: How to convert from TimeSpan to DateTime.

Aniket Inge
  • 25,375
  • 5
  • 50
  • 78

2 Answers2

13

I'm biased, but I'd use Noda Time:

var date1 = new LocalDate(1988, 3, 29);
var date2 = new LocalDate(2013, 1, 23); // See note below
var years = Period.Between(date1, date2, PeriodUnits.Years).Years;

Basically the BCL doesn't provide a hugely easy way of working with things like this - you really don't want a TimeSpan, because it's not anchored to a specific start/end point. You can subtract one Year value from another and then adjust if it does the wrong thing, but it's a bit icky.

Now in your original code, you used DateTime.Now. In Noda Time, we treat a clock as a dependency, with SystemClock.Instance being the normal production implementation. An IClock doesn't know about time zones - it just knows the current instant in time - so you have to say which time zone you're interested in. For example:

var today = clock.Now.InZone(zone).LocalDateTime.Date;

I know this seems long-winded, but it's isolating all the different conversions to make it all more explicit. (I may introduce a Date property on ZoneDateTime to reduce this slightly.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • NodaTime is cool.. Thanks. – Aniket Inge Jan 23 '13 at 10:01
  • Yes, I didnot want to use TimeSpan in any way possible. – Aniket Inge Jan 23 '13 at 10:02
  • is there a way to convert TimeSpan to DateTime? or convert DateTime to LocalDate()? – Aniket Inge Jan 23 '13 at 10:14
  • @Aniket: You can't convert from `TimeSpan` to `DateTime`, no. But you can use `LocalDateTime.FromDateTime` and then use the `Date` property to get a `LocalDate`. – Jon Skeet Jan 23 '13 at 10:25
  • Ah cool, just one more question, where can I get more docs on C#(5.0) and its libraries(the standard ones)(maybe as a PDF, so I can get a print).. also thanks for the link to NodaTime actually.. I will be using that in my current project. – Aniket Inge Jan 23 '13 at 10:28
  • @Aniket: That's a pretty unrelated question... MSDN is the best place for library stuff, and the C# 5 spec should be installed in your Visual Studio directory. (I don't think it's available for download yet.) – Jon Skeet Jan 23 '13 at 10:29
  • I am amazed at the amount of detailed knowledge you have in .NET and programming in general. And watched your talk on "Pushing the boundaries of the language" where you said read the specs to understand how and why of a language.. then do the evil thing of pushing the language to its limits. – Aniket Inge Jan 23 '13 at 10:31
  • And searched hard and long for the documents on the net(in PDF format). I couldn't find them – Aniket Inge Jan 23 '13 at 10:31
  • @Aniket: Well I doubt that you'll find much framework documentation in PDF format - it's all just online web pages. The spec is in Word, but you could presumably print to PDF. – Jon Skeet Jan 23 '13 at 11:08
  • Yes, I found the Spec and I was going through it. I just wanted to have an indepth understanding of the language. Is it possible to gain deep understanding of the language through that same spec in VS/Specifications/1033/ folder? – Aniket Inge Jan 23 '13 at 11:12
  • It doesn't matter where you find the spec, so long as you're using the version you want to learn about :) The one installed with Visual Studio 2012 will be for C# 5, so I'd use that. – Jon Skeet Jan 23 '13 at 11:17
  • That's awesome :-) thanks for everything Jon - btw, here is one more to that "Chuck Norris" style jokes: "If Jon Skeet were the Producer in Producer-Consumer problem, the Consumer would never run out of whatever he was consuming" – Aniket Inge Jan 23 '13 at 11:23
  • @JonSkeet please consider moving/copying/recreating this answer about "use NodaTime to compute difference between dates" to very popular duplicate . – Alexei Levenkov Sep 21 '16 at 16:22
  • @AlexeiLevenkov: Will do. – Jon Skeet Sep 21 '16 at 16:23
1

Here's how you can get the age in years:

static int AgeInYears(DateTime birthday, DateTime today)
{
    return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372;
}

This accounts for leap years, and will increment the age exactly on their birthday.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276