HP Forums

Full Version: Number of Days After January 1
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Introduction

The program DATENO calculates the number of days from January 1. The program prompts whether we are working in a leap year or not.

With D = Day and M = Month, the days between January 1 and any other date within the calendar year is:

If M = 1 and M = 2 Then
DATE# = int(30.6 * M + 368.8) + D - 400

Otherwise,
DATE# = int(30.6 * M + 1.6) +D - 35 (non-leap year)
DATE# = int(30.6 * M + 1.6) + D - 34 (leap year)

HP 41C/DM 41L Program: DATENO

(^T: beginning of an alpha string)

Code:
01 LBL^T DATENO
02 ^T MONTH
03 PROMPT
04 STO 01
05 ^T DAY?
06 PROMPT
07 STO 02
08 ^T LEAP? N=0,L=1
09 PROMPT
10 STO 03
11 RCL 01
12 3
13 X<=Y?
14 GTO 00
15 30.6
16 RCL 01
17 *
18 368.8
19 +
20 INT
21 RCL 02
22 +
23 400
24 -
25 GTO 01
26 LBL 00
27 RCL 01
28 30.6
29 *
30 1.6
31 +
32 INT
33 RCL 02
34 + 
35 35
36 - 
37 RCL 03
38 + 
39 LBL 01
40 STO 04
41 END

Examples

Days between January 1 and February 16 (M = 2, D = 16): 46

Days between January 1 and October 1 (M = 10, D = 1):
(Non-leap year): 273
(Leap year): 274

Link to blog post: https://edspi31415.blogspot.com/2019/03/...-days.html
(03-11-2019 02:25 AM)Eddie W. Shore Wrote: [ -> ]The program DATENO calculates the number of days from January 1.

Maybe you should add 1 to the result to get the more common "day of year", i.e. 1 January = day 1 and 31 December = day 365.

(03-11-2019 02:25 AM)Eddie W. Shore Wrote: [ -> ]If M = 1 and M = 2 Then
DATE# = int(30.6 * M + 368.8) + D - 400

What about 31*M + D -32 ?-)

Anyway, here is my attempt at a day-of-year program. I have derived the formulas myself, so beware. ;-) Please try it and report any errors you find.

Code:
01 LBL "DOY"
02 4
03 MOD
04 X≠0?
05 SIGN
06 CHS
07 STO T
08 RDN
09 30,6
10 *
11 31,3
12 -
13 50
14 X>Y?
15 GTO 01
16 RDN
17 INT
18 +
19 +
20 GTO 02
21 LBL 01
22 RDN
23 1,2
24 +
25 INT
26 +
27 LBL 02
28 END

Usage:
day [ENTER] month [ENTER] year XEQ "DOY"

If you prefer month, day, year instead simply insert an X<>Y command between line 08 and 09.

The program automatically checks for leap years, this works for all dates between 1 January 1901 and 28 February 2100.

Example:
1 [ENTER] 10 [ENTER] 1999 XEQ"DOY" => 274
1 [ENTER] 10 [ENTER] 2000 XEQ"DOY" => 275

Dieter
(03-11-2019 02:25 AM)Eddie W. Shore Wrote: [ -> ]The program DATENO calculates the number of days from January 1.

Somewhat related is the following program from the article Sunrise and Sunset.

Here it is adapted for the HP-42S:
Code:
00 { 30-Byte Prgm }
01 IP
02 12
03 LASTX
04 FP
05 100
06 ×
07 3
08 -
09 X<0?
10 +
11 30.6
12 ×
13 0.5
14 +
15 IP
16 R↑
17 +
18 END

Examples:

1.03 R/S
1

28.02 R/S
365

29.02 R/S
366


This avoids having to deal with leap years.

Cheers
Thomas
(03-11-2019 02:25 AM)Eddie W. Shore Wrote: [ -> ]If M = 1 and M = 2 Then
DATE# = int(30.6 * M + 368.8) + D - 400

Otherwise,
DATE# = int(30.6 * M + 1.6) +D - 35 (non-leap year)
DATE# = int(30.6 * M + 1.6) + D - 34 (leap year)

Eddie, you can simplify these formulas significantly.
Since D and 400 are positive integers...

int(30.6 * M + 368.8) + D - 400
= int(30.6 * M + 368.8 + D - 400)
= int(30.6 * M + D - 31.2)

Or here (D=1 or 2) simply

= int(30.6 * M + D - 31)

The two other formulas can be simplified the same way.
Or they can be derived from the Jan/Feb formula.

With L=0 (common year) or 1 (leap year):

days = 30.6 * M + D - 31
if M >= 3 then days = days - 2.3 + L
return int(days)

Note: according to your formulas the final 2.3 would be 2.4, but subtracting only 2.3 leaves a fractional part between 0.1 and 0.9 so that roundoff problems are avoided (e.g. in non-decimal environments) that may lead to cases like int(242.9999999....) for 1 September.

Here is a version of your HP-41C program that implements this idea.

Code:
01 LBL "DAYD"
02 "MONTH↑DAY ?"
03 PROMPT
04 RCL Y
05 30.6
06 *
07 +
08 31
09 -
10 X<>Y
11 3
12 X>y?
13 GTO 01
14 2.3
15 ST- T
16 R↑
17 "LEAP YR 0/1?"
18 PROMPT
19 +
20 STO Z
21 LBL 01
22 RCL Z
23 INT
24 END

XEQ "DAYD"
MONTH↑DAY ?
10 [ENTER] 1 [R/S]
LEAP YR 0/1?
0 [R/S]

=> 273


Note that the program only prompts for a leap year input if this is required, i.e. for months between March and December.

Dieter
Reference URL's