Time to Days, hours, minutes and seconds

Previous topic - Next topic

MrTAToad

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"

Kitty Hello

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.


fuzzy70

Quote from: Kitty Hello 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

It would be a bit of work, especially when you meet the switchover of calendars :)


Kitty Hello

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 :)

fuzzy70

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)

Kitty Hello

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

#7
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

fuzzy70

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

#9
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...

fuzzy70

#10
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.
"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)

Slydog

#11
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!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Kitty Hello

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

fuzzy70

Quote from: Kitty Hello 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)

erico

Quote from: Kitty Hello 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: