Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Date routines for the Micromote Mk2
Author | Message | ||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5905 |
With the introduction of 64 bit integers, using Unix time has become relatively painless. These routines were written with an early beta of 4.6 and there are some areas that can be updated. I was going to wait for 4.6 final before doing the updates but I thought that some of the routines will go well with jman's NTP code. The main program loop simply takes a date and time then converts it to Julian and Unix then back again as a check. The subroutines can be used for doing time/date maths. The odd one is the routines for converting to Julian Date. We need a double float to store the number but that is not available so it is stored as a string. The STR$ function has been updated since this code was written and I should be able to get rid of the mystr$ function now. ' date conversion routines
' TassyJim Nov2014 currentdate$= DATE$ currenttime$=TIME$ DO PRINT currentdate$;" ";currenttime$ IF MM.DEVICE$<>"Micromite MkII" THEN PRINT "This program will not run on the ";MM.DEVICE$ ENDIF JD% = Julian(currentdate$) weekday= (jd%+1) MOD 7 'weekday starts at 0 for Sunday dayz$=MID$("SunMonTueWedThuFriSatSun",weekday*3+1,3) Utime%=unixtime%(currentdate$+" "+currenttime$ ) DoY= DayofYear(currentdate$) Jdate$=JulianDate$(currentdate$+" "+currenttime$ ) PRINT "Day of Week: ";weekday;" ";dayz$ PRINT "Day of year: ";DoY PRINT "Julian Day : ";JD% PRINT "Julian Date: ";Jdate$ PRINT "Unix time : ";Utime% PRINT "Reverse J Day : "; JDString$(JD%) PRINT "Reverse J Date : "; JDateString$(Jdate$) PRINT "Reverse U time : "; unixDateString$(Utime%) INPUT "New Date (DD/MM/YYYY) or X to quit: ",newdate$ IF UCASE$(newdate$)="X" THEN EXIT DO IF newdate$<>"" THEN currentdate$=newdate$ INPUT "New Time (HH:MM:SS) : ",newtime$ IF newtime$<>"" THEN currenttime$=newtime$ ELSE currenttime$=TIME$ ENDIF LOOP END FUNCTION Julian(datestring$) ' datestring in the format "dd/mm/yyyy" or "dd-mm-yyyy" ' returns the Julian day number corresponding to midday on the given date ' using the Gregorian calendar LOCAL d, m, y, ff, yo, mo d=VAL(MID$(datestring$,1,2)) m=VAL(MID$(datestring$,4,2)) y=VAL(MID$(datestring$,7,4)) ff=(14-m)\12 yo=y+4800-ff mo=m+12*ff-3 Julian = d +(153*mo+2)\5 + 365*yo + yo\4 - yo\100 + yo\400 - 32045 'Julian = d +(153*mo+2)\5 + 365*yo + yo\4 - 32083 ' Julian calendar END FUNCTION FUNCTION JulianDate$(datestring$) ' datestring in the format "dd/mm/yyyy hh:mm:ss" or "dd-mm-yyyy hh:mm:ss" ' returns the Julian Date as a string ' requires Julian() LOCAL h, m, s, JD%, JDtime JD%=Julian(LEFT$(datestring$,10)) h=VAL(MID$(datestring$,12,2)) m=VAL(MID$(datestring$,15,2)) s=VAL(MID$(datestring$,18,2)) JDtime=(h*3600+m*60+s)/86400 IF JDtime >= 0.5 THEN ' adjust times before midday to the previous day JDtime = JDtime - 0.5 ELSE JDtime = JDtime + 0.5 JD% = JD% -1 ENDIF IF JDtime=0 THEN JulianDate$=STR$(JD%)+".0" ELSE JulianDate$=STR$(JD%)+MID$(mystr$(JDtime),2) ENDIF END FUNCTION FUNCTION DayofYear(datestring$) ' given the date dd/mm/yyyy, returns the day number of the year ' requires Julian() LOCAL day1, y day1=Julian(datestring$) y=VAL(MID$(datestring$,7,4))-1 DayofYear= day1-Julian("31/12/"+STR$(y,4)) END FUNCTION FUNCTION unixtime%(datestring$) ' datestring in the format "dd/mm/yyyy hh:mm:ss" or "dd-mm-yyyy hh:mm:ss" ' returns the unixtime ' requires Julian() LOCAL h%, m%, s%, JD% JD%=Julian(LEFT$(datestring$,10)) unixtime%=(JD%-2440588)*86400 h%=VAL(MID$(datestring$,12,2)) m%=VAL(MID$(datestring$,15,2)) s%=VAL(MID$(datestring$,18,2)) unixtime%=unixtime%+h%*3600+m%*60+s% END FUNCTION FUNCTION unixDateString$(unixt%) LOCAL unixd%, unixf%, h, m, s, ut$ unixd%=unixt%\86400 unixf%=unixt% MOD 86400 IF unixd%<0 AND unixf%<>0 THEN unixf%=86400+unixf% ENDIF h= unixf%\3600 m= (unixf% MOD 3600)\60 s=(unixf% MOD 3600) MOD 60 ut$=STR$(h,2,0,"0")+":"+STR$(m,2,0,"0")+":"+STR$(s,2,0,"0") unixDateString$=JDString$(JD%)+" "+ut$ END FUNCTION FUNCTION JDString$(JD%) ' Given the Julian day number, returns the date as a string ' valid for Gregorian dates after Oct 15, 1582 LOCAL l, n, i, j, d, m, y l = jd%+68569 n = FIX((4*l)/146097) l = l-FIX((146097*n+3)/4) i = FIX((4000*(l+1))/1461001) l = l-FIX((1461*i)/4)+31 j = FIX((80*l)/2447) d = l-FIX((2447*j)/80) l = FIX(j/11) m = j+2-(12*l) y = 100*(n-49)+i+l JDString$=STR$(d,2,0,"0")+"/"+STR$(m,2,0,"0")+"/"+STR$(y,4) END FUNCTION FUNCTION JDateString$(JDate$) ' Given the Julian date as a string, returns the date and time as a string LOCAL dp, JD% dp=INSTR(JDate$,".") IF dp >0 THEN JD%=VAL(LEFT$(JDate$,dp-1)) JDsecs=VAL(MID$(JDate$,dp))*86400 ELSE JD%=VAL(JDate$) JDsecs=0 ENDIF IF JDsecs >= 43200 THEN ' adjust times before midday to the previous day JDsecs= JDsecs - 43200 JD% = JD% +1 ELSE JDsecs= JDsecs + 43200 ENDIF h= JDsecs\3600 m= (JDsecs MOD 3600)\60 s=(JDsecs MOD 3600) MOD 60 JDateString$=JDString$(JD%)+" "+STR$(h,2,0,"0")+":"+STR$(m,2,0,"0")+":"+STR$(s,2,0,"0") END FUNCTION FUNCTION mystr$(k) ' needed to print small numbers with 7 digits after decimal point SELECT CASE k CASE IS > 0.0001, IS < -0.0001 ' big enough for the normal STR$ function mystr$=STR$((k),0,7) CASE IS > 0.0000001 mystr$=STR$((k*1000),0,4) mystr$="0.000"+MID$(mystr$,3) CASE IS < -0.0000001 mystr$=STR$((ABS(k)*1000),0,4) mystr$="-0.000"+MID$(mystr$,3) CASE ELSE ' really small numbers display as zero mystr$="0.0000000" END SELECT END FUNCTION Jim VK7JH MMedit MMBasic Help |
||||
twofingers Guru Joined: 02/06/2014 Location: GermanyPosts: 1133 |
Hi Jim, I like this useful stuff! Thanks a lot! Regards Michael |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1328 |
Yes, another one for the "I'm gonna need that sometime" box Jim, thanks for that. Greg |
||||
Print this page |