Date Functions

Blitz3D Forums/Blitz3D Beginners Area/Date Functions

Farflame(Posted 2007) [#1]
I need an accurate set of date functions, such as calculating how many days/months/years have passed between two dates and calculating which day of the week a certain date will be. There's a Blitzmax version in their forums but I don't know how to convert Blitzmax code to Blitz3D.

Does anyone know if there are any B3D functions to do this?


Buggy(Posted 2007) [#2]
It shouldn't be too hard to come up with some, even for a beginner programmer. However, it does depend on how you store your dates.

It may be this:
date$ = "09 February 2007"

Or this:
day = 9
month = 2
year = 2007


Or something completely different. I suggest doing it yourself.


Farflame(Posted 2007) [#3]
Hmm, I don't think you read my post :)

I want to find out the number of days, months or years between two dates. For example, if I pass the dates "19 Jun 1970" and "09 Feb 2007" to a function, I want it to be able to return the number of days, months and years between those two dates.

Also, I need to be able to pass a date to a function, and have it return the day (Monday, Tuesday, Wednesday) etc of that date.


Farflame(Posted 2007) [#4]
Well I'm pleased to say I found some code for the weekday function at least. Now all I need is a 'datediff' and a 'dateadd' function.

Here's the code for the weekday btw... from the code archives.

Function GetDayOfTheWeek$(day,month,year)
 ; Returns the day of the week.
 ; day, month & year are integers i.e. 15 04 2004
  a=(14-month)/12
  y=year-a
  m=month+(12*a)-2
  d=(day+y+(y/4)-(y/100)+(y/400)+((31*m)/12))Mod 7  ;Ooouch!
  Select d
    Case 0:Weekday$="Sunday - bonny and blithe, and good and gay"
    Case 1:Weekday$="Monday - Fair of face"
    Case 2:Weekday$="Tuesday - Full of grace"
    Case 3:Weekday$="Wednesday - Full of woe"
    Case 4:Weekday$="Thursday - Far to go"
    Case 5:Weekday$="Friday - Loving and giving"
    Case 6:Weekday$="Saturday - Work for a living"
    Default:Weekday=""
  End Select
  Return Weekday$
End Function



Stevie G(Posted 2007) [#5]
Not sure if it's any use but here's the Julian method of converting a date to integer. Note it's not the same method a Excel's datevalue function.

Function DATEnumber( Day , Month , Year )

	m1 = ( Month - 14 ) / 12
	y1 = Year + 4800
	Return ( 1461 * ( y1 + m1 ) / 4 + 367 * ( Month - 2 - 12 * m1 ) / 12 - ( 3 * ( ( y1 + m1 + 100 ) / 100 ) ) / 4 + Day - 32075 )
	
End Function


Stevie


GfK(Posted 2007) [#6]
I use this:

http://www.blitzbasic.com/codearcs/codearcs.php?code=298


Farflame(Posted 2007) [#7]
Ahhh, almost there then. If that DateNumber function is accurate, which I'm sure it is, then I'm almost there. If I subtract the earlier date from the later date, then I get the number of days which have passed between the two dates. All I need now is to know how to convert that into months and years. Can't quite work out how to do that at the moment because years and months all have different amounts of days in them. I suppose I could just count backwards and check the days in each month and year as I go, but it's not very efficient and I'm sure there's an algorithm to do it. Any ideas?


octothorpe(Posted 2007) [#8]
I think this will do it. I can't think of any test cases where you might need to add more than one month worth of days to the delta date, but it might be worth thinking about further.

Function weirdDateDiff$(d1, m1, y1, d2, m2, y2)
	Local dy = y2 - y1
	Local dm = m2 - m1
	Local dd = d2 - d1
	If dd < 0 Then
		dd = dd + numberOfDaysInMonth(m2, y2)
		dm = dm - 1
	EndIf
	If dm < 0 Then
		dm = dm + 12
		dy = dy - 1
	EndIf
	If dy < 0 Then RuntimeError("date1 > date2")
	Return dy + " years, " + dm + " months, and " + dd + " days"
End Function

Function numberOfDaysInMonth(m, y)
	If m < 1 Or m > 12 Then RuntimeError("invalid month")
	If m = 2 Then
		Local isLeap = ( y Mod 4 = 0 ) And (( y Mod 100 <> 0 ) Or ( y Mod 400 = 0 ))
		If isLeap Then Return 29 Else Return 28
	ElseIf (m < 8 And m Mod 2 = 1) Or (m >=8 And m Mod 2 = 0)
		Return 31
	Else
		Return 30
	EndIf
End Function



Farflame(Posted 2007) [#9]
Thanks, that does the trick. What I need it for at the moment is simply to calculate a person's age given their birthday, so in some cases I'll be adding 50 or 60 years. This does the job perfectly, so thanks alot :)


Buggy(Posted 2007) [#10]
Sorry 'bout that.


Farflame(Posted 2007) [#11]
Hmmm now then, this probably seems dumb after you've given me the above routine, which works perfectly for working out somebody's age in years, but what if I need to work out the distance between two dates in days only? I can't do (Years * 365 + Months * 31 + Days) or anything because of the different numbers in each year or month, so again, the only way I can think about doing it at the moment is by just adding on a day and counting until I reach the target date.

So for example, how would I get 'You've been alive for 13,456 days'.


Farflame(Posted 2007) [#12]
I think the old 'JulianDay' function works for that purpose actually (at http://www.blitzbasic.com/codearcs/codearcs.php?code=298 )

So JulianDay(d2,m2,y2)-JulianDay(d1,m1,y2) gives the answer in days (I hope).