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

• HelpEditors
• Prof. Inline
• Posts: 5341
• Its me!
##### Re: Time to Days, hours, minutes and seconds
« Reply #15 on: 2012-May-24 »
Quote
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.
That'll be good - if they differ, then there is a mathematical problem somewhere.  Its possible that some extra leap years were being taken into account too...

I've produced this, which uses a different calculation for things, and is based on this site http://www.onlineconversion.com/julian_date.htm

#### Kitty Hello

• code monkey
• Prof. Inline
• Posts: 10277
• here on my island the sea says 'hello'
##### Re: Time to Days, hours, minutes and seconds
« Reply #16 on: 2012-May-24 »
Wow, that's very handy. Now I only need a few days off to make some notes on this.

#### fuzzy70

• Prof. Inline
• Posts: 555
• Look left, Look right, LOOK OUT!!
##### Re: Time to Days, hours, minutes and seconds
« Reply #17 on: 2012-May-24 »
I have found out why the code gave incorrect results on pre 1585 dates, just a pure simple typo.

The original code in the Pascal version of the MJD function was

THEN B:=-2+TRUNC((YEAR+4716)/4)-1179

The converted was

b=2+INTEGER((year%+4716)/4)-1179

I have underlined & made bold the difference, Just a simple "-" sign was missing & a very easy mistake to make thanks to := being used in Pascal. Here is the amended version & I have tested it on the dates you had problems with & they return the correct values back

Code: [Select]
`LOCAL day%,month%,year%,hour%DEBUG MJD(24,5,1500,12)+"\n"CALDAT(-130923.5,day%,month%,year%,hour%)DEBUG day%+" "+month%+" "+year%+" "+hour%FUNCTION MJD:day%,month%,year%,hourLOCAL 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.0ENDFUNCTIONFUNCTION 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`
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)

• HelpEditors
• Prof. Inline
• Posts: 5341
• Its me!
##### Re: Time to Days, hours, minutes and seconds
« Reply #18 on: 2012-May-24 »

• HelpEditors
• Prof. Inline
• Posts: 5341
• Its me!
##### Re: Time to Days, hours, minutes and seconds
« Reply #19 on: 2012-May-24 »
I'm incorporating both versions into the program now

Your version does seem to be an out by hour though :

Code: [Select]
`DEBUG MJD(24,5,2012,17)+"\n"CALDAT(56071.70833,day%,month%,year%,hour%)DEBUG day%+" "+month%+" "+year%+" "+hour%END`
Gives :

56071.70833
24 5 2012 16
« Last Edit: 2012-May-24 by MrTAToad »

#### fuzzy70

• Prof. Inline
• Posts: 555
• Look left, Look right, LOOK OUT!!
##### Re: Time to Days, hours, minutes and seconds
« Reply #20 on: 2012-May-24 »
Interesting, seems to happen on any hour >=14 regardless of year etc. Time for some investigation me thinks

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)

• HelpEditors
• Prof. Inline
• Posts: 5341
• Its me!
##### Re: Time to Days, hours, minutes and seconds
« Reply #21 on: 2012-May-24 »
I've got a nasty feeling its a rounding problem.

For example, hour ends up being 16.992, which would mean when converted to an integer would come out at as 16...

This code modification seems to work out okay though :

Code: [Select]
`hour%=(24.0*(jd+0.5-jd0))+0.05`
« Last Edit: 2012-May-24 by MrTAToad »

#### fuzzy70

• Prof. Inline
• Posts: 555
• Look left, Look right, LOOK OUT!!
##### Re: Time to Days, hours, minutes and seconds
« Reply #22 on: 2012-May-24 »
It is indeed a rounding problem. Using the one prior to your 0.05 I done it by hand & the 17 hour / 24 is 0.7083333333 recurring. Adding the extra 3's returned the correct answer.

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)

#### Ian Price

• Global Moderator
• Prof. Inline
• Posts: 3099
• On the shoulders of giants.
##### Re: Time to Days, hours, minutes and seconds
« Reply #23 on: 2012-May-24 »
You lot obviously have too much time on your hands...
I came. I saw. I played.

#### erico

• Prof. Inline
• Posts: 1936
##### Re: Time to Days, hours, minutes and seconds
« Reply #24 on: 2012-May-24 »
Ok, so when do we test the code on the Delorian?

#### Slydog

• Prof. Inline
• Posts: 800
• KodeSource
##### Re: Time to Days, hours, minutes and seconds
« Reply #25 on: 2012-May-24 »
Ok, so when do we test the code on the Delorian?

When we can get our FPS up to 88!
- Do pessimistic cats have 9 deaths?

• HelpEditors
• Prof. Inline
• Posts: 5341
• Its me!
##### Re: Time to Days, hours, minutes and seconds
« Reply #26 on: 2012-May-24 »
I've finished my conversion program.  It generally works well, but does occasionally suffer from occasional rounding errors.  Usually it's only out by a second, but occasionally I have seen it out by a day.

#### erico

• Prof. Inline
• Posts: 1936
##### Re: Time to Days, hours, minutes and seconds
« Reply #27 on: 2012-May-24 »

• HelpEditors
• Prof. Inline
• Posts: 5341
• Its me!
##### Re: Time to Days, hours, minutes and seconds
« Reply #28 on: 2012-May-24 »
Heh

Here is the code for the program :

Code: [Select]
`GLOBAL gDDguiMinControlDimension%=16LOCAL day%,month%,year%,hour%LOCAL sW%=320,sH%=240LOCAL size%,temp\$,vLOCAL dateTime\$[],date\$[],time\$[]size%=(sW%/6)-8DIM dateTime\$[0]IF SPLITSTR(PLATFORMINFO\$("TIME"),dateTime\$[]," ")>=2 // Get the date DIM date\$[0] DIM time\$[0] IF SPLITSTR(dateTime\$[0],date\$[],"-")<>3 OR SPLITSTR(dateTime\$[1],time\$[],":")<>3 DDgui_msg("Date/Time split is invalid",FALSE,"* Error *") RETURN FALSE ENDIFELSE DDgui_msg("Can't get current date and time",FALSE,"* Error *") RETURN FALSEENDIFLOADFONT "Media/smalfont.png",0SETFONT 0DDgui_pushdialog(0,0,sW%,sH%)DDgui_tab("tab","Julian To Value,f1,type1,wday1,day1,wmonth1,month1,wyear1,year1,whour1,hour1,wmin1,min1,wsec1,sec1,convert1,wresult|"+ _ "Value To Julian,f2,value,type2,convert2,wday2,day2,wmonth2,month2,wyear2,year2,whour2,hour2,wmin2,min2,wsec2,sec2")DDgui_framestart("f1","Enter Julian Date",sW%-8)DDgui_checkbox("usnavy1"," Use US Navy Routine",sW%-8,0)DDgui_radio("type1","AD|BC",sW%-8);DDgui_widget("wday1","Day",size%,0); DDgui_numbertext("day1",date\$[2],size%)DDgui_widget("wmonth1"," Mnth",size%,0); DDgui_numbertext("month1",date\$[1],size%)DDgui_widget("wyear1"," Year",size%,0); DDgui_numbertext("year1",date\$[0],size%)DDgui_widget("whour1"," Hour",size%,0); DDgui_numbertext("hour1",time\$[0],size%)DDgui_widget("wmin1"," Min",size%,0); DDgui_numbertext("min1",time\$[1],size%)DDgui_widget("wsec1"," Sec",size%,0); DDgui_numbertext("sec1",time\$[2],size%)DDgui_button("convert1","Convert To Modified Julian Date value",sW%-18,0)DDgui_widget("wresult","Resulting date value :",0,0); DDgui_numbertext("result1","",128); DDgui_set("result1","READONLY",TRUE)DDgui_frameend()DDgui_framestart("f2","Enter Modified Julian Date value",sW%-8)DDgui_numbertext("value","",sW%-18)DDgui_checkbox("usnavy2"," Use US Navy Routine",sW%-8,0)DDgui_button("convert2","Convert To Standard calendar Format",sW%-18,0)DDgui_radio("type2","AD|BC",sW%-8); //DDgui_set("type2","READONLY",TRUE)DDgui_widget("wday2","Day",size%,0); DDgui_numbertext("day2","",size%); DDgui_set("day2","READONLY",TRUE)DDgui_widget("wmonth2"," Mnth",size%,0); DDgui_numbertext("month2","",size%); DDgui_set("month2","READONLY",TRUE)DDgui_widget("wyear2"," Year",size%,0); DDgui_numbertext("year2","",size%); DDgui_set("year2","READONLY",TRUE)DDgui_widget("whour2"," Hour",size%,0); DDgui_numbertext("hour2","",size%); DDgui_set("hour2","READONLY",TRUE)DDgui_widget("wmin2"," Min",size%,0); DDgui_numbertext("min2","",size%); DDgui_set("min2","READONLY",TRUE)DDgui_widget("wsec2"," Sec",size%,0); DDgui_numbertext("sec2","",size%); DDgui_set("sec2","READONLY",TRUE)DDgui_frameend()WHILE TRUE DDgui_show(FALSE) SHOWSCREEN IF DDgui_get("usnavy1","CLICKED") IF INTEGER(DDgui_get("usnavy1","SELECT")) // US Navy needs access to AD/BC and mins and secs DDgui_set("type1","READONLY",FALSE) DDgui_set("min1","READONLY",FALSE) DDgui_set("sec1","READONLY",FALSE) ELSE // Fuzzy 70 doesn't use AC/BC or mins or secs DDgui_set("type1","READONLY",TRUE) DDgui_set("min1","READONLY",TRUE) DDgui_set("sec1","READONLY",TRUE) DEBUG "Here2\n" ENDIF ELSEIF DDgui_get("convert1","CLICKED") LOCAL day%,month%,year%,hour%,mins%,sec%,isBC% year%=INTEGER(DDgui_get("year1","TEXT")) IF year%=0 DDgui_msg("There is no year 0 !",FALSE,"* Error *") ELSE day%=INTEGER(DDgui_get("day1","TEXT")) month%=INTEGER(DDgui_get("month1","TEXT")) hour%=INTEGER(DDgui_get("hour1","TEXT")) mins%=INTEGER(DDgui_get("min1","TEXT")) sec%=INTEGER(DDgui_get("sec1","TEXT")) IF INTEGER(DDgui_get("usnavy1","SELECT")) IF INTEGER(DDgui_get("type1","SELECT"))=0 isBC%=FALSE IF year%=1582 AND month%=10 AND (day%>4 AND day%<15) DDgui_msg("Error 5/10/1582 to 14/10/1582",FALSE,"* Error *") CONTINUE ENDIF ELSE isBC%=TRUE ENDIF DDgui_set("result1","TEXT",cal_to_jd\$(isBC%,year%,month%,day%,hour%,mins%,sec%)) ELSE IF year%=1582 AND month%=10 AND (day%>4 AND day%<15) DDgui_msg("Error 5/10/1582 to 14/10/1582",FALSE,"* Error *") ELSE DDgui_set("result1","TEXT",MJD(day%,month%,year%,hour%)) ENDIF ENDIF ENDIF ELSEIF DDgui_get("convert2","CLICKED") LOCAL value\$,day%,month%,year%,hour%,mins%,sec%,result% value\$=DDgui_get\$("value","TEXT") IF value\$="" DDgui_msg("No date value entered",FALSE,"* Error *") ELSE IF INTEGER(DDgui_get("usnavy2","SELECT")) result%=jd_to_cal(value\$,day%,month%,year%,hour%,mins%,sec%) IF result%=TRUE DDgui_set("type2","SELECT",1) ELSE DDgui_set("type2","SELECT",0) ENDIF DDgui_set("min2","TEXT",RIGHT\$("00"+mins%,2)) DDgui_set("sec2","TEXT",RIGHT\$("00"+sec%,2)) ELSE IF CALDAT(value\$,day%,month%,year%,hour%)=TRUE DDgui_set("type2","SELECT",0) ELSE DDgui_set("type2","SELECT",1) ENDIF DDgui_set("min2","TEXT","N/A") DDgui_set("sec2","TEXT","N/A") ENDIF DDgui_set("day2","TEXT",RIGHT\$("00"+day%,2)) DDgui_set("month2","TEXT",RIGHT\$("00"+month%,2)) DDgui_set("year2","TEXT",year%) DDgui_set("hour2","TEXT",RIGHT\$("00"+hour%,2)) ENDIF ENDIFWENDFUNCTION MJD:day%,month%,year%,hourLOCAL 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.0ENDFUNCTIONFUNCTION CALDAT%:value,BYREF day%,BYREF month%,BYREF year%,BYREF hour%LOCAL b%,d%,f%LOCAL jd,jd0,c,e,r% 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%=INTEGER((24.0*(jd+0.5-jd0))+0.005) IF year%<0 year%=-year% r%=FALSE ELSE r%=TRUE ENDIF RETURN r%ENDFUNCTIONINLINE extern "C" double floor (      double x );ENDINLINEFUNCTION cal_to_jd\$:isBC%, y%, m%, d%, h%, mn%, s%INLINE long jy,ja,jm,gregcal=15 + 31*( 10 + 12*1582); double dayfrac,frac,jd0,jd,intgr; if (isBC) {    y = -y + 1;    } if (m > 2) { jy = y; jm = m + 1; } else { jy = y - 1; jm = m + 13; } intgr=floor((365.25*jy)+(30.6001*jm)+d+1720995); //check for switch to Gregorian calendar if (d + 31*(m + 12*y) >= gregcal) { ja = floor(0.01*jy); intgr+=2 - ja + floor(0.25*ja); } //correct for half-day offset dayfrac = h/24.0 - 0.5; if (dayfrac < 0.0) { dayfrac++; intgr--; } //now set the fraction of a day frac = dayfrac + (mn + s/60.0)/60.0/24.0;    //round to nearest second    jd0 = (intgr + frac)*100000.0;    DEBUG("Here : "); DEBUG(DGInt(jd0)); DEBUG("\n");    jd  = floor(jd0);    if (jd0 - jd > 0.5) jd++;    return FORMAT_Str(16,6,jd/100000.0);ENDINLINEENDFUNCTIONFUNCTION jd_to_cal%:jd,BYREF day%,BYREF month%,BYREF year%,BYREF hour%,BYREF mins%,BYREF secs%INLINE bool isBC; long j1,j2,j3,j4,j5; double frac,dayfrac,f; long gregjd = 2299161; long intgr; intgr=floor(jd); frac=jd-intgr; if (intgr>=gregjd) { double tmp; tmp=floor( ( (intgr - 1867216) - 0.25 ) / 36524.25 ); j1=intgr + 1 + tmp - floor(0.25*tmp); } else { j1=intgr; } dayfrac=frac+0.5; if (dayfrac>=1.0) { dayfrac--; j1++; } j2=j1+1524; j3=floor(6680.0 + ( (j2 - 2439870) - 122.1 )/365.25); j4=floor(j3*365.25); j5=floor( (j2 - j4)/30.6001 ); day=floor(j2 - j4 - floor(j5*30.6001)); month=floor(j5-1); if (month>12) month-=12; year=floor(j3-4715); if (month>2) year--; if (year<=0) year--; // get time of day from day fraction hour=floor(dayfrac * 24.0); mins=floor((dayfrac*24.0 - hour)*60.0); f=((dayfrac*24.0 - hour)*60.0 - mins)*60.0; secs=floor(f); if (f>0.5) secs++; if (year<0) { isBC=true; year=-year; } else { isBC=false; } return isBC;ENDINLINEENDFUNCTION`

#### fuzzy70

• Prof. Inline
• Posts: 555
• Look left, Look right, LOOK OUT!!
##### Re: Re: Time to Days, hours, minutes and seconds
« Reply #29 on: 2012-May-24 »
You lot obviously have too much time on your hands...

I was lucky in that I already wrote the code years ago so all the brain ache of the maths is long behind me lol.

Still have another 100 odd Pascal source files that make up the whole program which the ones I posted are the little baby ones

The whole lot basically works out planetary positions, eclipses, new moons, comet paths etc which I used to control my old telescope.

examples of what can be done with a cheap webcam & sub    £100 telescope.

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)