digitalmars.D.learn - The difference between the dates in years
- Alexander Zhirov (9/9) Feb 10 Is it possible to calculate the difference between dates in years
- H. S. Teoh (10/23) Feb 10 IIRC you can just subtract two DateTime's to get a Duration that you can
- Alexander Zhirov (8/32) Feb 10 I did it this way, but there will be an inaccuracy, since
- Alexander Zhirov (16/51) Feb 10 ```
- matheus (48/49) Feb 10 Maybe this will help: I think if you will divide it can't be 365,
- Jonathan M Davis (80/89) Feb 10 Well, diffMonths could be used to build what you want, but std.datetime
- Lance Bachmeier (24/33) Feb 10 I'm assuming you mean you want the number of full years between
- Lance Bachmeier (13/51) Feb 10 should be
- Brad Roberts (9/22) Feb 10 Back when I was doing lots of software developer interviews, one of my
- matheus (5/14) Feb 10 Interesting but I have a doubt, they (Interviewees) should do the
- Brad Roberts (8/24) Feb 10 My interviews were never tests, they were discussions that might also
- Jonathan M Davis (11/19) Feb 10 Indeed. And because it seems simple at first, it's very common for code ...
- Steven Schveighoffer (5/14) Feb 10 Maybe I'm not understanding the question, but why not that result
- Jonathan M Davis (8/25) Feb 10 If I understand correctly, he cares about how far into the month the dat...
- Steven Schveighoffer (9/17) Feb 10 I thought `diffMonths` was actually already taking this into
- Jonathan M Davis (12/28) Feb 10 Possibly. Given the trickiness involved, there probably should be a func...
- Steven Schveighoffer (19/28) Feb 10 OK, so I thought this was already taking into account the day of
Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.
Feb 10
On Sat, Feb 10, 2024 at 03:53:09PM +0000, Alexander Zhirov via Digitalmars-d-learn wrote:Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.IIRC you can just subtract two DateTime's to get a Duration that you can then convert into whatever units you want. Only thing is, in this case conversion to months may not work because months don't have a fixed duration (they can vary from 28 days to 31 days) so there is no "correct" way of computing it, you need to program it yourself according to the exact calculation you want. T -- PNP = Plug 'N' Pray
Feb 10
On Saturday, 10 February 2024 at 16:03:32 UTC, H. S. Teoh wrote:On Sat, Feb 10, 2024 at 03:53:09PM +0000, Alexander Zhirov via Digitalmars-d-learn wrote:I did it this way, but there will be an inaccuracy, since somewhere there may be 366 days, and somewhere 365 ``` auto d = cast(Date)Clock.currTime() - Date.fromISOExtString("2001-02-01"); writeln(d.total!"days"().to!int / 365); ```Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.IIRC you can just subtract two DateTime's to get a Duration that you can then convert into whatever units you want. Only thing is, in this case conversion to months may not work because months don't have a fixed duration (they can vary from 28 days to 31 days) so there is no "correct" way of computing it, you need to program it yourself according to the exact calculation you want. T
Feb 10
On Saturday, 10 February 2024 at 18:12:07 UTC, Alexander Zhirov wrote:On Saturday, 10 February 2024 at 16:03:32 UTC, H. S. Teoh wrote:``` int getDiffYears(string date) { auto currentDate = cast(Date)Clock.currTime(); auto startDate = Date.fromISOExtString(date); auto currentDay = currentDate.dayOfYear; auto startDay = startDate.dayOfYear; auto currentMonth = currentDate.month; auto startMonth = startDate.month; auto diffDays = currentDate - startDate; auto diffYears = diffDays.total!"days"().to!int / 365; return currentMonth >= startMonth && currentDay >= startDay ? diffYears : diffYears - 1; } ```On Sat, Feb 10, 2024 at 03:53:09PM +0000, Alexander Zhirov via Digitalmars-d-learn wrote:I did it this way, but there will be an inaccuracy, since somewhere there may be 366 days, and somewhere 365 ``` auto d = cast(Date)Clock.currTime() - Date.fromISOExtString("2001-02-01"); writeln(d.total!"days"().to!int / 365); ```Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.IIRC you can just subtract two DateTime's to get a Duration that you can then convert into whatever units you want. Only thing is, in this case conversion to months may not work because months don't have a fixed duration (they can vary from 28 days to 31 days) so there is no "correct" way of computing it, you need to program it yourself according to the exact calculation you want. T
Feb 10
On Saturday, 10 February 2024 at 19:16:35 UTC, Alexander Zhirov wrote:...Maybe this will help: I think if you will divide it can't be 365, but 365.242199. About your code: I having tested fully, but I found a few problems and I wrote (Again without further tests) as below: import std; int getDiffYears(string date) { auto currentDate = cast(Date)Clock.currTime(); auto startDate = Date.fromISOExtString(date); auto currentDay = currentDate.dayOfYear; auto startDay = startDate.dayOfYear; auto currentMonth = currentDate.month; auto startMonth = startDate.month; auto diffDays = currentDate - startDate; auto diffYears = diffDays.total!"days"().to!int / 365; return currentMonth >= startMonth && currentDay >= startDay ? diffYears : diffYears - 1; } int getDiffYears2(string date) { auto now = cast(Date)Clock.currTime(); auto from = Date.fromISOExtString(date); auto dy = now.year-from.year; auto dm = (from.month-now.month); auto dd = (dm == 0 && from.day>now.day); return dy - 1 * (dm > 0 || dd); } void main(){ writeln("2001-02-09 is ", getDiffYears("2001-02-09")); writeln("2001-02-10 is ", getDiffYears("2001-02-10")); writeln("2001-02-11 is ", getDiffYears("2001-02-11")); writeln("2001-03-01 is ", getDiffYears("2001-03-01")); writeln(""); writeln("2001-02-09 is ", getDiffYears2("2001-02-09")); writeln("2001-02-10 is ", getDiffYears2("2001-02-10")); writeln("2001-02-11 is ", getDiffYears2("2001-02-11")); writeln("2001-03-01 is ", getDiffYears2("2001-03-01")); } Output: 2001-02-09 is 23 2001-02-10 is 23 2001-02-11 is 22 2001-03-01 is 21 2001-02-09 is 23 2001-02-10 is 23 2001-02-11 is 22 2001-03-01 is 22 Matheus.
Feb 10
On Saturday, February 10, 2024 8:53:09 AM MST Alexander Zhirov via Digitalmars-d-learn wrote:Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.Well, diffMonths could be used to build what you want, but std.datetime doesn't really provide a direct solution for it. Subtracting one Date from another gives you a Duration, but that doesn't take the month or year into account, because the lengths of the months are variable. diffMonths is the solution to get around that, since it does take the exact years and months involved to give you the number of months. However, it doesn't take the days of the month into account. It's just diffing the months themselves, and any day of the month counts as being part of that month. However, after some mucking around, I think that I have a solution built on top of diffMonths, though of course, it's possible that I screwed up somewhere with my test dates. I named it yearsApart rather than diffYears, since unlike diffMonths, it does take the smaller units into account. But of course, you can name it whatever you want. import std.datetime.date : Date; int yearsApart(Date lhs, Date rhs) { auto months = lhs.diffMonths(rhs); auto years = months / 12; if(years == 0) return 0; auto remainder = months % 12; if(remainder != 0) return years; if(months >= 0) return lhs.day >= rhs.day ? years : years - 1; return lhs.day <= rhs.day ? years : years + 1; } unittest { assert(yearsApart(Date(1999, 3, 1), Date(1999, 1, 1)) == 0); assert(yearsApart(Date(1999, 1, 1), Date(1999, 3, 1)) == 0); assert(yearsApart(Date(1999, 3, 1), Date(1998, 1, 1)) == 1); assert(yearsApart(Date(1998, 3, 1), Date(1999, 1, 1)) == 0); assert(yearsApart(Date(2000, 12, 1), Date(1995, 12, 1)) == 5); assert(yearsApart(Date(1995, 12, 1), Date(2000, 12, 1)) == -5); assert(yearsApart(Date(2000, 12, 2), Date(1995, 12, 1)) == 5); assert(yearsApart(Date(1995, 12, 1), Date(2000, 12, 2)) == -5); assert(yearsApart(Date(2000, 12, 1), Date(1995, 12, 2)) == 4); assert(yearsApart(Date(1995, 12, 2), Date(2000, 12, 1)) == -4); assert(yearsApart(Date(2000, 2, 29), Date(1999, 2, 28)) == 1); assert(yearsApart(Date(1999, 2, 28), Date(2000, 2, 29)) == -1); assert(yearsApart(Date(2000, 2, 29), Date(1999, 3, 1)) == 0); assert(yearsApart(Date(1999, 3, 1), Date(2000, 2, 29)) == 0); assert(yearsApart(Date(2000, 2, 29), Date(1998, 3, 1)) == 1); assert(yearsApart(Date(1998, 3, 1), Date(2000, 2, 29)) == -1); assert(yearsApart(Date(2001, 3, 1), Date(2000, 2, 29)) == 1); assert(yearsApart(Date(2000, 2, 29), Date(2001, 3, 1)) == -1); assert(yearsApart(Date(2005, 3, 1), Date(2000, 2, 29)) == 5); assert(yearsApart(Date(2004, 3, 1), Date(2000, 2, 29)) == 4); assert(yearsApart(Date(2003, 3, 1), Date(2000, 2, 29)) == 3); assert(yearsApart(Date(2002, 3, 1), Date(2000, 2, 29)) == 2); assert(yearsApart(Date(2001, 3, 1), Date(2000, 2, 29)) == 1); assert(yearsApart(Date(2000, 3, 1), Date(2000, 2, 29)) == 0); assert(yearsApart(Date(2000, 2, 29), Date(2001, 3, 1)) == -1); assert(yearsApart(Date(2000, 2, 29), Date(2002, 3, 1)) == -2); assert(yearsApart(Date(2000, 2, 29), Date(2003, 3, 1)) == -3); assert(yearsApart(Date(2000, 2, 29), Date(2004, 3, 1)) == -4); assert(yearsApart(Date(2000, 2, 29), Date(2005, 3, 1)) == -5); assert(yearsApart(Date(2005, 2, 28), Date(2000, 2, 29)) == 4); assert(yearsApart(Date(2004, 2, 29), Date(2000, 2, 29)) == 4); assert(yearsApart(Date(2004, 2, 28), Date(2000, 2, 29)) == 3); assert(yearsApart(Date(2003, 2, 28), Date(2000, 2, 29)) == 2); assert(yearsApart(Date(2002, 2, 28), Date(2000, 2, 29)) == 1); assert(yearsApart(Date(2001, 2, 28), Date(2000, 2, 29)) == 0); assert(yearsApart(Date(2000, 2, 29), Date(2000, 2, 29)) == 0); assert(yearsApart(Date(2000, 2, 28), Date(2000, 2, 29)) == 0); assert(yearsApart(Date(2000, 2, 29), Date(2000, 2, 28)) == 0); assert(yearsApart(Date(2000, 2, 29), Date(2000, 2, 29)) == 0); assert(yearsApart(Date(2000, 2, 29), Date(2001, 2, 28)) == 0); assert(yearsApart(Date(2000, 2, 29), Date(2002, 2, 28)) == -1); assert(yearsApart(Date(2000, 2, 29), Date(2003, 2, 28)) == -2); assert(yearsApart(Date(2000, 2, 29), Date(2004, 2, 28)) == -3); assert(yearsApart(Date(2000, 2, 29), Date(2004, 2, 29)) == -4); assert(yearsApart(Date(2000, 2, 29), Date(2005, 2, 28)) == -4); } - Jonathan M Davis
Feb 10
On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote:Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.I'm assuming you mean you want the number of full years between the dates. If so, I use something like this: ``` import std; void main() { writeln(fullYears(Date(1999, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 4, 1))); writeln(fullYears(Date(2006, 4, 1), Date(1999, 4, 1))); } bool earlierInYear(Date date1, Date date2) { return date1 < Date(date1.year, date2.month, date2.day); } long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year, 0); } else { return date1.year - date2.year; } } ```
Feb 10
On Saturday, 10 February 2024 at 21:56:30 UTC, Lance Bachmeier wrote:On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote:should be ``` long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year - 1, 0); } else { return date1.year - date2.year; } } ```Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.I'm assuming you mean you want the number of full years between the dates. If so, I use something like this: ``` import std; void main() { writeln(fullYears(Date(1999, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 4, 1))); writeln(fullYears(Date(2006, 4, 1), Date(1999, 4, 1))); } bool earlierInYear(Date date1, Date date2) { return date1 < Date(date1.year, date2.month, date2.day); } long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year, 0); } else { return date1.year - date2.year; } } ```
Feb 10
Back when I was doing lots of software developer interviews, one of my frequent questions involved date math. This wasn't because it's difficult from a coding standpoint, but that it's NOT a coding problem. The key part of the question is realization that it's a requirements question. The thing that makes dates complicated is defining what the question actually is. The topic _seems_ like it should be simple, but the deeper you dig the more you realize it's anything but simple. On 2/10/2024 7:53 AM, Alexander Zhirov via Digitalmars-d-learn wrote:Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.
Feb 10
On Saturday, 10 February 2024 at 22:11:48 UTC, Brad Roberts wrote:Back when I was doing lots of software developer interviews, one of my frequent questions involved date math. This wasn't because it's difficult from a coding standpoint, but that it's NOT a coding problem. The key part of the question is realization that it's a requirements question. The thing that makes dates complicated is defining what the question actually is. The topic _seems_ like it should be simple, but the deeper you dig the more you realize it's anything but simple.Interesting but I have a doubt, they (Interviewees) should do the test with already existing Date Functions of given language or write new ones? Matheus.
Feb 10
On 2/10/2024 6:01 PM, matheus via Digitalmars-d-learn wrote:On Saturday, 10 February 2024 at 22:11:48 UTC, Brad Roberts wrote:My interviews were never tests, they were discussions that might also involve coding tasks. In this case, the discussion was about requirements gathering disguised initially as a coding task. By and large, I never put a lot of weight on the coding parts themselves and mostly focused on problem solving and thinking skills. If the candidate couldn't get past writing code and wouldn't ask questions, that was a very bad sign.Back when I was doing lots of software developer interviews, one of my frequent questions involved date math. This wasn't because it's difficult from a coding standpoint, but that it's NOT a coding problem. The key part of the question is realization that it's a requirements question. The thing that makes dates complicated is defining what the question actually is. The topic _seems_ like it should be simple, but the deeper you dig the more you realize it's anything but simple.Interesting but I have a doubt, they (Interviewees) should do the test with already existing Date Functions of given language or write new ones? Matheus.
Feb 10
On Saturday, February 10, 2024 3:11:48 PM MST Brad Roberts via Digitalmars-d- learn wrote:Back when I was doing lots of software developer interviews, one of my frequent questions involved date math. This wasn't because it's difficult from a coding standpoint, but that it's NOT a coding problem. The key part of the question is realization that it's a requirements question. The thing that makes dates complicated is defining what the question actually is. The topic _seems_ like it should be simple, but the deeper you dig the more you realize it's anything but simple.Indeed. And because it seems simple at first, it's very common for code to be written which does the wrong thing with regards to dates and times - often which seems like it does the right thing, because it works a lot of the time, when in fact, there are edge cases where it definitely does the wrong thing (e.g. with regards to leap years or DST). And math around months is a prime area where it's difficult to get right in part because different people have different requirements depending on the actual problem that they're trying to solve. - Jonathan M Davis
Feb 10
On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote:Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.Maybe I'm not understanding the question, but why not that result / 12? -Steve
Feb 10
On Saturday, February 10, 2024 4:20:33 PM MST Steven Schveighoffer via Digitalmars-d-learn wrote:On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote:If I understand correctly, he cares about how far into the month the dates are, whereas diffMonths ignores the smaller units, meaning that you get the same result no matter when in the month the dates are. So, 2000-05-10 - 1990-05-09 would give 10, whereas 2000-05-10 - 1990-05-30 would give 9. diffMonths / 12 would give 10 in both cases. - Jonathan M DavisIs it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.Maybe I'm not understanding the question, but why not that result / 12?
Feb 10
On Saturday, 10 February 2024 at 23:48:56 UTC, Jonathan M Davis wrote:If I understand correctly, he cares about how far into the month the dates are, whereas diffMonths ignores the smaller units, meaning that you get the same result no matter when in the month the dates are. So, 2000-05-10 - 1990-05-09 would give 10, whereas 2000-05-10 - 1990-05-30 would give 9. diffMonths / 12 would give 10 in both cases.I thought `diffMonths` was actually already taking this into account... Looking at the impl, it's pretty simple. Would it make sense to have an overload that takes into account the day as well as the month/year? This kind of stuff is sometimes tricky to get right. -Steve
Feb 10
On Saturday, February 10, 2024 7:31:47 PM MST Steven Schveighoffer via Digitalmars-d-learn wrote:On Saturday, 10 February 2024 at 23:48:56 UTC, Jonathan M Davis wrote:Possibly. Given the trickiness involved, there probably should be a function in std.datetime to handle it, but I'll have to think about what the best way to do it would be in terms of the API. It is kind of similar to how some functions behave differently depending on how you want to treat the end of the month (e.g. whether adding a month to May 31st gives you June 30th or July 1st), but it's also not quite the same. So, the enum related to that wouldn't be appropriate, but it's yet another edge case where sometimes you want one behavior, and at other times, you want the other behavior. - Jonathan M DavisIf I understand correctly, he cares about how far into the month the dates are, whereas diffMonths ignores the smaller units, meaning that you get the same result no matter when in the month the dates are. So, 2000-05-10 - 1990-05-09 would give 10, whereas 2000-05-10 - 1990-05-30 would give 9. diffMonths / 12 would give 10 in both cases.I thought `diffMonths` was actually already taking this into account... Looking at the impl, it's pretty simple. Would it make sense to have an overload that takes into account the day as well as the month/year? This kind of stuff is sometimes tricky to get right.
Feb 10
On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote:Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly.OK, so I thought this was already taking into account the day of the month. This is what I came up with: ```d int diffMonthNew(Date d1, Date d2) { auto diff = d1.diffMonths(d2); if(diff > 0) return diff + (d1.day < d2.day ? -1 : 0); else if(diff < 0) return diff + (d1.day > d2.day ? 1 : 0); return 0; } ``` Then if you want the years, it would be `diffMonthNew(d1, d2) / 12` -Steve
Feb 10