Need to know the time - accurately for your next project?

The code below allows your PIC to log into a network timeserver and it (eventually) writes the time to a Dallas RTC (code not supplied).
The PIC checks the NET TIME every power-up and thereafter every 4 hours. If it doesn't make connection, it tries an alternate time server. If THAT doesn't work (after retries) it gives up and tries again 4 hours later. A Lantronix XPort handles the connection to the net.

The PIC normally reads the time from the Dallas RTC. The clock is self-setting and self-correcting, as long as you have a network connection.

And all of you using 16F chips, time to upgrade! This sub requires LONGS.

;-----------------------------------------------------------------------------------------------------------------------------------------------
Net Time' is the number of seconds since Jan 1 1900

This sub accomodates for leap years, GMT offsets and Daylight Savings Time.

The sub assumes you are in the present century, so it takes a shortcut by pre-subtracting the number of seconds from Jan 1 1900 to
Jan 1 2009.

It should be self-explanatory.
;----------------------------------------------------------------------------------------------------------------------

Hoffset is the hours offset from GMT
Sign = "1" or "2" depending on whether you are earlier or later than GMT
DST = 1 if you are in Daylight Savings Time (Another part of the PGM changes that value when appropriate).




GETNETTIME:
NETRETRYCOUNT = 0

GETNETTIME2:

HSEROUT [13,10,"TIMESERVER ",#TSIP1,".",#TSIP2,".",#TSIP3,".",#TSIP4,13,1 0]
PAUSE 100

THEADER[0] = $2 ' STX
THEADER[1] = TSIP1 ' DESTINATION IP
THEADER[2] = TSIP2
THEADER[3] = TSIP3
THEADER[4] = TSIP4

THEADER[5] = 0 ; DESTINATION PORT HIGHBYTE
THEADER[6] = 123 ; DESTINATION PORT LOWBYTE

LRC1 = 0
LRC2 = 0

For X = 1 to 6
LRC1 = LRC1 ^ THeader[x]
next X

THEADER[7] = LRC1
THEADER[8] = 0
THEADER[9] = 48 'Data Length lowbyte

;Send the header
HSEROUT [13,10]
For X = 0 to 9
HSEROUT2 [THeader[X]]
Next X

LRC2 = LRC2 ^ THeader[8]
LRC2 = LRC2 ^ THeader[9]

;Send the data
HSEROUT2 [$1B]
LRC2 = LRC2 ^ $1B
For X = 0 To 46
HSEROUT2 [0]
LRC2 = LRC2 ^ 0
NEXT X

;Send the Checksum (LRC)

HSEROUT2 [LRC2]
getresponse:
HSERIN2 1000,NoResponse,[Wait($2)]
hserin2 200,NoResponse,[SKIP 41,TimeNow.Byte3,TimeNow.Byte2,TimeNow.Byte1,TimeN ow.Byte0]

READ 851,HOFFSET

IF sign = "1" then
if DST = 1 and HOffset = 0 THEN
Sign = "2"
GOTO OtherSide
ENDIF

TimeNow = Timenow - ((HOffset - DST) * 3600)
ENDIF

OtherSide:
IF Sign = "2" THEN

TimeNow = TimeNow + ((Hoffset + DST) * 3600)
ENDIF

SINCEJAN2009 = TIMENOW - 3439756800 ; 3439756800 is the #of sec from Jan1 1900 to Jan1 2009

RUNNINGSECONDS = SINCEjAN2009
YR = 2009

GETYEAR:

LEAP = (YR//4) ; = 0 if leap year

if LEAP = 0 then
SecondsInYear = 31622400 ;366*60*60**24

ELSE
SecondsInYear = 31536000 ;365*60*60*24

endif

If RunningSeconds > SecondsInYear Then
RunningSeconds = RunningSeconds - SecondsInyear
YR = YR + 1
GOTO GetYear
ENDIF

Mo = 1 ; Start with Month = 1


GETMONTH:
IF LEAP > 0 THEN
lookup2 MO,[0,2678400,2419200,2678400,2592000,2678400,2592000, 2678400,2678400,2592000,2678400,2592000,2678400],SecondsInMonth
ELSE
LOOKUP2 MO,[0,2678400,2505600,2678400,2592000,2678400,2592000, 2678400,2678400,2592000,2678400,2592000,2678400],SecondsInMonth
ENDIF

If RunningSeconds >= SecondsInMonth THEN
RunningSeconds = RunningSeconds - SecondsInMonth

MO = MO + 1
GOTO GETMONTH
ENDIF
FINDDAYS:

DA = RUNNINGSECONDS/86400
RUNNINGSECONDS = RUNNINGSECONDS//86400

HR = RUNNINGSECONDS/3600
RUNNINGSECONDS = RUNNINGSECONDS//3600

MN = RUNNINGSECONDS/60
RUNNINGSECONDS = RUNNINGSECONDS//60
SC = RUNNINGSECONDS

Da = Da + 1
HSEROUT [13,10,13,10,DEC2 HR,":",DEC2 MN,":",DEC2 SC," ",DEC2 MO,"/",DEC2 DA,"/",#YR,13,10]

Return