What is the easiest way to get years, months and days?

Post

Posted
Rating:
#1 (In Topic #968)
Enthusiast
gambafeliz is in the usergroup ‘Enthusiast’
 Happy New Year

I was wondering, What is the easiest way to get years, months and days?

Let me explain, I have two specific dates: "Purchase date" and "Date of return due to breakdown" and I want to present the user, for example:
Purchase date: DD/MM/YYYY 21/12/2022
Fault Date: DD/MM/YYYY 31/10/2024

1 years, 10 months and 20 days

It is possible that these years, months and days are wrong, but it is an example.

To the question, What is the easiest way that you can think of?

Thank you and have a Happy day, I mean, a wonderful day.

For your misfortunes I am Spanish and I only know Spanish, please, be patient with me, Thank you. :)
Online now: No Back to the top

Post

Posted
Rating:
#2
Avatar
Guru
cogier is in the usergroup ‘Guru’
To the question, What is the easiest way that you can think of?

Well, this had me thinking. 'Easy' it was not! I tried several solutions before coming up with this. This solution calculates all the days in the months between the 2 dates. For example, if the dates are 30/01/2023 to 01/03/2023 it will find all the days for January, February and March, 30 days will be deducted from the 31 of January and 30 from March leaving 1 month and 2 days.

Your example, 21/12/2022 to 31/10/2024 is 1 Year, 10 months and 10 days. See here. This routine will also produce the same result. Your example is very good as it has a leap year (2024) in it as well!

Thank you and have a Happy day, I mean, a wonderful day.
Thank you and may your 2023 be a happy one also. ¡Feliz año nuevo!     

Code (gambas)

  1. Public Sub Form_Open()
  2.  
  3.   Dim iYMD As Integer[]
  4.  
  5.   iYMD = GetPeriod(Date(2022, 12, 21), Date(2024, 10, 31))
  6.  
  7.   Message(Str(iYMD[0]) & " Years " & Str(iYMD[1]) & " Months " & Str(iYMD[2]) & " Days", "OK")
  8.  
  9.  
  10. Public Sub GetPeriod(dDate1 As Date, dDate2 As Date) As Integer[]                   'Returns the period between the first date and the last date in the format "YMD"
  11.  
  12.   Dim iMonths As Integer[] = [0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]     'Amount of days in each month
  13.   Dim iAllDays As New Integer[]                                                     'Array of all the days in each month
  14.   Dim iYMD As New Integer[]                                                         'To return in the format "YMD"
  15.   Dim iFirstday As Integer = Day(dDate1)                                            'First day of the first date
  16.   Dim iLastDay As Integer = Day(dDate2)                                             'Last day of the last date
  17.   Dim iFirstMonth As Integer = Month(dDate1)                                        'First month of first date
  18.   Dim iLastMonth As Integer = Month(dDate2)                                         'Last month of last date
  19.   Dim iFirstYear As Integer = Year(dDate1)                                          'First Year of first date
  20.   Dim iLastYear As Integer = Year(dDate2)                                           'Last Year of first date
  21.   Dim dWorkDate As Date = Date(iFirstYear, iFirstMonth, 1)                          'Used for calculations
  22.   Dim dFebCheck As Date                                                             'Used to check if February is 28 or 29 days
  23.  
  24.   Do
  25.     If Month(dWorkDate) = 2 Then                                                    'Is the month February?
  26.       Try dFebCheck = Date(Year(dWorkDate), 2, 29)                                  'Does February work?
  27.       If Error Then iMonths[2] = 28 Else iMonths[2] = 29                            'If no then 28 days else 29 days
  28.     Endif
  29.     iAllDays.Add(iMonths[Month(dWorkDate)])                                         'Add the amount of days in the month to the array
  30.     If Year(dWorkDate) = iLastYear And Month(dWorkDate) = iLastMonth Then Break     'If the end date has been reached then break out of the loop
  31.     dWorkDate = DateAdd(dWorkDate, gb.Month, 1)                                     'Add one month to the calculation and continue
  32.   Loop
  33.  
  34.   If iFirstday = iAllDays[0] Then                                                   'If the first day is the same as the last day of the first month then
  35.     iFirstDay = 0                                                                   'Set iFirstDay
  36.   Else
  37.     iFirstDay = iAllDays[0] - iFirstday                                             'Set iFirstDay
  38.  
  39.   iAllDays.Delete(0)                                                                'Delete the first item in the array
  40.  
  41.   If iLastDay = iAllDays[iAllDays.max] Then                                         'If the last day = the last day of the last month then
  42.     iLastDay = 0                                                                    'Set iLastDay
  43.   Else
  44.     iAllDays.pop()                                                                  'Delete the last month form the array
  45.  
  46.   iYMD.Add(iAllDays.Count / 12)                                                     'Calculate the years and add to the array
  47.   iYMD.Add(iAllDays.Count Mod 12)                                                   'Calculate the months and add to the array
  48.   iYMD.Add(iFirstDay + iLastDay)                                                    'Calculate the days and add to the array
  49.  
  50.   Return iYMD                                                                       'Return the array
  51.  
Online now: No Back to the top

Post

Posted
Rating:
#3
Enthusiast
gambafeliz is in the usergroup ‘Enthusiast’
 Hi cogier.

I hope you are feeling very well today. Look, I take my hat off to you. Thank you.

I'm thinking of another solution but first I have to create it since it's only in my head.

Thank you for everything, and I'm sorry in some way, that I have you very busy with my problem on the date that I have put it. Sorry about it.

Greetings with my wishes to wish you Health and Happiness.

For your misfortunes I am Spanish and I only know Spanish, please, be patient with me, Thank you. :)
Online now: No Back to the top

Post

Posted
Rating:
#4
Enthusiast
gambafeliz is in the usergroup ‘Enthusiast’
 Hi cogier

Your code is failing with these dates:
DD/MM/YYYY
10/12/2022
29/12/2022

So far this is what I have verified. Greeting.

For your misfortunes I am Spanish and I only know Spanish, please, be patient with me, Thank you. :)
Online now: No Back to the top

Post

Posted
Rating:
#5
Guru
BruceSteers is in the usergroup ‘Guru’
What about DateDiff ?
And i think you can use Val on a date string.

This works for me…
EDIT: NO IT DOES NOT!! Sorry , solution is in another post.

Code (gambas)

  1. Public Sub TimeSpan(date1 As String, date2 As String) As String
  2.  
  3.   Dim d1 As Date = Date(Val(date1))
  4.   Dim d2 As Date = Date(Val(date2))
  5.   Dim yr, mn, dy As Integer
  6.  
  7.   yr = DateDiff(d1, d2, gb.Year) - 1
  8.   d1 = DateAdd(d1, gb.Year, yr)
  9.   mn = DateDiff(d1, d2, gb.Month)
  10.   d1 = DateAdd(d1, gb.Month, mn)
  11.   dy = DateDiff(d1, d2, gb.Day)
  12.  
  13.   Return Subst("&1 years &2 months &3 days", yr, mn, dy)
  14.  
  15.  
Using your dates like this..

Code (gambas)

  1. Print TimeSpan("21/12/2022", "31/10/2024")
  2.  
gives me this…

1 years 10 months 10 days
Online now: No Back to the top

Post

Posted
Rating:
#6
Guru
BruceSteers is in the usergroup ‘Guru’
I edited the above routine because it was wrong.

How it works.

Sets the 2 dates using Val()
Year comparison is rounded up so have to decrease it.

then I add the years to the older date with DateAdd()
Then compare months.
then add months to older date
then compare days.

Hope it helps :)
Online now: No Back to the top

Post

Posted
Rating:
#7
Enthusiast
gambafeliz is in the usergroup ‘Enthusiast’
Happy New Year BruceS

My idea is similar to your logic. (It is not Work)

Code

   Dim sFechaCompra As String = "21/12/2022"
   Dim sFechaEstado As String = "31/10/2024"
         Dim iYear As Integer = Int(DateDiff(Val(sFechaCompra), Val(sFechaEstado), gb.Month) \ 12)
         Dim dFecha As Date = DateAdd(Val(sFechaCompra), gb.Year, iYear)
         Dim iMes As Integer = DateDiff(dFecha, Val(sFechaEstado), gb.Month)
         dFecha = DateAdd(dFecha, gb.Month, iMes)
         Dim iDia As Integer = Abs(DateDiff(dFecha, Val(sFechaEstado), gb.Day))         
         
         Message(iYear & " Years " & iMes & " Months " & iDia & " Days", "OK")

I think it works for me but I'm right now testing the code with the Web that cogier has ported

For your misfortunes I am Spanish and I only know Spanish, please, be patient with me, Thank you. :)
Online now: No Back to the top

Post

Posted
Rating:
#8
Guru
BruceSteers is in the usergroup ‘Guru’
Me ideas are all wrong sorry.
Online now: No Back to the top

Post

Posted
Rating:
#9
Enthusiast
gambafeliz is in the usergroup ‘Enthusiast’
Hi BruceS

Your code does not work well for me, it leaks everywhere, try the date that I have given as an example of:
DD/MM/YYYY
10/12/2022
29/12/2022

My code works but I don't know if it is exact in the calculations. I am going to count the days, months and years in case it is valid.

Note: I promise you this is going to be fun, let's go your heads and mine are going to smoke. :)

For your misfortunes I am Spanish and I only know Spanish, please, be patient with me, Thank you. :)
Online now: No Back to the top

Post

Posted
Rating:
#10
Enthusiast
gambafeliz is in the usergroup ‘Enthusiast’
 I am going to give you dates calculated by the web provided previously.

DD/MM/YYYY

10/12/2022  -  29/12/2022    0 year, 0 month, 19 days (Ok)
19/10/2021  -  09/12/2022    1 year, 1 month, 21 days (Ok)
26/09/2015  -  14/06/2021    5 year, 8 month, 20 days (Ok)
29/09/1998  -  04/10/2021   23 year, 0 month,  6 days (Ok)

For your misfortunes I am Spanish and I only know Spanish, please, be patient with me, Thank you. :)
Online now: No Back to the top

Post

Posted
Rating:
#11
Guru
BruceSteers is in the usergroup ‘Guru’
Right i got it working like this :)
(tested correct with the dates you gave in the last post)

Code (gambas)

  1. Public Sub TimeSpan(date1 As String, date2 As String) As String
  2.  
  3.   Dim d1 As Date = CDate(Val(date1))
  4.   Dim d2 As Date = CDate(Val(date2))
  5.   Dim yr, mn, dy, add As Integer
  6.  
  7.   yr = DateDiff(d1, d2, gb.Year)
  8.   If Month(d1) > Month(d2) Then Dec yr
  9.   d1 = DateAdd(d1, gb.Year, yr)
  10.  
  11.   mn = DateDiff(d1, d2, gb.Month)
  12.   If Day(d1) > Day(d2) Then
  13.     Dec mn
  14.     add = 1
  15.  
  16.   d1 = DateAdd(d1, gb.Month, mn)
  17.   dy = DateDiff(d1, d2, gb.Day) + add
  18.  
  19.   Return Subst("&1 years &2 months &3 days", yr, mn, dy)
  20.  
  21.  

Just needed to note if the year/month/day being checked was before or after and adjust accordingly
Passed like this..

Code (gambas)

  1. Print TimeSpan("10/12/2022", "29/12/2022")
  2. Print TimeSpan("19/10/2021", "09/12/2022")
  3. Print TimeSpan("26/09/2015", "14/06/2021")
  4. Print TimeSpan("29/09/1998", "04/10/2021")
  5.  

My Console said

0 years 0 months 19 days
1 years 1 months 21 days
5 years 8 months 20 days
23 years 0 months 6 days

Cheers for the puzzle :)
Online now: No Back to the top

Post

Posted
Rating:
#12
Enthusiast
gambafeliz is in the usergroup ‘Enthusiast’
:o  :shock:
Ole !!!
For me you are a machine.  Thank you for your masterful solution

For your misfortunes I am Spanish and I only know Spanish, please, be patient with me, Thank you. :)
Online now: No Back to the top

Post

Posted
Rating:
#13
Enthusiast
gambafeliz is in the usergroup ‘Enthusiast’
Hi BruceS

With your permission, I have corrected the code because it fails with this date:
DD/MM/YYYY
04/01/2023
02/01/2026

Code

Public Sub TimeSpan(date1 As String, date2 As String) As String
 
  Dim d1 As Date = CDate(Val(date1))
  Dim d2 As Date = CDate(Val(date2))
  Dim yr, mn, dy, add As Integer
 
  yr = DateDiff(d1, d2, gb.Year)
  If Month(d1) > Month(d2) Then Dec yr
  If Month(d1) = Month(d2) And Day(d1) > Day(d2) Then Dec yr   ' ADD
  d1 = DateAdd(d1, gb.Year, yr)
 
  mn = DateDiff(d1, d2, gb.Month)
  If Day(d1) > Day(d2) Then
    Dec mn
    add = 1
  Endif
 
  d1 = DateAdd(d1, gb.Month, mn)
  dy = DateDiff(d1, d2, gb.Day) + add
 
  Return Subst("&1 years &2 months &3 days", yr, mn, dy)
 
End

For your misfortunes I am Spanish and I only know Spanish, please, be patient with me, Thank you. :)
Online now: No Back to the top
1 guest and 0 members have just viewed this.