2

Whilst looking for the best way to do a "Relative time" conversion I came across this post

On my first test with a date of March 3 2013 (today is May 25 2013) the realitve time came back as 2 months ago.

That doesnt seem right to me as it should be 3. Is this a bug or is there a better way to do a relative time conversion?

Update: So I was using that code and created an extension method for example:

DateTime.Parse('2013-03-05T16:12:30Z').ToRelativeTime()

That would output 2 months ago.

Doing client side code with moment.js it produces 3 months ago.

I'd like to use any DateTime and be able to use the ToRelativeTime for past dates

Community
  • 1
  • 1
Jon
  • 38,814
  • 81
  • 233
  • 382
  • I would say it's a bug. Can you attach your code, please? – Fabian Bigler May 25 '13 at 13:55
  • Do you understand the code in that post? There are 83 days between March 3 and May 25, and the code measures one month as 30 days; `floor(83/30) = 2`. Why "should it be 3"? – 一二三 May 25 '13 at 13:57
  • Three months ago it was February, not March. Maybe you prefer rounding but that was unstated and probably not very appropriate. – Hans Passant May 25 '13 at 14:13

4 Answers4

2

That doesnt seem right to me as it should be 3.

Why? March 3rd was definitely less than three months ago... although admittedly closer to three than two. You need to work out exactly what rules you want.

My Noda Time project may well be useful to you here. For example:

using System;
using NodaTime;

class Test
{
    static void Main()
    {
        LocalDate start = new LocalDate(2013, 3, 3);
        LocalDate end = new LocalDate(2013, 5, 25);

        // Defaults to years, months and days - but you can change
        // that by specifying a PeriodUnits value.
        Period period = Period.Between(start, end);
        Console.WriteLine("{0} years, {1} months, {2} days",
                          period.Years, period.Months, period.Days);
    }
}

Noda Time always truncates towards zero, effectively - so if you ask for the months between x and y, it will return the largest number such that x + that many months is less tha or equal to y. It doesn't "overshoot" so to speak. If you want other rules, you may find you can implement them on top of those though.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

Use TimeSpan to represent differences in DateTime objects.

For you example of March 3 to May 25, a full 3 months have not passed yet. Not until June 3 will you get 3 months. Until then it's 2 months or 2.x months.

Matt Houser
  • 33,983
  • 6
  • 70
  • 88
1

It is also a matter of definition.

E.g. for banks there are only 360 days per year. So one month back is like 30 days back.

Also, if people say it was exactly one month back, they're meaning 'One month back, same day'. Which is in some cases more (e.g. July) or less (e.g. February) than the average of 30 days.

So what do you need now? Since the second case is more logical, you want to go two months back

In C#, you simply have to call the AddMonths-Function (25.05.2013 => 25.03.2013)

DateTime.AddMonths(-2)

EDIT: I passed some Datetimes to jeff's function: Here are some results:

DateTime.AddMonths(-2) => Returns two months ago.
DateTime.AddMonths(-2).AddDays(1) => Returns one month ago.
DateTime.AddMonths(-3) => Returns two months ago (!)

That's because it's using 30 days as a base:

int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));

Though as I pointed out, it's just a matter of definition.

Fabian Bigler
  • 10,403
  • 6
  • 47
  • 70
0

The post you referred was about jQuery and java which have different base of calculating date and day. If you use the same algorithm in javascript and C#, you will see sometimes different results by 1. Please check the javascript function of getting weeekday, you know what I mean.

Since your post is tagged with C#, you are actually asking C# .NET question. You may try DateTime.AddMonths(-2) and check the result.

ZZZ
  • 2,752
  • 2
  • 25
  • 37
  • Yes, both this question and the reference are tagged C#, but with javascript content. How about the moment.js source which I presume is javascript? – ZZZ May 25 '13 at 14:45
  • C# and javascript have different idea of calculating date and day. So sometime people get confusion. And you many not just copy the algorithm between C# and javascript. – ZZZ May 25 '13 at 14:46
  • A good way to tackle such inconvenient confusion is to create unit tests for both your javascript functions and C# functions, and some integration tests might be even better. – ZZZ May 25 '13 at 14:49