Author Topic: Function Timestamp  (Read 14383 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #15 on: August 21, 2019, 09:09:13 am »
In fact 2000 WAS a leap year as usual. It is because it was divisible but 100 BUT ALSO by 400!

Yikes! nothing like wasting allot of time under a false premise.

Well it's not wasted if I learn something positive from it!




Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #16 on: August 21, 2019, 09:25:14 am »
Quote
The toolbox ExtendedTimer gives us the right result just because it's wrong at being wrong!  0_o!!

The toolbox code last edited August 11, 2019 is still flawed when the current month is < 3
Code: QB64: [Select]
  1. SHELL "https://www.epochconverter.com/"
  2.     CLS
  3.     PRINT TIMER, INT(ExtendedTimer)
  4.     PRINT "Compare to the time at https://www.epochconverter.com/"
  5.     _DISPLAY
  6.     _LIMIT 10
  7.  
  8. FUNCTION ExtendedTimer##
  9.     d$ = DATE$
  10.     l = INSTR(d$, "-")
  11.     l1 = INSTR(l + 1, d$, "-")
  12.     m = VAL(LEFT$(d$, l))
  13.     d = VAL(MID$(d$, l + 1))
  14.     y = VAL(MID$(d$, l1 + 1)) - 1970
  15.     FOR i = 1 TO m
  16.         SELECT CASE i 'Add the number of days for each previous month passed
  17.             CASE 1: d = d 'January doestn't have any carry over days.
  18.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  19.             CASE 3: d = d + 28
  20.             CASE 5, 7, 10, 12: d = d + 30
  21.         END SELECT
  22.     NEXT
  23.     FOR i = 1 TO y
  24.         d = d + 365
  25.     NEXT
  26.     FOR i = 2 TO y STEP 4
  27.         IF m > 2 THEN d = d + 1 'add an extra day for leap year every 4 years, starting in 1970
  28.     NEXT
  29.     d = d - 1 'for year 2000
  30.     s~&& = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  31.     ExtendedTimer## = (s~&& + TIMER)

« Last Edit: August 21, 2019, 09:30:23 am by bplus »

Offline petoro

  • Newbie
  • Posts: 27
    • View Profile
Re: Function Timestamp
« Reply #17 on: August 21, 2019, 01:15:01 pm »
Yikes! nothing like wasting allot of time under a false premise.

Well it's not wasted if I learn something positive from it!

The western calendar has some twisted details :)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #18 on: August 21, 2019, 01:42:12 pm »
The western calendar has some twisted details :)

:)) What's twisted are the Earth's rotations and revolutions.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Function Timestamp
« Reply #19 on: August 22, 2019, 11:18:55 am »
TimeStamp should now work with all dates for us, even giving us the negative timestamps for dates/times before 1970.

Code: QB64: [Select]
  1. SHELL "https://www.epochconverter.com/"
  2. PRINT "Compare to time stamps generated at the website which popped up in your browser.https://www.epochconverter.com/"
  3.  
  4.     PRINT
  5.     PRINT
  6.     INPUT "Give me a DATE$ in format of DD-MM-YYYY"; d$
  7.     IF d$ = "" THEN SYSTEM
  8.     INPUT "Give me a TIMER value from 0 to 86399.999"; t##
  9.     PRINT
  10.     PRINT
  11.     PRINT "Your current timestamp is =>:"; TimeStamp(d$, t##)
  12.  
  13.  
  14. FUNCTION TimeStamp## (d$, t##) 'date and timer
  15.     'Based on Unix Epoch time, which starts at year 1970.
  16.     DIM s AS _FLOAT
  17.  
  18.     l = INSTR(d$, "-")
  19.     l1 = INSTR(l + 1, d$, "-")
  20.     m = VAL(LEFT$(d$, l))
  21.     d = VAL(MID$(d$, l + 1))
  22.     y = VAL(MID$(d$, l1 + 1))
  23.     IF y < 1970 THEN 'calculate shit backwards
  24.         SELECT CASE m 'turn the day backwards for the month
  25.             CASE 1, 3, 5, 7, 8, 10, 12: d = 31 - d '31 days
  26.             CASE 2: d = 28 - d 'special 28 or 29.
  27.             CASE 4, 6, 9, 11: d = 30 - d '30 days
  28.         END SELECT
  29.         IF y MOD 4 = 0 AND m < 3 THEN 'check for normal leap year, and we're before it...
  30.             d = d + 1 'assume we had a leap year, subtract another day
  31.             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
  32.         END IF
  33.  
  34.         'then count the months that passed after the current month
  35.         FOR i = m + 1 TO 12
  36.             SELECT CASE i
  37.                 CASE 2: d = d + 28
  38.                 CASE 3, 5, 7, 8, 10, 12: d = d + 31
  39.                 CASE 4, 6, 9, 11: d = d + 30
  40.             END SELECT
  41.         NEXT
  42.  
  43.         'we should now have the entered year calculated.  Now lets add in for each year from this point to 1970
  44.         d = d + 365 * (1969 - y) '365 days per each standard year
  45.         FOR i = 1968 TO y + 1 STEP -4 'from 1968 onwards,backwards, skipping the current year (which we handled previously in the FOR loopp)
  46.             d = d + 1 'subtract an extra day every leap year
  47.             IF (i MOD 100) = 0 AND (i MOD 400) <> 0 THEN d = d - 1 'but skiping every year divisible by 100, but not 400
  48.         NEXT
  49.         s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  50.         TimeStamp## = -(s## + 24 * 60 * 60 - t##)
  51.         EXIT FUNCTION
  52.     ELSE
  53.         y = y - 1970
  54.     END IF
  55.  
  56.     FOR i = 1 TO m 'for this year,
  57.         SELECT CASE i 'Add the number of days for each previous month passed
  58.             CASE 1: d = d 'January doestn't have any carry over days.
  59.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  60.             CASE 3 'Feb might be a leap year
  61.                 IF (y MOD 4) = 2 THEN 'if this year is divisible by 4 (starting in 1972)
  62.                     d = d + 29 'its a leap year
  63.                     IF (y MOD 100) = 30 AND (y MOD 400) <> 30 THEN 'unless..
  64.                         d = d - 1 'the year is divisible by 100, and not divisible by 400
  65.                     END IF
  66.                 ELSE 'year not divisible by 4, no worries
  67.                     d = d + 28
  68.                 END IF
  69.             CASE 5, 7, 10, 12: d = d + 30
  70.         END SELECT
  71.     NEXT
  72.     d = (d - 1) + 365 * y 'current month days passed + 365 days per each standard year
  73.     FOR i = 2 TO y - 1 STEP 4 'from 1972 onwards, skipping the current year (which we handled previously in the FOR loopp)
  74.         d = d + 1 'add an extra day every leap year
  75.         IF (i MOD 100) = 30 AND (i MOD 400) <> 30 THEN d = d - 1 'but skiping every year divisible by 100, but not 400
  76.     NEXT
  77.     s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  78.     TimeStamp## = (s## + t##)
  79.  
  80. FUNCTION ExtendedTimer##
  81.     ExtendedTimer = TimeStamp(DATE$, TIMER)
« Last Edit: August 25, 2019, 05:53:36 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #20 on: August 22, 2019, 03:24:08 pm »
LOL
Quote
   IF y < 1970 THEN 'calculate shit backwards
Nice to extend this back!

Steve, have you considered a timestamp decoder ring? a reverse function to restore date and time.

Also something I've noticed from start:
Code: QB64: [Select]
  1.     l = INSTR(d$, "-")
  2.     l1 = INSTR(l + 1, d$, "-")
  3.     m = VAL(LEFT$(d$, l))
  4.     d = VAL(MID$(d$, l + 1))
  5.     y = VAL(MID$(d$, l1 + 1))
  6.  

loose l and l1 variables and use straight MID$ extraction of m, d, y and you loose the restriction of the separator having to be "-" thusly a "/", a space, any single character would work just as well.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #21 on: August 22, 2019, 03:47:43 pm »
Wait... before we spend another second (or I in checking code of this coding exercise), can someone review for me the practical benefits it might serve?

Steve, you said yourself you use a different system for autosave, one I can appreciate for it's transparency.

Wait... maybe I can for myself, using it to calculate date and time differences. My code that I worked out yesterday was pretty inefficient counting one by one the days until I reach the later date. Converting to seconds, subtracting seconds and then converting to days hours minutes secs.... might be easier or more efficient.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Function Timestamp
« Reply #22 on: August 22, 2019, 04:05:20 pm »
Wait... before we spend another second (or I in checking code of this coding exercise), can someone review for me the practical benefits it might serve?

Steve, you said yourself you use a different system for autosave, one I can appreciate for it's transparency.

Wait... maybe I can for myself, using it to calculate date and time differences. My code that I worked out yesterday was pretty inefficient counting one by one the days until I reach the later date. Converting to seconds, subtracting seconds and then converting to days hours minutes secs.... might be easier or more efficient.

I haven’t used it for a time stamp before (which is why there was so many little glitches to work out); what I use all the time is the ExtendedTimer.  QB64 has 2 ways we can track time — TIME$ and TIMER. For most usages, I find myself using TIMER a lot more than I would TIME$ (it’s hard to add and subtract hours, minutes, and seconds...), but TIMER has one great flaw...

MIDNIGHT!!

Start a program at 11:59:59 PM (86399 seconds), and wait 10 seconds to do something....  and you’ll wait forever with IF TIMER > StartTime + 10 THEN....

Your timer goes back to 0 at midnight, so you’ll never pass (86409 seconds) — putting your program into an endless loop.

Thus, I added ExtendedTimer.  It tracks time with days, months, years, so midnight is no longer an issue.  Where “IF TIMER > StartTime + 10 THEN....” fails at midnight, “IF ExtendedTimer > StartTime + 10 THEN...” doesn’t.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #23 on: August 22, 2019, 04:43:47 pm »
Easier way, check if Timer < StartTime and fix accordingly with a day's worth of secs, that saves bloating code with another procedure  If Timer < StartTime then StartTime = StartTime - 24*60*60

Extended timer would work if run something more than a day (I don't) and Timer is no good for that kind usage either.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Function Timestamp
« Reply #24 on: August 24, 2019, 05:48:42 pm »
Heya boys,

I apologize for not following this thread to a tee, and not doing my proper reading on the tit-for-tat that happened... but can one of you fine gentleman reply to this with what *should* appear in the toolbox? Thanks kindly.
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #25 on: August 24, 2019, 06:00:09 pm »
Heya boys,

I apologize for not following this thread to a tee, and not doing my proper reading on the tit-for-tat that happened... but can one of you fine gentleman reply to this with what *should* appear in the toolbox? Thanks kindly.

Steve has something very interesting posted in #19 August 22

I have not had a chance to give it a test drive, I did want to check and see how it did calculating time & date differences for my submission for code challenge "Count Down 2020" but then Ken came up with more interesting problem and I got side tracked.

Not that you need my seal of approval, but it would be nice if someone tried to break it before submitting to librarian to save librarian's valuable time spent editing buggy code.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Function Timestamp
« Reply #26 on: August 24, 2019, 06:18:30 pm »
Here's what I'd call the "official version" of these two routines reworked for goodness's sake:

Code: QB64: [Select]
  1. SHELL "https://www.epochconverter.com/"
  2. PRINT "Compare to time stamps generated at the website which popped up in your browser.https://www.epochconverter.com/"
  3.  
  4. CONST MyTimeZone## = 4 * 3600
  5.  
  6.     _LIMIT 1
  7.     CLS
  8.     PRINT TimeStamp(DATE$, TIMER + MyTimeZone) 'Timezone difference with GMT, which is what the webpage sometimes points to.
  9.     '                                           If the times seem off from the website, you'll want to change the timezone
  10.     '                                           offset to match your current time zone.
  11.     PRINT ExtendedTimer 'Unix Epoch Timer based on local time.
  12.     _DISPLAY
  13.  
  14.  
  15. FUNCTION TimeStamp## (d$, t##) 'date and timer
  16.     'Based on Unix Epoch time, which starts at year 1970.
  17.     DIM s AS _FLOAT
  18.  
  19.     l = INSTR(d$, "-")
  20.     l1 = INSTR(l + 1, d$, "-")
  21.     m = VAL(LEFT$(d$, l))
  22.     d = VAL(MID$(d$, l + 1))
  23.     y = VAL(MID$(d$, l1 + 1))
  24.     IF y < 1970 THEN 'calculate shit backwards
  25.         SELECT CASE m 'turn the day backwards for the month
  26.             CASE 1, 3, 5, 7, 8, 10, 12: d = 31 - d '31 days
  27.             CASE 2: d = 28 - d 'special 28 or 29.
  28.             CASE 4, 6, 9, 11: d = 30 - d '30 days
  29.         END SELECT
  30.         IF y MOD 4 = 0 AND m < 3 THEN 'check for normal leap year, and we're before it...
  31.             d = d + 1 'assume we had a leap year, subtract another day
  32.             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
  33.         END IF
  34.  
  35.         'then count the months that passed after the current month
  36.         FOR i = m + 1 TO 12
  37.             SELECT CASE i
  38.                 CASE 2: d = d + 28
  39.                 CASE 3, 5, 7, 8, 10, 12: d = d + 31
  40.                 CASE 4, 6, 9, 11: d = d + 30
  41.             END SELECT
  42.         NEXT
  43.  
  44.         'we should now have the entered year calculated.  Now lets add in for each year from this point to 1970
  45.         d = d + 365 * (1969 - y) '365 days per each standard year
  46.         FOR i = 1968 TO y + 1 STEP -4 'from 1968 onwards,backwards, skipping the current year (which we handled previously in the FOR loop)
  47.             d = d + 1 'subtract an extra day every leap year
  48.             IF (i MOD 100) = 0 AND (i MOD 400) <> 0 THEN d = d - 1 'but skipping every year divisible by 100, but not 400
  49.         NEXT
  50.         s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  51.         TimeStamp## = -(s## + 24 * 60 * 60 - t##)
  52.         EXIT FUNCTION
  53.     ELSE
  54.         y = y - 1970
  55.     END IF
  56.  
  57.     FOR i = 1 TO m 'for this year,
  58.         SELECT CASE i 'Add the number of days for each previous month passed
  59.             CASE 1: d = d 'January doestn't have any carry over days.
  60.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  61.             CASE 3 'Feb might be a leap year
  62.                 IF (y MOD 4) = 2 THEN 'if this year is divisible by 4 (starting in 1972)
  63.                     d = d + 29 'its a leap year
  64.                     IF (y MOD 100) = 30 AND (y MOD 400) <> 30 THEN 'unless..
  65.                         d = d - 1 'the year is divisible by 100, and not divisible by 400
  66.                     END IF
  67.                 ELSE 'year not divisible by 4, no worries
  68.                     d = d + 28
  69.                 END IF
  70.             CASE 5, 7, 10, 12: d = d + 30
  71.         END SELECT
  72.     NEXT
  73.     d = (d - 1) + 365 * y 'current month days passed + 365 days per each standard year
  74.     FOR i = 2 TO y - 1 STEP 4 'from 1972 onwards, skipping the current year (which we handled previously in the FOR loopp)
  75.         d = d + 1 'add an extra day every leap year
  76.         IF (i MOD 100) = 30 AND (i MOD 400) <> 30 THEN d = d - 1 'but skiping every year divisible by 100, but not 400
  77.     NEXT
  78.     s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  79.     TimeStamp## = (s## + t##)
  80.  
  81. FUNCTION ExtendedTimer##
  82.     'Simplified version of the TimeStamp routine, streamlined to only give positive values based on the current timer.
  83.     'Note:  Only good until the year 2100, as we don't do all the fancy calculations for leap years.
  84.     'A timer should work quickly and efficiently in the background; and the less we do, the less lag we might insert
  85.     'into a program.
  86.  
  87.     DIM m AS INTEGER, d AS INTEGER, y AS INTEGER
  88.     DIM s AS _FLOAT, day AS STRING
  89.     day = DATE$
  90.     m = VAL(LEFT$(day, 2))
  91.     d = VAL(MID$(day, 4, 2))
  92.     y = VAL(RIGHT$(day, 4)) - 1970
  93.     SELECT CASE m 'Add the number of days for each previous month passed
  94.         CASE 2: d = d + 31
  95.         CASE 3: d = d + 59
  96.         CASE 4: d = d + 90
  97.         CASE 5: d = d + 120
  98.         CASE 6: d = d + 151
  99.         CASE 7: d = d + 181
  100.         CASE 8: d = d + 212
  101.         CASE 9: d = d + 243
  102.         CASE 10: d = d + 273
  103.         CASE 11: d = d + 304
  104.         CASE 12: d = d + 334
  105.     END SELECT
  106.     IF (y MOD 4) = 2 AND m > 2 THEN d = d + 1 'add a day if this is leap year and we're past february
  107.     d = (d - 1) + 365 * y 'current month days passed + 365 days per each standard year
  108.     d = d + (y + 2) \ 4 'add in days for leap years passed
  109.     s = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  110.     ExtendedTimer## = (s + TIMER)
  111.  

The demo should speak for itself, I'd hope.  ;)
« Last Edit: August 25, 2019, 05:54:55 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #27 on: August 24, 2019, 09:12:38 pm »
Hi Steve,

I am using this code to calculate difference in dates using your timeStamp## and code I used in my last post in Count  Down 2020:
Code: QB64: [Select]
  1.  
  2. FUNCTION TimeStampDiff$ (LaterDate$, LaterTime##, EarlierDate$, EarlierTime##)
  3.     secLate## = TimeStamp##(LaterDate$, LaterTime##)
  4.     secEarly## = TimeStamp##(EarlierDate$, EarlierTime##)
  5.     secDiff = secLate## - secEarly##
  6.     'covert to days, hours, minutes, secs I am dropping fraction secs for test
  7.     days = INT(secDiff / 86400)
  8.     secDiff = secDiff - days * 86400
  9.     hours = INT(secDiff / 3600)
  10.     secDiff = secDiff - hours * 3600
  11.     minutes = INT(secDiff / 60)
  12.     secs = INT(secDiff - minutes * 60)
  13.     TimeStampDiff$ = _TRIM$(STR$(days)) + " Days and " + _TRIM$(STR$(hours)) + " Hours, " + _TRIM$(STR$(minutes)) + " Minutes, " + _TRIM$(STR$(secs))
  14.  

The good news we agree for years >=1970, bad news there is difference in days for years earlier than 1970.
This is the completely new section of your timeStamp## code that I thought should be tested because the web site can't verify your numbers in those circumstances.

I am currently revising the test to maybe help see what is off.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Function Timestamp
« Reply #28 on: August 24, 2019, 09:34:12 pm »
You can compare with the page here: https://www.epochconverter.com/

Times were matching at my last tests, unless I posted a glitchy version on the forums here...  I’ll recheck results again to see what’s up.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Function Timestamp
« Reply #29 on: August 24, 2019, 09:51:22 pm »
Hi Steve,

It's the new part of your code where you attempt dates before 1970, here is my test code:
Code: QB64: [Select]
  1. _TITLE "Test Steve timeStamp" 'B+ test 2019-08-24
  2. '2019-08-24 Quick test Steve timestamp by comparing DiffDateTime$ to TimeStampDiff$
  3. 'I am just testing day counts
  4.  
  5. SCREEN _NEWIMAGE(600, 760, 32)
  6. times$ = "00:00:00": times## = 0
  7.  
  8. dates$(3) = "08-24-2019": dates$(2) = "01-01-2020": dates$(1) = "01-01-2021": dates$(0) = "01-01-2025"
  9. dates$(4) = "01-01-2019": dates$(5) = "01-01-1970": dates$(6) = "01-01-1815"
  10.  
  11. FOR i = 0 TO 5
  12.     FOR j = i + 1 TO 6
  13.         PRINT dates$(i); " Minus "; dates$(j)
  14.         PRINT DiffDateTime$(DateTime$(dates$(i), times$), DateTime$(dates$(j), times$))
  15.         PRINT TimeStampDiff$(dates$(i), time##, dates$(j), time##)
  16.         PRINT
  17.     NEXT
  18.     INPUT "OK ... press enter "; w$
  19.     CLS
  20. d1970$ = "01-01-1970"
  21. FOR y = 1970 TO 1950 STEP -1
  22.     d$ = "01-01-" + _TRIM$(STR$(y))
  23.     PRINT d1970$; " Minus "; d$
  24.     PRINT DiffDateTime$(DateTime$(d1970$, times$), DateTime$(d$, times$))
  25.     PRINT TimeStampDiff$(d1970$, time##, d$, time##)
  26.     PRINT
  27.     IF y MOD 5 = 0 THEN
  28.         INPUT "OK ... press enter "; w$
  29.         CLS
  30.     END IF
  31.  
  32. ' I used this code for Count Down 2020
  33. 'note: this uses 2 dates and times formatted with DateTime$() Function
  34. FUNCTION DiffDateTime$ (LaterDate$, MinusEarlierDate$)
  35.     es = VAL(MID$(MinusEarlierDate$, 18, 2))
  36.     ls = VAL(MID$(LaterDate$, 18, 2))
  37.  
  38.     em = VAL(MID$(MinusEarlierDate$, 15, 2))
  39.     lm = VAL(MID$(LaterDate$, 15, 2))
  40.  
  41.     eh = VAL(MID$(MinusEarlierDate$, 12, 2))
  42.     lh = VAL(MID$(LaterDate$, 12, 2))
  43.  
  44.     ed = VAL(MID$(MinusEarlierDate$, 9, 2))
  45.     ld = VAL(MID$(LaterDate$, 9, 2))
  46.  
  47.     emm = VAL(MID$(MinusEarlierDate$, 6, 2))
  48.     lmm = VAL(MID$(LaterDate$, 6, 2))
  49.  
  50.     ey = VAL(MID$(MinusEarlierDate$, 1, 4))
  51.     ly = VAL(MID$(LaterDate$, 1, 4))
  52.  
  53.     IF es > ls THEN ls = ls + 60: lm = lm - 1
  54.     DiffDateTime$ = STR$(ls - es) + " secs"
  55.  
  56.     IF em > lm THEN lm = lm + 60: lh = lh - 1
  57.     DiffDateTime$ = STR$(lm - em) + " mins" + DiffDateTime$
  58.  
  59.     IF eh > lh THEN lh = lh + 24: ld = ld - 1
  60.     DiffDateTime$ = STR$(lh - eh) + " hours" + DiffDateTime$
  61.  
  62.     ''did we barrow off day
  63.     IF ld = 0 THEN
  64.         SELECT CASE lmm
  65.             CASE 1: ly = ly - 1: lmm = 12: ld = 31
  66.             CASE 3: IF IsLeapYear(ly) = 1 THEN lmm = 2: ld = 29 ELSE lmm = 2: ld = 28
  67.             CASE 5, 7, 8, 10, 12: lmm = lmm - 1: ld = 30
  68.             CASE 2, 4, 6, 9, 11: lmm = lmm - 1: ld = 31
  69.         END SELECT
  70.     END IF
  71.     'PRINT ly, lmm, ld   ' check target and start
  72.     'PRINT ey, emm, ed
  73.  
  74.     'now count days
  75.     DO
  76.         IF ly = ey THEN
  77.             IF lmm = emm THEN
  78.                 IF ld = ed THEN EXIT DO '  all date numbers match, done calc
  79.             END IF
  80.         END IF
  81.         ed = ed + 1
  82.         cnt = cnt + 1
  83.         IF ed = 29 AND emm = 2 THEN
  84.             'is it leap year
  85.             IF IsLeapYear%(ey) = 1 THEN
  86.                 'pass
  87.             ELSE
  88.                 emm = 3: ed = 1
  89.             END IF
  90.         ELSEIF ed = 30 AND emm = 2 THEN 'must be leap year
  91.             emm = 3: ed = 1
  92.         ELSEIF ed = 31 THEN
  93.             IF emm = 4 OR emm = 6 OR emm = 9 OR emm = 11 THEN
  94.                 emm = emm + 1: ed = 1
  95.             END IF
  96.         ELSEIF ed = 32 THEN
  97.             IF emm = 12 THEN
  98.                 ed = 1: emm = 1: ey = ey + 1
  99.             ELSE
  100.                 ed = 1: emm = emm + 1
  101.             END IF
  102.         END IF
  103.         'PRINT ey, emm, ed, ly; " "; lmm; " "; ld   'Check progress
  104.         '_LIMIT 2
  105.     LOOP
  106.     DiffDateTime$ = _TRIM$(STR$(cnt)) + " Days and" + DiffDateTime$
  107.  
  108. FUNCTION CurrentDateTime$
  109.     CurrentDateTime$ = "    -  -  _  :  :  "
  110.     MID$(CurrentDateTime$, 1, 4) = MID$(DATE$, 7, 4)
  111.     MID$(CurrentDateTime$, 6, 5) = MID$(DATE$, 1, 5)
  112.     MID$(CurrentDateTime$, 12, 8) = TIME$
  113.  
  114. FUNCTION DateTime$ (mm_dd_yy$, hh_mm_ss$)
  115.     DateTime$ = "    -  -  _  :  :  "
  116.     MID$(DateTime$, 1, 4) = MID$(mm_dd_yy$, 7, 4)
  117.     MID$(DateTime$, 6, 5) = MID$(mm_dd_yy$, 1, 5)
  118.     MID$(DateTime$, 12, 8) = hh_mm_ss$
  119.  
  120. FUNCTION IsLeapYear% (yr) 'mod from Pete's calendar this is a very clear calc
  121.     IF yr MOD 4 = 0 THEN
  122.         IF yr MOD 100 = 0 THEN
  123.             IF yr MOD 400 = 0 THEN IsLeapYear = 1
  124.         ELSE
  125.             IsLeapYear = 1
  126.         END IF
  127.     END IF
  128.  
  129. 'this calc date time diff using Steve' TimeStamp## secs
  130. FUNCTION TimeStampDiff$ (LaterDate$, LaterTime##, EarlierDate$, EarlierTime##)
  131.     secLate## = TimeStamp##(LaterDate$, LaterTime##)
  132.     secEarly## = TimeStamp##(EarlierDate$, EarlierTime##)
  133.     secDiff = secLate## - secEarly##
  134.     'covert to days, hours, minutes, secs I am dropping fraction secs for test
  135.     days = INT(secDiff / 86400)
  136.     secDiff = secDiff - days * 86400
  137.     hours = INT(secDiff / 3600)
  138.     secDiff = secDiff - hours * 3600
  139.     minutes = INT(secDiff / 60)
  140.     secs = INT(secDiff - minutes * 60)
  141.     TimeStampDiff$ = _TRIM$(STR$(days)) + " Days and " + _TRIM$(STR$(hours)) + " Hours, " + _TRIM$(STR$(minutes)) + " Minutes, " + _TRIM$(STR$(secs))
  142.  
  143. ' Steve's latest version
  144. ' https://www.qb64.org/forum/index.php?topic=1638.msg108650#msg108650
  145. FUNCTION TimeStamp## (d$, t##) 'date and timer
  146.     'Based on Unix Epoch time, which starts at year 1970.
  147.  
  148.     m = VAL(LEFT$(d$, 2))
  149.     d = VAL(MID$(d$, 4, 2))
  150.     y = VAL(RIGHT$(d$, 4))
  151.     IF y < 1970 THEN 'calculate shit backwards
  152.         SELECT CASE m 'turn the day backwards for the month
  153.             CASE 1, 3, 5, 7, 8, 10, 12: d = 31 - d '31 days
  154.             CASE 2: d = 28 - d 'special 28 or 29.
  155.             CASE 4, 6, 9, 11: d = 30 - d '30 days
  156.         END SELECT
  157.         IF y MOD 4 = 0 AND m < 3 THEN 'check for normal leap year, and we're before it...
  158.             d = d - 1 'assume we had a leap year, subtract another day
  159.             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
  160.         END IF
  161.  
  162.         'then count the months that passed after the current month
  163.         FOR i = m + 1 TO 12
  164.             SELECT CASE i
  165.                 CASE 2: d = d - 28
  166.                 CASE 3, 5, 7, 8, 10, 12: d = d - 31
  167.                 CASE 4, 6, 9, 11: d = d - 30
  168.             END SELECT
  169.         NEXT
  170.  
  171.         'we should now have the entered year calculated.  Now lets add in for each year from this point to 1970
  172.         d = d + 365 * (1969 - y) '365 days per each standard year
  173.         FOR i = 1968 TO y + 1 STEP -4 'from 1968 onwards,backwards, skipping the current year (which we handled previously in the FOR loopp)
  174.             d = d + 1 'subtract an extra day every leap year
  175.             IF (i MOD 100) = 30 AND (i MOD 400) <> 30 THEN d = d - 1 'but skiping every year divisible by 100, but not 400
  176.         NEXT
  177.         s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  178.         TimeStamp## = -(s## + 24 * 60 * 60 - t##)
  179.         EXIT FUNCTION
  180.     ELSE
  181.         y = y - 1970
  182.     END IF
  183.  
  184.     FOR i = 1 TO m 'for this year,
  185.         SELECT CASE i 'Add the number of days for each previous month passed
  186.             CASE 1: d = d 'January doestn't have any carry over days.
  187.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  188.             CASE 3 'Feb might be a leap year
  189.                 IF (y MOD 4) = 2 THEN 'if this year is divisible by 4 (starting in 1972)
  190.                     d = d + 29 'its a leap year
  191.                     IF (y MOD 100) = 30 AND (y MOD 400) <> 30 THEN 'unless..
  192.                         d = d - 1 'the year is divisible by 100, and not divisible by 400
  193.                     END IF
  194.                 ELSE 'year not divisible by 4, no worries
  195.                     d = d + 28
  196.                 END IF
  197.             CASE 5, 7, 10, 12: d = d + 30
  198.         END SELECT
  199.     NEXT
  200.     d = (d - 1) + 365 * y 'current month days passed + 365 days per each standard year
  201.     FOR i = 2 TO y - 1 STEP 4 'from 1972 onwards, skipping the current year (which we handled previously in the FOR loopp)
  202.         d = d + 1 'add an extra day every leap year
  203.         IF (i MOD 100) = 30 AND (i MOD 400) <> 30 THEN d = d - 1 'but skiping every year divisible by 100, but not 400
  204.     NEXT
  205.     s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  206.     TimeStamp## = (s## + t##)
  207.