Getting the date difference in years months days.

Once again, and with all due respect, I am from a generation that uses calendars. Take anybody who uses that tool and ask him or her to count days, and chances are their way of counting will be days, then months.

Ask anybody to use his head (not his smart phone) to do the same, and the way to count will be days until the end of the month, then months, then days again. And most probably on fingers.

Ask someone to do the same on his Calendar application without jumping to a specialized Internet site, and watch how, once again, days will be counted until the end of the month.

Ask an accountant to calculate the same and I bet you he will proceed by calendar days. Let alone not to pay people on extra virtual days created by the method. Business usually considers months start on the first, not in the middle.

Now, the world will not come to an end because programmers, the Internet and Excel have their own idea about how actual life should be.

Please allow me the right to conceive my own world otherwise.

Ask your bank to calculate the same: each year will be 360 days long and each month 30 days (at least in Europe).

Sure : they want to miss daily interest profit on overdrafts and all sorts of credits.

I have to confess my ignorance when it comes to Germany, but in France, Luxembourg, Belgium and Spain, statements reflect interest charged on real, actual days when it comes to overdraft or term payment. Never on 30 days months. I am certain banks would not give you interest on the 31st for free.

The discussion between Tim and I does not hinge on the length of months, anyway. They could have 30 days or any other arbitrary length it would make no difference in the result. The 360 days year is fine.

What I call the Calendar day method that I use starts counting months on the first. So when the start date is before the end of the month, days are counted until the end of the month : 28,29,30 or 31, then full months are counted (whatever their length), then days are counted again from the first until the end date.

My issue businesswise is extremely simple and has to do with the difference in results: take your bank example. With Tim’s method, I will end up paying 16 days interest. With the Calendar method used by MBS and I, you pay only 12 days. Which do you prefer ?

To be fair, and the reason why I referred to that in a previous post, the only way both methods would be valid businesswise would be by counting days between the two dates. Because real life happens from 00:00 until midnight, on real, actual days. Not on the Internet, as far as I can tell. Schools, businesses, bank included, hospitals and the army count days by their place in the month from the first to the 28,29,30 or 31, not rolling months starting on the 20th.

This isn’t a business problem. Businesses deal with actual days, and that’s not what the question was. The OP is more akin to calculating a person’s age than anything else. The question is how do you express the span between dates in terms of 3 disparate units - years, months, and days. And until you said anything, I assumed there was a universal standard for it. I’ve never encountered anyone who uses your calendar method. And I’ve seen plenty of people with a calendar in hand flip the pages and put their finger on the 20th of each month and count months until they get to the last full month and then start counting days. It must be, as you said, a cultural thing.

It is no doubt a cultural, and maybe generational thing as well.

Still, and forgive me for being stubborn, time measurement is a precise science. The concept of month is tied to its definition as starting on the first and ending on ending on 28,29,30 or 31. If you care to look it up at Month - Wikipedia a month starts in relation to the lunar cycle, which is a very specific occurence in time, not an arbitrary duration starting on a random date.

Until defined otherwise, time units are the result of precise standards.

Now your example of measuring age is another matter, and your method is perfectly valid for that purpose, since a birthday occurs on the same day of the month.

As I wrote before, we are both right. Depends on the purpose of the time measurement.

I corrected my Excel method because it was wrong.
And I wrote it in RealStudio (I still developp with RealStudio to build in Xojo) :
DiffDateDaysMonthsYears.zip

Date are in the normal format, the French one :wink: which is Day / Month / Year

The Method

  Dim DiffDay, DiffMonth, DiffYear, NbDaysInMonthB as Int16
  Dim TampDate as Date
  
  TampDate = New Date(DateB) ' Usefull only if DiffDay < 0 but I display it in the TextField
  TampDate.Month = TampDate.Month + 1
  TampDate.Day = 1
  TampDate.TotalSeconds = TampDate.TotalSeconds - (24 *3600) ' 1 day previous
  NbDaysInMonthB = TampDate.Day
  TextFieldNbDaysInMont.Text = "There is " + str(NbDaysInMonthB) + " days in the month " + str(TampDate.Month) + " of year " + str(TampDate.Year)
  
  If DateA.TotalSeconds < DateB.TotalSeconds Then
    Beep
    TextFieldDiffDate.Text = "Error, DateA must be greater than DateB (or equal) !"
    
  Else
    DiffDay = DateA.Day - DateB.Day
    
    DiffMonth = DateA.Month - DateB.Month
    If DiffDay < 0 Then DiffMonth = DiffMonth - 1
    
    DiffYear = DateA.Year - DateB.Year
    If DiffMonth < 0 Then DiffYear = DiffYear - 1
    
    If DiffDay < 0 Then DiffDay = DiffDay + NbDaysInMonthB
    
    If DiffMonth < 0 Then DiffMonth = DiffMonth + 12
    
    TextFieldDiffDate.Text = str(DiffDay) + " days " + str(DiffMonth) + " months " + str(DiffYear) + " years"
    
  End If

And I f I do the difference between 28 february and 1 march I have 1 day (2 if bissextil).

I learned something with Tim. When I wanted to copy a date, I use a variant to copy DateA in variant and the variant in dateB. Because DateB = DateA make the 2 dates linked. I never thinked about write DateB = New DateA .

So, Michal, what is the span between 2014-02-20 and 2014-04-20? Is it 2 months or is it 1 month, 28 days? You’re being too literal. In everyday parlance, the span of one month is understood as being from the nth day of a month to the nth day of the next month. It doesn’t matter how many actual days that is.

[quote=127142:@Thomas ROBISSON]I corrected my Excel method because it was wrong.
And I wrote it in RealStudio (I still developp with RealStudio to build in Xojo) :
DiffDateDaysMonthsYears.zip

Date are in the normal format, the French one :wink: which is Day / Month / Year

The Method

  Dim DiffDay, DiffMonth, DiffYear, NbDaysInMonthB as Int16
  Dim TampDate as Date
  
  TampDate = New Date(DateB) ' Usefull only if DiffDay < 0 but I display it in the TextField
  TampDate.Month = TampDate.Month + 1
  TampDate.Day = 1
  TampDate.TotalSeconds = TampDate.TotalSeconds - (24 *3600) ' 1 day previous
  NbDaysInMonthB = TampDate.Day
  TextFieldNbDaysInMont.Text = "There is " + str(NbDaysInMonthB) + " days in the month " + str(TampDate.Month) + " of year " + str(TampDate.Year)
  
  If DateA.TotalSeconds < DateB.TotalSeconds Then
    Beep
    TextFieldDiffDate.Text = "Error, DateA must be greater than DateB (or equal) !"
    
  Else
    DiffDay = DateA.Day - DateB.Day
    
    DiffMonth = DateA.Month - DateB.Month
    If DiffDay < 0 Then DiffMonth = DiffMonth - 1
    
    DiffYear = DateA.Year - DateB.Year
    If DiffMonth < 0 Then DiffYear = DiffYear - 1
    
    If DiffDay < 0 Then DiffDay = DiffDay + NbDaysInMonthB
    
    If DiffMonth < 0 Then DiffMonth = DiffMonth + 12
    
    TextFieldDiffDate.Text = str(DiffDay) + " days " + str(DiffMonth) + " months " + str(DiffYear) + " years"
    
  End If

And I f I do the difference between 28 february and 1 march I have 1 day (2 if bissextil).

I learned something with Tim. When I wanted to copy a date, I use a variant to copy DateA in variant and the variant in dateB. Because DateB = DateA make the 2 dates linked. I never thinked about write DateB = New DateA .[/quote]

Thomas, I just tried your posted code, and several variables where not initialized. Maybe they are properties in your project.

Here is what I added :

Dim TampDate as new Date // lacked the 'new' Dim DateB as new date(2013,2,20) Dim DateA as new date(2014,2,5)

Apart form that, I see you count days until the end of the month. As Tim would note, must be a cultural difference (smile).

There is yet one difference with Christian’s TimeDifferenceMBS : you seem to include the day of the starting date, so you get 13 days where MBS finds 12, probably because he starts counting the day after.

In a way, his method uses an hour counting analogous to the calendar way of counting days : if the time on the starting date is 00:00 his method produces 13 days. If time has elapsed the day has started, so he counts the time until the end of the day, then starts counting days until the end of the month.

This whole discussion about what started as a seemingly simple problem is interesting since it shows how time measurement could be relative to the context.

And is the span from 2014-02-20 to 2014-02-21, “2 months, 1 day” or “1 month, 29 days”?

Once again, all is a matter of context… From what you say, I must conclude you mistyped the second date, and intended to write 2014-04-21. Otherwise I would answer “one day”, if time is the same on the two dates :wink:

I am not trying to fight you, here. Human beings have a way to understand things that varies with the circumstances and customs. We started with a code issue. Code is a precise science. One method produces different results from another, and through Thomas late effort, I realized Christian had yet another approach based on time which produced different results.

No doubt since 20 and 21 are very close, human beings in casual conversation would not bother counting and would say “two months one day”. It would be another matter for an accountant. Or TimeDifferenceMBS, which takes into account the time on start and ending date.

Oops, you’re right, typo.

I assumed that the OP was interested in the result from, as you say, “casual conversation”, which the computer is able to re-create based on a few heuristics (read: edge-cases). It was, as I understood it, not a matter for an accountant.

I never felt your intent was to pick a fight, but to explore the nuances of this topic, which are quite interesting. I hope I haven’t come across as combative, either. Well, maybe my last post. :wink: Sorry.

[quote=127159:@Tim Hare]Oops, you’re right, typo.

I assumed that the OP was interested in the result from, as you say, “casual conversation”, which the computer is able to re-create based on a few heuristics (read: edge-cases). It was, as I understood it, not a matter for an accountant.

I never felt your intent was to pick a fight, but to explore the nuances of this topic, which are quite interesting. I hope I haven’t come across as combative, either. Well, maybe my last post. :wink: Sorry.[/quote]

Same thing. I did not want to dismiss your approach, but was more interested in the different ways of getting to a result.

This has been an interesting conversation. Thank you for allowing me to exchange ideas.

Yes, the DateA and DateB are properties. I set them with each button “DateA” and “DateB”.

I’ve to check if, when I get the count of days in a month, what happens when I do Date.month = Date.month + 1 if date is December.
Edit : Tested, it seems Xojo automatically put january and year + 1.

I did a Method to obtain the last day of a date :

[code]Function LastDayOfDate(ThisDate as Date) As Int16

ThisDate.Day = 1
If ThisDate.Month = 12 Then ’ It seems that Xojo do that automatically but …
ThisDate.Month = 1
ThisDate.Year = ThisDate.Year + 1
Else
ThisDate.Month = ThisDate.Month + 1
End If
ThisDate.TotalSeconds = ThisDate.TotalSeconds - 86400 ’ = (24 h *3600 s) ’ 1 day previous

Return ThisDate.Day

End Function
[/code]
And I do “ThisDate.Day = 1” first because if I change the month to a mont of less than 31 days with ThisDate.Day = 31 :confused: It may cause bug.

But I have a trouble, I do

NbDaysInMonthB = LastDayOfDate(DateB)

But DateB is changed, its day become 1 and its month is +1 (that I do for ThisDate in the Method).
Then how pass a date to a function without linked them (the Date passed and the Date used in the function)?
I tried “Function LastDayOfDate(ThisDate as New Date) As Int16” but it doesn’t work.
Neither than “NbDaysInMonthB = LastDayOfDate(New DateB)

Edit : I added in my function “ThisDate = New Date(ThisDate)” and it works but isn’t there another way?

No, that is the correct approach. There is no better way.

Yes, it does. It is very convenient.

Then, I post my solution, like that if someone want it after a search :

[code]Function LastDayOfDate(ThisDate as Date) As Int16

ThisDate = New Date(ThisDate) ’ This function return the count of days in a month, depending of the year for leap year (anne bissextile)
ThisDate.Day = 1
If ThisDate.Month = 12 Then ’ It seems that Xojo do that automatically but
ThisDate.Month = 1
ThisDate.Year = ThisDate.Year + 1
Else
ThisDate.Month = ThisDate.Month + 1
End If
ThisDate.TotalSeconds = ThisDate.TotalSeconds - 86400 ’ = (24 h *3600 s) ’ 1 day previous

Return ThisDate.Day

End Function
[/code]

[code]Sub DiffDateDaysMonthsYears(DateA as Date, DateB as Date)

Dim DiffDay, DiffMonth, DiffYear, NbDaysInMonthB as Int16
Dim TampDate as Date
Dim DiffSign as String

If DateA.TotalSeconds < DateB.TotalSeconds Then ’ DateA must be greater than DateB (or equal)
TampDate = New Date(DateB)
DateB = New Date(DateA)
DateA = New Date(TampDate)
DiffSign = "- "
Else
DateA = New Date(DateA)
DateB = New Date(DateB)
DiffSign = "+ "
End If

DateA.Hour = 12 ’ For the test below
DateA.Minute = 0
DateA.Second = 0
DateB.Hour = 12
DateB.Minute = 0
DateB.Second = 0
If DateA.TotalSeconds = DateB.TotalSeconds Then DiffSign = " " ’ Because maybe just the time was different, and I don’t want a sign + or - if equal

NbDaysInMonthB = LastDayOfDate(DateB) ’ Usefull only if DiffDay < 0 but I display it in the TextField
TextFieldNbDaysInMont.Text = "There is " + str(NbDaysInMonthB) + " days in the month " + str(DateB.Month) + " of year " + str(DateB.Year)

DiffDay = DateA.Day - DateB.Day

DiffMonth = DateA.Month - DateB.Month
If DiffDay < 0 Then DiffMonth = DiffMonth - 1

DiffYear = DateA.Year - DateB.Year
If DiffMonth < 0 Then DiffYear = DiffYear - 1

If DiffDay < 0 Then DiffDay = DiffDay + NbDaysInMonthB

If DiffMonth < 0 Then DiffMonth = DiffMonth + 12

TextFieldDiffDate.Text = DiffSign + str(DiffDay) + " days " + str(DiffMonth) + " months " + str(DiffYear) + " years"

End Sub
[/code]

DiffDateDaysMonthsYears.zip

Michel, you wrote “Dim TampDate as new Date // lacked the ‘new’”
I don’t understand why you added the new in my case?
I understand with first Tim exemple that write New Date brake the link between the 2 dates when creating a date from another one.
But here ? As I create an empty date?

[quote=127182:@Thomas ROBISSON]Michel, you wrote “Dim TampDate as new Date // lacked the ‘new’”
I don’t understand why you added the new in my case?
I understand with first Tim exemple that write New Date brake the link between the 2 dates when creating a date from another one.
But here ? As I create an empty date?[/quote]

I got an error when I tried to run your code without. Create New is the documented constructor. As far as I can figure, Date is an object, not a variable, so you have to create a new instance.

But I could be wrong…

An observation after reading this thread… this is a good example why some XOJO lurkers will opt to use something else.

Comments about someone’s suggestions should be positive and constructive rather than negative and demeaning.