Handling the Date with your Sharp Pocket Computer

Helper functions

One function we might need is the modulo function. This is the rest of
an integer division, e.g. the result of 5 MOD 3 is 2. The
BASIC representation of Y = A MOD B is

10 Y=A-B*INT(A/B)

Storing the Date in BASIC variables

The easiest way to do this is to use three standard variables, like Y
for year, M for month and D for day. The advantages of this
are

Easy to understand

The date may be printed with e.g. 10 PRINT "Date is";D;M;STR$ Y

The disadvantages are

Takes three variables for only one date

It is hard to create a sequence of dates

It is also hard to determine the weekday or the difference of days between two dates

Another way to store the date is to use a single variable and store the date as difference in
days to a fixed date, e.g. to the 15.Oct.1582 (which is the start of the gregorian calendar).
The advantages of this
are

Takes only one variable to represent one date

It is easy to create a sequence of dates

It is also easy to determine the weekday or the difference of days between two dates

The disadvantages are

Hard to understand

Hard to print

Which one would be the best reference date?

A good reference date would be the 15.Oct.1582 (start of the gregorian calendar), the difference is
always positive for all valid gregorian calendar dates then and the values are simpler to
understand then. As you will see, it is easier to calculate with the 1. March 0000 as reference
day. Note that this is only a virtual difference of days, because the gregorian calendar was
not valid this time (and the first year was one, not zero).

Because both representation format have their advantages, it would be nice to convert
them one to another. This leads us directly to the

Conversion Subroutines for Date formats

Converting D,M,Y to a Difference of Days to a fixed Date

The fixed date will be the 1. March 0000 in all further calculations.
First let's convert the month (Jan.- Dec. or 1- 12) as shown in the following table:

Month

converted

Offset in days to 1. March

January (1)

10

306

February (2)

11

337

March (3)

0

0

April (4)

1

31

May (5)

2

61

June (6)

3

92

July (7)

4

122

August (8)

5

153

September (9)

6

184

October (10)

7

214

November (11)

8

245

December (12)

9

275

The calculation to to this is MC = (M + 9) MOD 12.
MC stands for "Month converted" here.

In BASIC this is

10 MC=M+9-12*INT((M+9)/12)

Why? Because we will not have to respect februarys with 29 days. The month offset in
days to the 1. March (you can see it in the third column of the table) is the same
for years with 365 days and years with 366 days.

Now, we're able to calculate the difference in days to the 1. March in a single
year. It is the month offset from the table plus the day part of the date minus one.
How is it possible to represent the month offset table in the sharp? The simplest
approach would be to create an array and fill it with the offset at program start.
This is very memory-consuming, but fortunately I found a function, which is able to
calculate this:

INT(MC*30,6+0,5)

Let's have a look at the year now: If the month is January or February, we have to
reduce the number of years by one year, because these two month belong to the past year
due to the month conversion calculation. In BASIC this would be (YC stands
for "Year corrected")

10 YC=Y:IF M<3 LET YC=YC-1

Without years with 366 days it would be simple: The offset in days would
be diff = YC * 365.

With respecting the years with 366 days it
is diff = INT(YC * 365,25).

But there are some extra rules for years with 366 days:

If the year is (integer-) dividable (without rest) by 100, the year has 365 days, except

if the year is dividable by 400, the year has 366 days.

The function, which respects this, looks like this (in BASIC):

10 DI= INT (YC*365.25)- INT (YC/100)+ INT (YC/400)

Now, let's respect the days: The difference of days to the first day of the month is
simply the number minus one.

Here is a complete subroutine, which calculates the difference in days to
the 1. March 0000:

10 rem CONVERT DATE IN D,M,Y TO NUMBER OF DAYS
20 rem SINCE 1.MARCH 0000; RESULT IS IN A
30 A=Y:if M<3 let A=A-1
40 A=int (A*365.25)-int (A/100)+int (A/400)+D-1
50 A=A+int (.5+30.6*(M+9-12*int ((M+9)/12))):return

Note, that this is very efficient, it is straight forward, there are no loops and
there is no array for determining the number of days for a month.

Converting the Difference of Days (to the 1. March 0000) to Day, Month and Year

First, let's have a look at the year: Calculating the year is rather complicated,
because the INT operation is not reversible. But Y = diff / 365,2425 will
give a value that will match in most cases. If you add two to the difference
(Y = (diff + 2) / 365,2425), the result will

match in most cases

if it doesn't match, the result will be greater than the real year (this is easier to
handle, because you must not respect years with 366 days)

After we've calculated this value, we have to

Calculate the real number of days this number of years causes

Decrease the number of years, if it causes more days than the given value

Note, that we have to add one to the year, if the month is less than 3 (March), but
to do this, we'll first calculate the month. This is most similar to calculating the number
of years. Just calculate a nearby-value, an then correct it. In BASIC this would be