It's a glitch for negative years divisible by 100 and not 400....
Here's the fix:
_TITLE "Test Steve timeStamp" 'B+ test 2019-08-24 '2019-08-24 Quick test Steve timestamp by comparing DiffDateTime$ to TimeStampDiff$
'I am just testing day counts
times$ = "00:00:00": times## = 0
dates$(3) = "08-24-2019": dates$(2) = "01-01-2020": dates$(1) = "01-01-2021": dates$(0) = "01-01-2025"
dates$(4) = "01-01-2019": dates$(5) = "01-01-1970": dates$(6) = "01-01-1815"
PRINT dates$
(i
);
" Minus "; dates$
(j
) PRINT DiffDateTime$
(DateTime$
(dates$
(i
), times$
), DateTime$
(dates$
(j
), times$
)) PRINT TimeStampDiff$
(dates$
(i
), time##
, dates$
(j
), time##
) INPUT "OK ... press enter "; w$
d1970$ = "01-01-1970"
PRINT d1970$;
" Minus "; d$
PRINT DiffDateTime$
(DateTime$
(d1970$
, times$
), DateTime$
(d$
, times$
)) PRINT TimeStampDiff$
(d1970$
, time##
, d$
, time##
) INPUT "OK ... press enter "; w$
' I used this code for Count Down 2020
'note: this uses 2 dates and times formatted with DateTime$() Function
FUNCTION DiffDateTime$
(LaterDate$
, MinusEarlierDate$
) es
= VAL(MID$(MinusEarlierDate$
, 18, 2))
em
= VAL(MID$(MinusEarlierDate$
, 15, 2))
eh
= VAL(MID$(MinusEarlierDate$
, 12, 2))
ed
= VAL(MID$(MinusEarlierDate$
, 9, 2))
emm
= VAL(MID$(MinusEarlierDate$
, 6, 2))
ey
= VAL(MID$(MinusEarlierDate$
, 1, 4))
IF es
> ls
THEN ls
= ls
+ 60: lm
= lm
- 1 DiffDateTime$
= STR$(ls
- es
) + " secs"
IF em
> lm
THEN lm
= lm
+ 60: lh
= lh
- 1 DiffDateTime$
= STR$(lm
- em
) + " mins" + DiffDateTime$
IF eh
> lh
THEN lh
= lh
+ 24: ld
= ld
- 1 DiffDateTime$
= STR$(lh
- eh
) + " hours" + DiffDateTime$
''did we barrow off day
CASE 1: ly
= ly
- 1: lmm
= 12: ld
= 31 CASE 3:
IF IsLeapYear
(ly
) = 1 THEN lmm
= 2: ld
= 29 ELSE lmm
= 2: ld
= 28 CASE 5, 7, 8, 10, 12: lmm
= lmm
- 1: ld
= 30 CASE 2, 4, 6, 9, 11: lmm
= lmm
- 1: ld
= 31 'PRINT ly, lmm, ld ' check target and start
'PRINT ey, emm, ed
'now count days
ed = ed + 1
cnt = cnt + 1
'is it leap year
'pass
emm = 3: ed = 1
emm = 3: ed = 1
emm = emm + 1: ed = 1
ed = 1: emm = 1: ey = ey + 1
ed = 1: emm = emm + 1
'PRINT ey, emm, ed, ly; " "; lmm; " "; ld 'Check progress
'_LIMIT 2
DiffDateTime$
= _TRIM$(STR$(cnt
)) + " Days and" + DiffDateTime$
CurrentDateTime$ = " - - _ : : "
FUNCTION DateTime$
(mm_dd_yy$
, hh_mm_ss$
) DateTime$ = " - - _ : : "
MID$(DateTime$
, 1, 4) = MID$(mm_dd_yy$
, 7, 4) MID$(DateTime$
, 6, 5) = MID$(mm_dd_yy$
, 1, 5) MID$(DateTime$
, 12, 8) = hh_mm_ss$
FUNCTION IsLeapYear%
(yr
) 'mod from Pete's calendar this is a very clear calc IsLeapYear = 1
'this calc date time diff using Steve' TimeStamp## secs
FUNCTION TimeStampDiff$
(LaterDate$
, LaterTime##
, EarlierDate$
, EarlierTime##
) secLate## = TimeStamp##(LaterDate$, LaterTime##)
secEarly## = TimeStamp##(EarlierDate$, EarlierTime##)
secDiff = secLate## - secEarly##
'covert to days, hours, minutes, secs I am dropping fraction secs for test
days
= INT(secDiff
/ 86400) secDiff = secDiff - days * 86400
hours
= INT(secDiff
/ 3600) secDiff = secDiff - hours * 3600
minutes
= INT(secDiff
/ 60) secs
= INT(secDiff
- minutes
* 60)
' Steve's latest version
' https://www.qb64.org/forum/index.php?topic=1638.msg108650#msg108650
FUNCTION TimeStamp##
(d$
, t##
) 'date and timer 'Based on Unix Epoch time, which starts at year 1970.
IF y
< 1970 THEN 'calculate shit backwards SELECT CASE m
'turn the day backwards for the month CASE 1, 3, 5, 7, 8, 10, 12: d
= 31 - d
'31 days CASE 2: d
= 28 - d
'special 28 or 29. CASE 4, 6, 9, 11: d
= 30 - d
'30 days IF y
MOD 4 = 0 AND m
< 3 THEN 'check for normal leap year, and we're before it... d = d - 1 'assume we had a leap year, subtract another day
IF y
MOD 100 = 0 AND y
MOD 400 <> 0 THEN d
= d
+ 1 'not a leap year if year is divisible by 100 and not 400
'then count the months that passed after the current month
CASE 3, 5, 7, 8, 10, 12: d
= d
- 31 CASE 4, 6, 9, 11: d
= d
- 30
'we should now have the entered year calculated. Now lets add in for each year from this point to 1970
d = d + 365 * (1969 - y) '365 days per each standard year
FOR i
= 1968 TO y
+ 1 STEP -4 'from 1968 onwards,backwards, skipping the current year (which we handled previously in the FOR loopp) d = d + 1 'subtract an extra day every leap year
IF (i
MOD 100) = 0 AND (i
MOD 400) <> 0 THEN d
= d
- 1 'but skiping every year divisible by 100, but not 400 s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
TimeStamp## = -(s## + 24 * 60 * 60 - t##)
y = y - 1970
FOR i
= 1 TO m
'for this year, SELECT CASE i
'Add the number of days for each previous month passed CASE 1: d
= d
'January doestn't have any carry over days. CASE 2, 4, 6, 8, 9, 11: d
= d
+ 31 CASE 3 'Feb might be a leap year IF (y
MOD 4) = 2 THEN 'if this year is divisible by 4 (starting in 1972) d = d + 29 'its a leap year
d = d - 1 'the year is divisible by 100, and not divisible by 400
ELSE 'year not divisible by 4, no worries d = d + 28
CASE 5, 7, 10, 12: d
= d
+ 30 d = (d - 1) + 365 * y 'current month days passed + 365 days per each standard year
FOR i
= 2 TO y
- 1 STEP 4 'from 1972 onwards, skipping the current year (which we handled previously in the FOR loopp) d = d + 1 'add an extra day every leap year
IF (i
MOD 100) = 30 AND (i
MOD 400) <> 30 THEN d
= d
- 1 'but skiping every year divisible by 100, but not 400 s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
TimeStamp## = (s## + t##)
This glitch makes perfect sense to me (unlike the swapped signs):
In the second half of the code (where we count forwards), we see this line -- IF (i MOD 100) = 30 AND (i MOD 400) <> 30 THEN d = d - 1 'but skiping every year divisible by 100, but not 400
And then, it was simply copy/pasted into the top half of the code, as is, which doesn't work.
In the bottom half, we subtract 1970 from our year, and start calculating as if we're working up from year 0. 30 years would be the year 2000. 130 years would be the year 2100... Years mod 100 = 30, are the years we need to check to see if they're leap years or not...
In the top half, we work with the date directly, without subtracting that 1970... 1900 is 1900, not -70... We have to year mod 100 = 0 to check for those special "are they, aren't they" leap years?
A simple change of the remainder in those MOD statements, and all appears to be working correctly. (Of course, I've thought that before, and some edge case always seems to show up to toss that idea upside down on its head...)