Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 18:26 29 Apr 2024 Privacy Policy
Jump to

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: Australia
Posts: 5905
Posted: 03:49pm 29 Nov 2014
Copy link to clipboard 
Print this post

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
PRINT "Reverse J Day : "; JDString$(JD%)
PRINT "Reverse J Date : "; JDateString$(Jdate$)
PRINT "Reverse U time : "; unixDateString$(Utime%)
PRINT

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: Germany
Posts: 1133
Posted: 04:59am 30 Nov 2014
Copy link to clipboard 
Print this post

Hi Jim,

I like this useful stuff! Thanks a lot!

Regards
Michael
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1328
Posted: 01:44pm 30 Nov 2014
Copy link to clipboard 
Print this post

Yes, another one for the "I'm gonna need that sometime" box Jim, thanks for that.

Greg
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024