
'Working with dates and days of the week

' I cannot take any credit for this - other greater people than me have worked it out
' just thought i'd put it together - it may help you at some time.

' Sub JulToDate by WayneA - thanks Wanye
' Sub Julian - not known but again thanks.
' Sub getday by Johnny - thanks Johnny
' Bill-Bo also has a 'DayOfweek' alternative which is just as good.

' Thanks all.


' So to begin:

' You cannot simply add 1 to a date, it does not work!
' If you add 1 to 31st August you would get 32nd of August which does not exist

' This is how you can manipulate dates:

' 1. You need to convert any date to a Julian number. (see internet for Julian explanation)
' 2. Once the date is converted, you can add / subtract as you would with a normal integer.
' 3. now you have added something to the initial date - convert it back to a date.

' 4. Any date can be calculated to find what day of week it is.

' So, we will ask for a date - convert it to a number 'JN' - Julian
' get the day of the week

' then:

' add 1 to the number 'JN'
' convert 'JN' back to a date 
' get the new day of the week.


DEF go$:string 
DEF dj$,mj$,yj$,dayin$,monthin$,yearin$:string 
DEF jn:int 
DEF dayin,monthin,yearin:int 

DEF Day,Month,Year,Days,DaysNY,Week,WeekNY,Weekday,WeekdayNY:INT
DEF DayNames[7]:STRING
'Initialize the 7 weekday names
DayNames = "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"


OPENCONSOLE
LABEL topofprogram

'get initial date e.g. 12.08.2013
PRINT
PRINT " Please enter a day (2 digits) a month (2 digits) and a year (4 digits)"
PRINT
INPUT " Day please   - ",dayin
INPUT " Month please - ",monthin
INPUT " Year please  - ",yearin

'Add any leading zeros for display purposes only (not needed for manipulating dates)
dayin$   = Using("0##",dayin)
monthin$ = Using("0##",monthin)
yearin$  = Using("0##",yearin)

'Convert the date entered to a julian number - note format - year / month / day
JN = julian(yearin,monthin,dayin)

'Find out the day of the week it is 
'To do this we have to get the start of the year values first
DaysNY = GetDay(1,1,yearin)
WeekdayNY = DaysNY % 7
WeekNY = (WeekdayNY < 4)
IF WeekNY = 0 THEN WeekNY = 52 + (INT(GetDay(1,1,yearin - 1) % 7) < 4)

'Send the values of the day/month/year you entered to the sub routine - note format day/month/year
Days = GetDay(dayin,monthin,yearin) 


Weekday = Days % 7
Week = INT(Days / 7) - INT(DaysNY / 7)
IF WeekdayNY < 4 THEN Week = Week + 1
IF Week = 0 THEN Week = WeekNY

'wkday$ = the actual day of week
wkday$ = DayNames[Days % 7] 

'Print the date you entered - the day of week it is - and the Julian number of the date.

PRINT "----------------------------------------------------------------------"
PRINT
PRINT " The date you entered is ", dayin$, ".",monthin$,".",yearin$
PRINT
PRINT " and that makes it a " ,wkday$
PRINT
PRINT " The Julian number for ",dayin$, ".",monthin$,".",yearin$, " is ", JN
PRINT
PRINT "----------------------------------------------------------------------"

'Now change the date to the next day by adding 1 to the number JN
JN = JN + 1  

'Convert the number JN back to a date
GOSUB JulToDate(jn)
'JulToDate - returns the values dj$(day date), mj$(month date), yj$(year date)


'Print the next day date.
PRINT
PRINT " The next day is ", dj$, ".",mj$,".",yj$
PRINT

'Send the values of the next day/month/year to the sub routine - note format day/month/year
Days = GetDay(VAL(dj$),VAL(mj$),VAL(yj$)) 

Weekday = Days % 7
Week = INT(Days / 7) - INT(DaysNY / 7)
IF WeekdayNY < 4 THEN Week = Week + 1
IF Week = 0 THEN Week = WeekNY

'wkday$ = the actual day of week
wkday$ = DayNames[Days % 7] 

'Convert to a julian number - note format - year / month / day
JN = julian(VAL(yj$),VAL(mj$),VAL(dj$))


'Finally, print the new week day and it's corresponding Julian number
PRINT " and that will make it a " ,wkday$
PRINT
PRINT " The Julian number for ",dj$, ".",mj$,".",yj$, " is ", JN
PRINT
PRINT "----------------------------------------------------------------------"
PRINT

'Try again or exit.
INPUT " Would you like to enter another date Y/N ? ",go$
PRINT 

go$ = LCASE$(go$)

IF go$ = "y" 

CLS
dayin = 0
monthin = 0
yearin = 0
JN = 0
GOTO topofprogram

ENDIF

'End program
END

'Sub routines needed

Sub Julian(year :int, month :int, day : int),int
def a, jd, m, y : int
a = (14 - month)/12
y = year + 4800 - a
m = month + 12 * a - 3
jd = day + (153 * m + 2)/5 + y * 365 + y/4 - y/100 + y/400 - 32045
RETURN jd
endsub 

SUB GetDay(dsearch as INT,msearch as INT,ysearch as INT), INT
	DEF N,Y2:INT

	c = INT(.4 * msearch + 2.3)
	c$ = STR$(c)
	p = VAL(c$)

	Y2 = ysearch - (msearch < 3)
	N = 365 * ysearch + dsearch + 31 * msearch + 2 - (msearch >= 3) * p + INT(Y2 / 4) - INT(.75 + INT(Y2 / 100) * .75)
	RETURN N
ENDSUB


Sub JulToDate(JN As Int),String

	JulNumber = JN + 68569
	calc = 4 * JulNumber / 146097
	JulNumber = JulNumber - (146097 * calc + 3) / 4
	Tempyj = 4000 * (JulNumber + 1) / 1461001
	JulNumber = JulNumber - (1461 * Tempyj / 4) + 31
	Tempmj = 80 * JulNumber / 2447
	dj = (JulNumber - (2447 * Tempmj / 80))
	mj = (Tempmj + 2 - (12 * (Tempmj / 11)))
	yj = (100 * (calc - 49) + Tempyj + (Tempmj / 11))
	mj$ = Using("0##",mj) 
	dj$ = Using("0##",dj)
	yj$ = Using("0####",Int(Abs(yj)))
	If yj < 0 Then yj$ = "-" + yj$
	Return dj$+mj$+yj$
EndSub