Hi
When I started using livecode the first thing I noticed was the lack of date functions I was used to in Foxpro - Yes I can write them using judicious use of date convert etc but I like my simple Foxpro calls. So the first library I wrote was date routines I had been using for the best part of 25 years.
With the seconds/zones/GMT problem I decided that I needed a reliable way to do the dates between dates routine. So I wrote a julian day number calculation base on a wikipedia article
Code: Select all
-- Julian Day Number -- As Per http://fox.wikis.com/wc.dll?Wiki~JulianDates
-- Agrees with Wikipedia January 1, 2000, was 2,451,545.
function JDN pDate
local lnD, lnM, lnYr, lnJulianDate
set itemdelimiter to "/"
put item 1 of pDate into lnD
put item 2 of pDate into lnM
put item 3 of pDate into lnYr
put 367 * lnYr - TRUNC(7 * (lnYr + TRUNC ((lnM + 9) / 12)) / 4) into lnJulianDate
put lnJulianDate - TRUNC(3 * (TRUNC((lnYr + (lnM - 9) / 7) / 100) + 1) / 4) into lnJulianDate
put lnJulianDate + TRUNC(275 * lnM / 9) + lnD + 1721029 into lnJulianDate
Return lnJulianDate
end JDN
With that out of the way the days between function became trivial
Code: Select all
-- Function : DayBetween()
-- Remarks : If the second date is blank it will use the current systemdate
-- : Assumes caller knows which is before or after
-- Params : {Date} pDate1, {Date} pDate2
-- Returns : {Integer} Absolute number of days (with decimals) between the two dates
Function DaysBetween pDate1, Pdate2
local lnD1, lnD2, lnDays
set the usesystemdate to true
if pDate2 is empty then
put the system date into pDate2
end if
put JDN(pDate1) into lnD1
put JDN(pDate2) into lnD2
put ABS(lnD1 - lnD2) into lnDays
return lnDays
end DaysBetween
Some of the other routines are trivial but very useful nonetheless if you have been using them for over 25 years
Code: Select all
-- Function : GODAYS()
-- Remarks : The date passed in as a parameter plus or minus the days specified.
-- param : {Date} pDate - Date we are adding or subtracting to/from
-- param : {Integer} pDays - Number of days to add/substract to pDate
-- Returns : {Date} pdDate - Date pDays forward or back
function GODAYS pDate, pDays
set useSystemDate to true
convert pDate to dateitems
add pDays to item 3 of pDate
convert pDate to system date -- NOt strictly needed but ....
return pDate
end GODAYS
Another one used in an employee database
Code: Select all
-- Function : Age()
-- Remarks : Pass in a Date of Birth to Find age in years months and Days
-- : Uses Julian Number
-- Params : {Date} pDate1, {Date} pDate2
-- Returns : {Integer} Absolute number of days (with decimals) between the two dates
Function Age pDOB, pUpto
local lnD1, lnD2, lnYears, lnMonths, ldToday, lnDays, lcAge
set itemdelimiter to "/"
put the short system date into ldToday
-- Allow age calcuklation upto any date - even future
if pUpto is not empty then
put pUpto into ldToday
end if
-- Get the Julian date with base January 1st 4713 BC
put JDN(ldToday) into lnD1
put JDN(pDOB) into lnD2
put TRUNC((lnD1 - lnD2) / 365.25) into lnYears
put TRUNC((((lnD1 - lnD2) / 365.25) - lnYears) * 12) into lnMonths
put TRUNC( ( ((((lnD1 - lnD2) / 365.25) - lnYears) * 12) - lnMonths) * 30.42) into lnDays -- My addition which makes it as close as dammit for the days
-- Send back 3 ITEMS
put lnYears & "," & lnMonths & "," & lnDays into lcAge
return lcAge
end Age
GOMONTH() is a stock Foxpro function but GODAYS() was needed because in foxpro we can just add numbers to a date variable and it returns a day variable
-- All my routines are UK date specific -
"We don't need no steenkin timezones!"
Code: Select all
-- Function : GOMONTH()
-- Remarks : The date passed in as a parameter plus or minus
-- : the months specified. To go forward a year pass 12 back a year -12
-- param : {Date} pDate - Base Date to add or substract the months to
-- param : {integer} pnMonths - Number of months to add/substract to pDate
-- Returns : {date} pDate - Date nMonths forward or -nMonths back
function GOMONTH pDate, pMonths
-- We are passing in a string in BRITISH (UK) format not ENGISH (AMERICAN)
-- So we tell the system that (assuming the users date is in DD/MM/YYY format
-- This property is local and only lasts for the current handler
set useSystemDate to true
convert pDate to dateitems
add pMonths to item 2 of pDate
convert pDate to system date
return pDate
end GOMONTH
-- Function : GODAYS()
-- Remarks : The date passed in as a parameter plus or minus the days specified.
-- param : {Date} pDate - Date we are adding or subtracting to/from
-- param : {Integer} pDays - Number of days to add/substract to pDate
-- Returns : {Date} pdDate - Date pDays forward or back
function GODAYS pDate, pDays
set useSystemDate to true
convert pDate to dateitems
add pDays to item 3 of pDate
convert pDate to system date -- Not strictly needed but ....
return pDate
end GODAYS
I'm sure we can make these smaller faster more beautiful - but they were written while i was learning and they work for me -
"If it ain't broke , don't fix it"
Regards Lagi