Simpler Datenum
#1
Code: (Select All)
a$ = Date$
month$ = Left$(Date$, 2)
day$ = Mid$(Date$, 4, 2)

Select Case month$
    Case "01": datenum = 0 ' jan 31
    Case "02": datenum = 31 ' feb 29+ F leap years
    Case "03": datenum = 60 ' mar 31+
    Case "04": datenum = 91 ' apr 30+
    Case "05": datenum = 121 ' may 31+
    Case "06": datenum = 152 ' jun 30+
    Case "07": datenum = 182 ' jul 31+
    Case "08": datenum = 213 ' aug 31+
    Case "09": datenum = 244 ' sep 30+
    Case "10": datenum = 274 ' oct 31+
    Case "11": datenum = 305 ' nov 30+
    Case "12": datenum = 335 ' dec 31+
End Select
datenum = datenum + Val(day$)
datenum$ = Right$("00" + _Trim$(Str$(datenum)), 3)

Print a$
Print month$
Print day$
Print datenum$
End

I wanted to simplify the code with a edit.  Messaged up the message big time.  So I deleted and retried.  If you remember my previous post.  You will notice the change after the end select and in each case. This will result in faster and smaller code, with no difference in performance.
Reply
#2
Nice!

This is another reason I love QB64 no-limits memory (system limits). Back in the QJUrassic days, we had to optimize code like crazy to get it work on large apps. For instance, I would have needed to change the way datenum$ is calculated by losing the SELECT CASE and doing something very obfuscated, like this....

datenum$ = _TRIM$(STR$(VAL(MID$("000031060091121152182213244274305335", VAL(month$) * 3 - 2, 3)) + VAL(day$)))
datenum$ = MID$("00", LEN(datenum$)) + datenum$ ' Three digit formatting.

Pete
Reply
#3
Actually, I'm going to post this demo to demonstrate how to calculate the day (1-366) in leap year and non-leap year calendar periods. I believe your deo only provides the accumulative days in a leap year event, but correct me if I'm wrong.



Code: (Select All)
INPUT "month-day-year as 'xx-xx-xxxx': ", a$
month$ = LEFT$(a$, 2)
day$ = MID$(a$, 4, 2)

a1 = VAL(MID$(a$, 7, 4)): ly = 0
IF a1 MOD 4 = 0 AND VAL(month$) > 2 THEN ' Check to add a day if leap year.
    IF a1 MOD 100 = 0 THEN
        IF a1 MOD 400 = 0 THEN ly = 1
    ELSE
        ly = 1
    END IF
END IF

datenum$ = _TRIM$(STR$(VAL(MID$("000031059090120151181212243273304334", VAL(month$) * 3 - 2, 3)) + VAL(day$) + ly))
datenum$ = MID$("00", LEN(datenum$)) + datenum$

PRINT a$
PRINT month$
PRINT day$
PRINT datenum$;: IF ly THEN PRINT " Leap year day included."
SLEEP
CLS
RUN


Note that 1700, 1800 and 1900 were not a leap year, but 2000 was.

I think Steve even has a one-liner for leap year calculation.

Anyway, feel free to add any of this info / code to your routine if you like, update /edit your code, etc. I don't get bent because my post no longer represents changes another poster makes, unless of course they are doing it to make me look stupid. My wife takes offense at that.... because it's her job.

Pete
Reply
#4
It seems like it was just a few days ago that I posted about this
https://staging.qb64phoenix.com/showthread.php?tid=65

So I changed it to take into account leap-years.  Very interesting.
The big "Int" statement starts the year with March, and Jan & Feb get moved to 13 and 14. Then the MOD 365 brings them back.
This code has just numerics; no strings.  Great fun.  Thanks.

Code: (Select All)
Print "m d", 2022, 2024, 2100, 2400
For m = 1 To 12
  Print m; 1, func(m, 1, 2022), func(m, 1, 2024), func(m, 1, 2100), func(m, 1, 2400)
Next m
Print 12; 31, func(12, 31, 2022), func(12, 31, 2024), func(12, 31, 2100), func(12, 31, 2400)

Function func (m, d, y)
  ret = d + Int((295 + 153 * ((m + 9) Mod 12) + 2) / 5) Mod 365
  If y Mod 4 = 0 And (y Mod 100 <> 0 Or y Mod 400 = 0) And m > 2 Then ret = ret + 1
  func = ret
End Function
Reply
#5
Ah, there's the one-liner calculation. I've seen it in JavaScript and C, but couldn't remember where I saw it in BASIC either on the dot net or dot rip site.

Thanks!

Pete
If eggs are brain food, Biden takes his scrambled.
Reply
#6
No Pete you are right.  I said F' leap years.  Every year is a leap year.  Since I was only using it as a Record # pointer.  My way (always a leap year.) I can compare or evaluate year over year records.  With out adjust the record number for leap years.

I only used case to simplify it for the general beginner.  I remember the old days of squeezing out bytes and cycles in assembler. Cycles+(conditional cycles)*(1/freq).  And hope to god, the byte count was not more than the 2K sometimes 1K eprom.
Reply
#7
(05-05-2022, 02:10 PM)doppler Wrote: No Pete you are right.  I said F' leap years.  Every year is a leap year.  Since I was only using it as a Record # pointer.  My way (always a leap year.) I can compare or evaluate year over year records.  With out adjust the record number for leap years.

I only used case to simplify it for the general beginner.  I remember the old days of squeezing out bytes and cycles in assembler. Cycles+(conditional cycles)*(1/freq).  And hope to god, the byte count was not more than the 2K sometimes 1K eprom.

LOL @F Leap Years. You know me, of all people, I saw that REM statement and thought the "F" stood for "For" Shame on me, I should F'n know better! Also, for a BEGINNER, yes, I totally agree. The SELECT CASE CODE is soooooo much easier to wrap the brain around than parsing a data string. The coolest thing about coding is there are so many roads to our destinations. We just have to be there to help those coders traveling them in the wrong direction. Reminds me of that joke, There's the high road and the low road. I like to take the high one, because there's less traffic.

Oh, and I tried some assembly, back in the day, too; but I'd usually finish the aspirin before I'd finish most projects. Yeah, push this ! Now if you will excuse me, I have to go install a Windows f'update.

Pete
Reply
#8
Please show also: https://qb64forum.alephc.xyz/index.php?t...#msg107775
Why not yes ?
Reply
#9
Let's throw a monkey wrench into the discussion.  Did you account for the missing 10 days?

https://www.britannica.com/story/ten-day...n-calendar
Reply
#10
(05-07-2022, 01:27 PM)doppler Wrote: Let's throw a monkey wrench into the discussion.  Did you account for the missing 10 days?

https://www.britannica.com/story/ten-day...n-calendar

Works for dates after october,15, 1582 Wink
Why not yes ?
Reply




Users browsing this thread: 4 Guest(s)