[Coco] Julian Date

Wayne Campbell asa.rand at gmail.com
Tue May 23 19:22:54 EDT 2017


I had to enter the code in manually as I do not have a constant internet
connection on my laptops. My VCC is currently on my old notebook. I made
sure I typed it in correctly (I did have one typo when I first loaded the
source into Basic09). It ran, but the numbers didn't look right. That's
when I went through the procedure thoroughly. I added many comments. I am
posting that version of your procedure here in this message. Please do not
take it that I am criticizing you or your coding. I am merely pointing out
things that I know to be true, or preferred in the case of code syntax in
Basic09. I have written the replacement procedure, but have not yet tested
it. When I have, and know that it works correctly, I will post it in this
thread. Perhaps tomorrow, but I can't promise anything.

To gain more understanding of Basic09 and its internal code structure,
check out this cocopedia wiki page:

The Structure of I-Code
http://www.cocopedia.com/wiki/index.php/The_Structure_of_I-Code

Wayne

PROCEDURE JD
PARAM TD:STRING[15] \ (* Pass todays date *)

(* Besides the problems explained below, this procedure produces extremely
flawed results. When I
(* entered the date 05/22/2017, the result was 6351 days elapsed since
1-1-1900. The actual number
(* of days is 42,875. When I entered the date 01/15/2000 the result was 15
days elapsed, when the
(* actual number of days is 36,538. This is partly due to the problems
described below, but is also
(* due to the fact that only the last two digits of the year are being
dealt with instead of the
(* whole 4-digit year.

(* The following statement is wrong. If you don't specify a data type, the
default for a non-STRING
(* variable is a REAL. For STRING variables (defined by using the $ at the
end of the variable name)
(* if no type is specified, the default is STRING[32]. Because of this,
your 3 Integers are in
(* reality 3 REALs. DIM x is the same as defining x by use in the code say,
x=1, with no DIM statement.
(* For STRINGS, DIM my$ is the same as defining my$ by use, say my$="word",
which is a STRING[32].
(* DIM mm,dd,yy:INTEGER is the correct syntax.
DIM mm,dd,yy \ (* Integer *)

(* There should be consistency in variable naming. If you are going to use
the $ on string names, you
(* should use it either on all string variables, or only on string
variables defined by use. day is a
(* vector array that contains 7 32-character strings (STRING and STRING[32]
are the same). The longest
(* word in the array is Wednesday, which contains 9 characters. You would
save 171 bytes of memory by
(* making it STRING[9]. By your usage of Leapyear, it could be DIM'd a
BOOLEAN or a BYTE. In the former
(* case, you would be able to use the IF Leapyear THEN syntax and it would
be legal, and you could have
(* a second variable DIM'd as a BYTE, say Leapday, to contain the 0 or 1
values. In the latter case,
(* because it only contains the values 0 or 1 it can be a byte and save 1
byte of memory. ST1 only
(* contains 25 characters where it is assigned a value, so you could save
35 bytes by changing the 60
(* to 25. DT$ is 5 bytes longer than TD, but it never contains anything
other than the contents of TD.
(* The size should be the same as TD.
DIM day(7):STRING
DIM JDate:REAL
DIM Leapyear:INTEGER
DIM ST1:STRING[60]
DIM DT$:STRING[20]

(* The day names are in the wrong order. Sunday is the first day, not
Monday. This caused your output
(* to be one day off.
day(1)="Monday"
day(2)="Tuesday"
day(3)="Wednesday"
day(4)="Thursday"
day(5)="Friday"
day(6)="Saturday"
day(7)="Sunday"

(* The following statement is fine, but there is a faster way. Use PUT:

(* PUT #1, 12

(* or

(* DIM cls:BYTE
(* cls:=12
(* PUT #1, cls

(* In the first example, 12 is an INTEGER (2 bytes), in the second example,
cls is a BYTE (1 byte).
PRINT CHR$(12)

(* All three of the following variables are being defined by use (no DIM
statement). daynumber is a
(* REAL and is only used to contain INTEGER values of 1 through 7. This
could be DIM'd as a BYTE
(* variable, and it would make the procedure run faster. cont$ is a 32
character string that only
(* contains one character, Y or N. It could be DIM'd as a STRING[1], or
better yet, since its
(* function serves a yes/no purpose, could be DIM'd as a BOOLEAN (without
the $) and contain the
(* values TRUE or FALSE. tdate$ is a 32 character string that only contains
24 characters later in
(* the procedure. It could be DIM'd as a STRING[24] and save 8 bytes of
memory.
tdate$=" / / "
cont$="Y"
daynumber=0

DT$ = TD

(* This entire loop construct does nothing. It is a waste of cpu cycles and
isn't necessary to the
(* function of the procedure.
WHILE cont$="Y" DO
(* What I say below concerning ST1 applies to all 4 of the following
assignments. They should occur
(* before the loop, not in it. The same data is being assigned repeatedly,
and wastes cpu cycles.
dt$ = TD
mm=VAL(MID$(DT$,1,2))
dd=VAL(MID$(DT$,4,2))
yy=VAL(MID$(DT$,9,2))
(* You assign the ST1 variable here, but then you never use it. The string
in the MID$ function of the
(* statement following it should use the ST1 variable instead of
duplicating the value. Also, you are
(* causing the assignment to happen with each iteration of the loop. The
assignment should occur before
(* the loop begins. The way you have it here adds unnecessary cpu cycles to
the program and slows it
(* down.
ST1="0312931303130313130313031"
(* This test will always fail. The month value will never be outside the
range of 1 to 12, and the day
(* value will never be outside the range of 1 to max days in given month.
IF mm<1 OR mm>12 AND dd<0 OR
dd>VAL(MID$("0312931303130313130313031",mm*2,2)) THEN
cont$="Y"
ELSE
(* This test will only be true if the month is February, it's not a leap
year and the day value is
(* greater than 28. As this condition cannot be true, the test will always
fail. The end result is that
(* the loop goes through 1 iteration and then exits.
IF mm=2 AND MOD(yy,4)<>0 AND dd>28 THEN
cont$="Y"
ELSE
cont$="N"
ENDIF
ENDIF
ENDWHILE

(* Set the leap year flag *)
(* The problem with this was stated in the thread. Leap year is divisible
by 4 and not divisible by 100,
(* or is divisible by 400. (MOD(yy,4)=0 AND MOD(yy,100)>0) OR MOD(yy,400)=0
REM IF MOD(yy,4)=0 AND mm>2 THEN
IF MOD(yy,4) = 0 THEN
Leapyear=1
ELSE
Leapyear=0
ENDIF

(* Use of INT() here is only necessary because mm, dd and yy are REAL, not
INTEGER.
mm=INT(mm-1)
tdate$="000303060811131619212426"
(* This calculation will never be accurate because you are only dealing
with the last two digits of the
(* year number. The year values being dealt with are 00 through 99. In
order to be accurate, you need
(* to use the whole year number and calculate from 1900, not 00.
JDate=INT((yy-1)/4+mm*28+VAL(MID$(tdate$,mm*2+1,2))+yy*365+dd+Leapyear)
daynumber=MOD(JDate,7)
PRINT JDate
REM PRINT "Today is "; day(daynumber); " "; DATE$
PRINT "There have been "; JDate; " days since 1-1-1900"
REM IF Leapyear THEN
IF Leapyear=1 THEN
PRINT "It is a leap year"
ELSE
PRINT "It is not a leap year"
ENDIF

END


On Sat, May 20, 2017 at 7:37 PM, Wayne Campbell <asa.rand at gmail.com> wrote:

> I don't write C code. It will be Basic09, as that is my preferred language
> on the CoCo.
>
> I will simply make the code better by using a couple of Boolean variables
> and I may do some variable renaming since B09 allows for 29-character
> variable names.
>
>
> On May 20, 2017 7:00 PM, "phillip taylor" <ptaylor2446 at gmail.com> wrote:
>
>> Thanks but If your going to convert the code to C not many users will
>> be able to understand how it works. It was intended to be used with
>> Os9Budget and runs as a procedure file so it can be called by the
>> other procedure files in Os9Budget.
>>
>> On 5/20/17, Gene Heskett <gheskett at shentel.net> wrote:
>> > On Saturday 20 May 2017 17:42:03 Wayne Campbell wrote:
>> >
>> >> I read your code. Not bad, but could be better. I will revamp it and
>> >> post my alteration.
>> >>
>> >> On May 20, 2017 11:57 AM, "phillip taylor" <ptaylor2446 at gmail.com>
>> > wrote:
>> >> > I hope that you all enjoy the julian date that I posted here.
>> >> >
>> >> > --
>> >> > Coco mailing list
>> >> > Coco at maltedmedia.com
>> >> > https://pairlist5.pair.net/mailman/listinfo/coco
>> >
>> > This code is incomplete, and will be wrong once every 400 years.
>> > The code in the original K&R C book shows how it should be done.
>> >
>> > Basically if the year is divisible by 4 its a leap year UNLESS the date
>> > is divisible by 400 without a remainder, then it is not a leap year.
>> > 2000 was not a leap year. 2400 will not be a leap year.  The C manual
>> > uses the mod(year,4) or mod(year,400) to determine this IIRC.
>> >
>> > Cheers, Gene Heskett
>> > --
>> > "There are four boxes to be used in defense of liberty:
>> >  soap, ballot, jury, and ammo. Please use in that order."
>> > -Ed Howdershelt (Author)
>> > Genes Web page <http://geneslinuxbox.net:6309/gene>
>> >
>> > --
>> > Coco mailing list
>> > Coco at maltedmedia.com
>> > https://pairlist5.pair.net/mailman/listinfo/coco
>> >
>>
>> --
>> Coco mailing list
>> Coco at maltedmedia.com
>> https://pairlist5.pair.net/mailman/listinfo/coco
>>
>


More information about the Coco mailing list