Author Topic: Time to Days, hours, minutes and seconds  (Read 8987 times)

MrTAToad

  • Guest
This code (modified from Matt Bennett's routine) converts the time (from 1970) to the number of days, hours, minutes and seconds :

Code: (glbasic) [Select]
INLINE
extern "C" int time (int * timer );
ENDINLINE

FUNCTION GetTime%:
INLINE
return time(0);
ENDINLINE
ENDFUNCTION

FUNCTION DaysHoursMinutesSeconds%:SrcTime%,BYREF days%,BYREF hours%,BYREF minutes%,BYREF seconds%
LOCAL TO_DAYS% = 86400
LOCAL TO_HOURS% = 3600
LOCAL TO_MINUTES% = 60

days% = SrcTime% / TO_DAYS%
hours%= INTEGER(( SrcTime% - (days% * TO_DAYS%) ) / ( TO_HOURS% ))
minutes%=INTEGER(( SrcTime% - (days% * TO_DAYS%) - (hours% * TO_HOURS% ) ) / TO_MINUTES%)
seconds%=INTEGER(( SrcTime% - (days% * TO_DAYS%) - (hours% * TO_HOURS% ) - (minutes% * TO_MINUTES%) ))
ENDFUNCTION

Test code :

Code: (glbasic) [Select]
LOCAL days%,hours%,minutes%,seconds%

DaysHoursMinutesSeconds(GetTime(),days%,hours%,minutes%,seconds%)
DEBUG "Day : "+days%+" Hour : "+hours%+" Minute : "+minutes%+" Seconds : "+seconds%+"\n"

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10732
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Time to Days, hours, minutes and seconds
« Reply #1 on: 2012-May-22 »
Oh! Many thanks! I always wanted such a routine. But I'd need one that goes back into -2000 a.D.
Is there some way to be able to calculate this? Next step would be to sync this times with other calendars. The hebrew one in detail.


Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
Re: Time to Days, hours, minutes and seconds
« Reply #2 on: 2012-May-22 »
Oh! Many thanks! I always wanted such a routine. But I'd need one that goes back into -2000 a.D.
Is there some way to be able to calculate this? Next step would be to sync this times with other calendars. The hebrew one in detail.

I think the Boost Date library's can handle them sort of dates. I will have a look at my old pascal code as I wrote various date handling routines (Julian/Gregorian) etc as well as degree/mins/secs & trajectories of our planets. From what I recall (was 7-8 years+ ago) the maths was not fun but at least I won't have to go through that again as converting my pascal code is a lot more easier  :D

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

MrTAToad

  • Guest
Re: Time to Days, hours, minutes and seconds
« Reply #3 on: 2012-May-22 »
It would be a bit of work, especially when you meet the switchover of calendars :)


Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10732
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Time to Days, hours, minutes and seconds
« Reply #4 on: 2012-May-23 »
totally. I think I would start an approach where I add 1 day in a loop and then try to convert that. But it looks liks the most stupid aproach ever :)

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
Re: Time to Days, hours, minutes and seconds
« Reply #5 on: 2012-May-23 »
Basically working in Julian Date format is probably the easiest as dates/months/years etc are stored as a single float so a simple subtraction should give you the amount of time passed. The following code is in Pascal from my old astronomy program I wrote to control my telescope (took a bit of digging out lol) & I will hopefully convert it to GLB when time permits, just am a tad busy at the moment but should be quite straight forward.

This 1st part converts normal hour/day/month/year to Modified Julian Date format which you would call twice with your 2 dates you want converted.

Code: (glbasic) [Select]
(*-----------------------------------------------------------------------*)
(* MJD: Modified Julian Date                                             *)
(*      The routine is valid for any date since 4713 BC.                 *)
(*      Julian calendar is used up to 1582 October 4,                    *)
(*      Gregorian calendar is used from 1582 October 15 onwards.         *)
(*-----------------------------------------------------------------------*)
FUNCTION MJD(DAY,MONTH,YEAR:INTEGER;HOUR:REAL):REAL;
  VAR A: REAL; B: INTEGER;
  BEGIN
    A:=10000.0*YEAR+100.0*MONTH+DAY;
    IF (MONTH<=2) THEN BEGIN MONTH:=MONTH+12; YEAR:=YEAR-1 END;
    IF (A<=15821004.1)
      THEN B:=-2+TRUNC((YEAR+4716)/4)-1179
      ELSE B:=TRUNC(YEAR/400)-TRUNC(YEAR/100)+TRUNC(YEAR/4);
    A:=365.0*YEAR-679004.0;
    MJD:=A+B+TRUNC(30.6001*(MONTH+1))+DAY+HOUR/24.0;
  END;


This 2nd part converts the Modified Julian Date back into our normal calender

Code: (glbasic) [Select]
(*----------------------------------------------------------------------*)
(* CALDAT: Finds the civil calendar date for a given value              *)
(*         of the Modified Julian Date (MJD).                           *)
(*         Julian calendar is used up to 1582 October 4,                *)
(*         Gregorian calendar is used from 1582 October 15 onwards.     *)
(*----------------------------------------------------------------------*)
PROCEDURE CALDAT(MJD:REAL; VAR DAY,MONTH,YEAR:INTEGER;VAR HOUR:REAL);
  VAR B,D,F     : INTEGER;
      JD,JD0,C,E: REAL;
  BEGIN
    JD  := MJD + 2400000.5;
        JD0 := INT(JD+0.5);             
    IF (JD0<2299161.0)                            (* calendar:    *)
      THEN BEGIN C:=JD0+1524.0 END                (* -> Julian    *)
      ELSE BEGIN                                  (* -> Gregorian *)
             B:=TRUNC((JD0-1867216.25)/36524.25);
             C:=JD0+(B-TRUNC(B/4))+1525.0
           END;
    D    := TRUNC((C-122.1)/365.25);          E     := 365.0*D+TRUNC(D/4);
    F    := TRUNC((C-E)/30.6001);
    DAY  := TRUNC(C-E+0.5)-TRUNC(30.6001*F);  MONTH := F-1-12*TRUNC(F/14);
    YEAR := D-4715-TRUNC((7+MONTH)/10);       HOUR  := 24.0*(JD+0.5-JD0);
  END;

@ Kitty, With a little bit of work I should be able to modify them to do your 2000BC etc calculations as the epoch of the Julian Date is 0=4713 BC.

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10732
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Time to Days, hours, minutes and seconds
« Reply #6 on: 2012-May-24 »
Excellent!!

OT:
BTW - have you ever thought about "why" the Julian starts at 4713 BC?
Just a hint - you can add all the birthdays in Genesis and book of kings in a line that has no "holes" (if you're digging deep enough). Also, check this page:
http://en.wikipedia.org/wiki/530s_BC
and see the date for 538 BC - That date is also mentioned in another scripture so we can overlap the old testament with the newer calenders at this year. It's really amazing.

Now, the year 0 in the bible starts with Adam+Eve. If there had been some humans _before_ them - would they have allowed this year to be 0 in the calendar?

Might shock you. Shocked me when I found out, too. I wanted to proof my brother in law a fool when I started researching about evolution facts and found out it's all estimations...

MrTAToad

  • Guest
Re: Time to Days, hours, minutes and seconds
« Reply #7 on: 2012-May-24 »
Here it is, nicely converted (still remember my Pascal) :

Code: (glbasic) [Select]
LOCAL day%,month%,year%,hour%

DEBUG MJD(24,5,1875,12)+"\n"
CALDAT(6032.5,day%,month%,year%,hour%)
DEBUG day%+" "+month%+" "+year%+" "+hour%

FUNCTION MJD:day%,month%,year%,hour
LOCAL a,b%

a=10000.0*year%+100.0*month%+day%
IF month%<=2
INC month%,12
DEC year%
ENDIF

IF a<=15821004.1
b=2+INTEGER((year%+4716)/4)-1179
ELSE
b=INTEGER(year%/400)-INTEGER(year%/100)+INTEGER(year%/4)
ENDIF

a=365.0*year%-679004.0
RETURN a+b+INTEGER(30.6001*(month%+1))+day%+hour/24.0
ENDFUNCTION

FUNCTION CALDAT%:value,BYREF day%,BYREF month%,BYREF year%,BYREF hour%
LOCAL b%,d%,f%
LOCAL jd,jd0,c,e

jd=value+2400000.5
jd0=INTEGER(jd+0.5)
IF jd0<2299161.0
c=jd0+1524.0
ELSE
b%=INTEGER((jd0-1867216.25)/36524.25)
c=jd0+(b-INTEGER(b%/4))+1525.0
ENDIF

d%=INTEGER((c-122.1)/365.25); e=365.0*d+INTEGER(d%/4)
f%=INTEGER((c-e)/30.6001)
day%=INTEGER(c-e+0.5)-INTEGER(30.6001*f%); month%=f%-1-12*INTEGER(f%/14)
year%=d%-4715-INTEGER((7+month%)/10); hour%=24.0*(jd+0.5-jd0)
ENDFUNCTION

It current has a problem with a few date ranges :

8th 1st (1 hour) 1AD has a value -678565.9583

but converts it back to

12th 1st (1 hour) 1AD
« Last Edit: 2012-May-24 by MrTAToad »

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
Re: Time to Days, hours, minutes and seconds
« Reply #8 on: 2012-May-24 »
Thanks MrTAToad, was going to convert it this weekend as for once I have some spare time :))

Looks like I can play with other things in GLB instead :)

Lee

Sent from my GT-I5700 using Tapatalk 2
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

MrTAToad

  • Guest
Re: Time to Days, hours, minutes and seconds
« Reply #9 on: 2012-May-24 »
Not totally sure about the values at the moment, especially as a few dates does trip it up - does seem to be dates from before the 1500's

For example :

Code: (glbasic) [Select]
DEBUG MJD(24,5,1500,12)+"\n"
CALDAT(-130919.5,day%,month%,year%,hour%)
DEBUG day%+" "+month%+" "+year%+" "+hour%

There is a 4 day gain (28 5 1500 12) - not sure whether that is correct or not...
« Last Edit: 2012-May-24 by MrTAToad »

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
Re: Time to Days, hours, minutes and seconds
« Reply #10 on: 2012-May-24 »
Hmm, I wonder if the following has anything to do with it http://www.rmg.co.uk/explore/astronomy-and-time/time-facts/leap-years. Leap Years changed from the Julian calendar in our current Gregorian system so that might be a reason. I will read up more on it as things like this interest me  =D

Lee

Will see what output I get on my home machine this weekend as that has Delphi installed as well as Free Pascal on Linux & will enter the same dates you tried.
« Last Edit: 2012-May-24 by fuzzy70 »
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

Offline Slydog

  • Prof. Inline
  • *****
  • Posts: 930
  • KodeSource
    • View Profile
    • KodeSource
Re: Time to Days, hours, minutes and seconds
« Reply #11 on: 2012-May-24 »
Interesting code!  And discussion.
I never looked into the details of the code however, but here's how leap years are determined currently, if somebody didn't know.

  • A year is a leap year if it is evenly divisible by 4. eg: 2004,2008,2012 ARE leap years
  • UNLESS the year is also evenly divisible by 100. eg: 1800,1900,2100 are NOT leap years
  • UNLESS again the year is also evenly divisible by 400. eg: 1600,2000,2400 ARE leap years

So a year in 15xx, up until now, the skipped leap years would be 1700,1800,1900.
But that still only adds up to 3, not the 4 we're looking for. 
Unless of course your code does account for that.

Fascinating stuff.

[Edit] Just read your link fuzzy70, ha, ya, what they said!
« Last Edit: 2012-May-24 by Slydog »
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10732
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Time to Days, hours, minutes and seconds
« Reply #12 on: 2012-May-24 »
2000 was a skipped leap year. Wiki says:
Code: (glbasic) [Select]
if mod(year ,400)= 0
   is_leap_year
elseif mod(year,100)= 0
   not_leap_year
elseif mod(year, 4)=0
   is_leap_year
else
   not_leap_year

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
Re: Time to Days, hours, minutes and seconds
« Reply #13 on: 2012-May-24 »
2000 was a skipped leap year. Wiki says:
Code: (glbasic) [Select]
if mod(year ,400)= 0
   is_leap_year
elseif mod(year,100)= 0
   not_leap_year
elseif mod(year, 4)=0
   is_leap_year
else
   not_leap_year

2000 was a leap year as it is divisible by 400

Quote
The change from the Julian calendar to the Gregorian involved the change of the simple rule for leap-years to the more complex one in which century years should only be leap-years if they were divisible by 400. For example, 1700, 1800 and 1900 are not leap-years whereas 2000 was

From the link I posted earlier  =D

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

Offline erico

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 4291
    • View Profile
    • Portfolio
Re: Time to Days, hours, minutes and seconds
« Reply #14 on: 2012-May-24 »
... Also, check this page:
http://en.wikipedia.org/wiki/530s_BC
and see the date for 538 BC - That date is also mentioned in another scripture so we can overlap the old testament with the newer calenders at this year. It's really amazing.

And Cyrus story is a great one. :good: