Page 1 of 1

Date Functions

Posted: Wed Jul 23, 2014 5:23 pm
by doogle
This is my first attempt to code in Smart Basic.

Coming from VB6 I found I had a need for Date Functions such as DateAdd (add a number of Days to a Date), DateDiff (calculate the number of Days between 2 Dates) and DayOfWeek for a given Date; so I had a go. Code is below. Any / all constructive criticisms appreciated.

Code: Select all

'
' doogle 23/07/2014
'
dim daystomonth(13,2)
data 0,0,31,31,59,60,90,91,120,121,151,152,181,182,212,213,243,244
data 273,274,304,305,334,335,365,366
for i = 0 to 12
	for j = 0 to 1
		read daystomonth(i,j)
	next j
next i

def datetosecs(d,m,y)
'
' Create a 'Timestamp' representing seconds from 1/1/1900
' ignore leap seconds
' But check the year for leap year so
' February gets dealt with properly
'
if y % 4 = 0 then
	thisleap = 1
else
	thisleap = 0
end if
if y >= 400 and y % 400 = 0 then
		thisleap = 0
end if
days = ((y - 1970) * 365)
mdays = .daystomonth(m-1,thisleap)
ddays = d - 1 
totaldays = days + mdays + ddays
totalsecs = totaldays * (24 * 60 * 60)
return totalsecs
end def

def secondstodate$(secs)
'
' Convert 'Timestamp' back to a Date
' Again ignore leap seconds but check the 
' resulting year so February is processed properly
'
totaldays = secs / (24 * 60 * 60)
years = floor(totaldays / 365)
daysrem = totaldays - (years * 365) 
year = 1970 + years
if year % 4 = 0 then
	leap = 1
else 
	leap = 0
end if
if year >= 400 and year % 400 = 0 then
		leap = 0
end if
mfound = -1
if daysrem <> 0 then
	do 
		if daysrem < .daystomonth(i,leap) then
			mfound = i
		else
			i = i + 1
		end if
	until mfound <> -1
	m = mfound
	d =  daysrem - .daystomonth(m-1, leap) + 1
else
	m = 12
	d = 31
	year = year - 1
end if   
d$ = left$("00", 2-len(str$(d))) & str$(d)
m$ = left$("00", 2-len(str$(m))) & str$(m)
y$ = str$(year)
return d$ & "/" & m$ & "/" & y$
end def

def dateadd$(date$,days)
daysecs = days * 24 * 60 * 60
d = val(mid$(date$,0,2))
m = val(mid$(date$,3,2))
y = val(mid$(date$,6,4))
da = datetosecs(d,m,y)
daysecs = da + daysecs
return secondstodate$(daysecs)
end def

def datediff(date1$, date2$)
d = val(mid$(date1$,0,2))
m = val(mid$(date1$,3,2))
y = val(mid$(date1$,6,4))
da1 = datetosecs(d,m,y)
d = val(mid$(date2$,0,2))
m = val(mid$(date2$,3,2))
y = val(mid$(date2$,6,4))
da2 = datetosecs(d,m,y)
dadiff = da1 - da2
return dadiff /(24*60*60)
end def

def dayofweek$(date$)
'
' Uses Zeller's Congruence
'	0 = Saturday,7 = Friday
'
dim days$(7)
for i = 0 to 6
	read days$(i)
next i
'
' Expect Date in dd[sep]mm[sep]yyyy format
' where [sep] can be any single character
'
d = val(mid$(date$,0,2))
m = val(mid$(date$,3,2))
y = val(mid$(date$,6,4))
'
'Algorithm requires Jan = month 13 Feb = month 14
'
if m = 1 then m =13
if m = 2 then m = 14
t1 = floor((13*(m+1))/5)
k = y % 100
j = floor(y / 100)
h = (d + t1 + k + floor(k/4) + 5 + (5*j)) % 7
return days$(h)
data "Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"
end def
'
' Test Data
'
print "25/07/2014 is a ";dayofweek$("25/07/2014")
print "12/02/2003 + 20 Days is: "; dateadd$("12/02/2003",20)
print "Days difference between 01/03/2004 and 28/02/2004 is "; datediff("01/03/2004","28/02/2004")
print "Days difference between 01/03/2014 and 28/02/2014 is "; datediff("01/03/2014","28/02/2014")
print "20/07/2014 less 10 days is "; dateadd$("20/07/2014",-10)

Re: Date Functions

Posted: Thu Jul 24, 2014 5:55 am
by Mr. Kibernetik
Very interesting.
I will treat this post as a request for dates functions.

Comment about code. This part:

Code: Select all

for i = 0 to 12
   for j = 0 to 1
      read daystomonth(i,j)
   next j
next i
will be shorter and faster as:

Code: Select all

for i = 0 to 12
   read daystomonth(i,0)
   read daystomonth(i,1)
next i

Re: Date Functions

Posted: Thu Jul 24, 2014 8:29 am
by doogle
Thanks for the comments. It was an interesting task and could do with tidying up. If you could add the functionality into the core poduct that would be great.

Re: Date Functions

Posted: Thu Jul 24, 2014 2:43 pm
by Dutchman
I made a lib with date functions.
See viewtopic.php?f=20&t=556