Page 1 of 1
DateDiff ?
Posted: Wed Dec 20, 2006 4:18 pm
by va!n
I have a little problem to calculate the time different between two days/times. If someone can show me a working way, it would be nice. What i need is something like:
Procedure Diff (sTimeStamp1.s, sTimeStamp2.s) ; sTimeStamp.s = like 1166173200
Result = "x Years, x Months, x Days, x Hours, x Minutes, x Seconds"
thanks.
Posted: Wed Dec 20, 2006 4:36 pm
by Tranquil
This is difficult to calculate course there are month with 28/30/31 days. How many days do you want to expect in your difference calculation? 31?
And why holding the timevalue in a string?
Posted: Wed Dec 20, 2006 4:48 pm
by Trond
Code: Select all
DateDifference = DateLate-DateEarly
Code: Select all
Procedure.l YearDiff(Date)
ProcedureReturn Year(Date)-1970
EndProcedure
Procedure.l MonthDiff(Date)
ProcedureReturn Month(Date)-1
EndProcedure
Procedure.l DayDiff(Date)
ProcedureReturn Day(Date)-1
EndProcedure
Debug YearDiff(DateDifference)
Debug MonthDiff(DateDifference)
Debug DayDiff(DateDifference)
Debug Hour(DateDifference)
Debug Minute(DateDifference)
Debug Second(DateDifference)
Posted: Wed Dec 20, 2006 5:09 pm
by netmaestro
Won't work, Trond, because the pattern of months will rarely line up properly. Take a six-month date difference, the months will always be assumed to be jan-feb-mar-apr-may-june, which will affect the number of days returned. See the error with these dates:
Code: Select all
dateearly = ParseDate("%yyyy/%mm/%dd/%hh:%ii:%ss", "2006/6/01/00:00:00")
datelate = Date()
Too many days! Also - leap years counted in the wrong place will throw it off by a whole day for longer differences.
Posted: Sat Dec 30, 2006 10:34 pm
by atnheaderlen
Date (...) returns the seconds if a date is entered.
If you do that with the beginn-date and end-date and after this subtract the values you get the difference in seconds. It should be easy to get the days/months/years then.
Posted: Sun Dec 31, 2006 12:14 am
by jear
This code will return the time difference as string.
Code: Select all
; TimeDiffString : jear Dez 2005
;#TimeUnits = "Woche|n,Tag|e,Stunde|n,Minute|n,Sekunde|n"
#TimeUnits = "week|s,day|s,hour|s,minute|s,second|s"
Procedure.s AddTimeUnit(number.l, unit.l)
Protected Result.s, sUnit.s
If number = 0 : ProcedureReturn "" : EndIf
If number < 0 : number * -1 : EndIf
sUnit = StringField(#TimeUnits, unit, ",")
If number > 1
sUnit = RemoveString(sUnit, "|")
Else
sUnit = StringField(sUnit, 1, "|")
EndIf
Result + Space(1) + Str(number) + Space(1) + sUnit
ProcedureReturn Result
EndProcedure
Procedure.s sTimeDiff(Seconds.l)
Protected Result.s
Protected Weeks.l, Days.l, Hours.l, Minutes.l
Weeks = Seconds / 604800 : Seconds = Seconds % 604800
Days = Seconds / 86400 : Seconds = Seconds % 86400
Hours = Seconds / 3600 : Seconds = Seconds % 3600
Minutes = Seconds / 60 : Seconds = Seconds % 60
Result = AddTimeUnit(Weeks,1)
Result + AddTimeUnit(Days,2) : Result + AddTimeUnit(Hours,3)
Result + AddTimeUnit(Minutes,4) : Result + AddTimeUnit(Seconds,5)
ProcedureReturn Result
EndProcedure
PastDate.l = ParseDate("%dd.%mm.%yyyy", "20.12.2005 12:00")
Debug Date() - PastDate
Debug sTimeDiff(Date() - PastDate)
Delay(2000)
Debug PastDate - Date()
Debug sTimeDiff(PastDate - Date())
Posted: Sun Dec 31, 2006 12:43 am
by Tranquil
@jear:
Your routine gives not the correct results that was requested by vain.
Take a look on the Tips&Tricks section:
http://www.purebasic.fr/english/viewtopic.php?t=25085
Posted: Tue Jan 02, 2007 11:39 am
by Lewis
You can use the following code to compute the day difference.
Code: Select all
Procedure.l Days(Year.l, Month.l, Day.l)
; CONVERT DATE PARTS TO JULIAN DAY (SERIAL) NUMBER:
A.l = (14 - Month.l) / 12
Y.l = Year.l + 4800 - A.l
M.l = Month.l + (12 * A.l) - 3
D.l = Day.l + Int((153 * M.l + 2) / 5) + (365 * Y.l) + Int(Y.l / 4)
ProcedureReturn = D.l - Int(Y.l / 100) + Int(Y.l / 400) - 32045
EndProcedure
Debug days(2004,3,1) - days(2004,2,28) ; 2004 was a leap year
Debug days(2001,1,1) - days(2000,1,1) ; 2000 was a leap year
Debug days(1901,1,1) - days(1900,1,1) ; 1900 was not a leap year
Debug days(2000,1,1) - days(1900,1,1) ; 24 leap years between centennials
Debug days(2100,1,1) - days(2000,1,1) ; ... unless least centennial is divisible by 400
Debug days(1908,7,19) - days(756,3,29)
The Debug Output window displays:
- 2
366
365
36524
36525
420871
Are the results correct? You can bet your bottom dollar on it!
Now all that remains is for you to do the time (clock) computation (and, if necessary, subtract a day from the day difference computation).
You might also find (the last part of) this thread interesting:
As a sidenote, you might be wondering why I choose to use Int() in the Days() function. Well, it's because it's easier for me to write those to ensure that I get integer arithmetic than to constantly try to figure out whether PureBasic will automatically apply integer arithmetic to the computation. Not a big deal, I know, but one needs to be constantly on one's toes to avoid inadvertent use of the float library. I asked for it before (early 2006, I believe) and I noticed that others have recently requested the same in the Wishlist sub-forum: PLEASE, PLEASE, PLEASE give us an integer division operator (eg Div).
Posted: Tue Jan 02, 2007 2:53 pm
by dell_jockey
Lewis wrote: PLEASE, PLEASE, PLEASE give us an integer division operator (eg Div).
Have you considered using the mod-operator (%) to create a DIV ?
Posted: Tue Jan 02, 2007 3:04 pm
by gnozal
I used this one in an old project :
Code: Select all
Procedure.l Julian(year.l, month.l, day.l)
Protected Days.l, yearsBC.l, yearsAD.l
If month < 3
month = month + 12
year = year - 1
EndIf
yearsBC = 4714 - 1
yearsAD = year - 1
Days = Int((yearsBC + yearsAD) * 365.25)
Days = Days - (year / 100)
Days = Days + (year / 400)
Days = Days + Int(30.6 * (month - 1) + 0.2)
ProcedureReturn Days + day
EndProcedure
It seems to pass the Lewis test !
2
366
365
36524
36525
420871
Posted: Tue Jan 02, 2007 5:45 pm
by Lewis
dell_jockey wrote:Lewis wrote: PLEASE, PLEASE, PLEASE give us an integer division operator (eg Div).
Have you considered using the mod-operator (%) to create a DIV ?
I'm sure you're just dying to enlighten me, so go ahead!

Posted: Tue Jan 02, 2007 8:51 pm
by PB
>> Have you considered using the mod-operator (%) to create a DIV ?
>
> I'm sure you're just dying to enlighten me, so go ahead!
http://www.purebasic.com/documentation/ ... ables.html
Posted: Tue Jan 02, 2007 11:00 pm
by Lewis
What nonsense is this? Why on earth would you think that directing me to the modulo entry in the PureBasic Reference Manual would make me any the wiser?
