PROCEDURE DateTimeMilli() LPARAMETERS lAsNumber AS Boolean *LPARAMETERS nString,nMilliSecs,nCentury,nRollover LOCAL nString, nMilliSecs, nCentury, nRollover nString = SYS(2015) * If the Century and Rollover aren't supplied, fill them with the VFP defaults. IF VARTYPE(nCentury) <> 'N' nCentury = SET('CENTURY', 1) ENDIF IF VARTYPE(nRollover) <> 'N' nRollover = SET('CENTURY', 2) ENDIF *The Sys2015 command returns a string of 10 characters. *The first one is always an underscore '_' *The following 9 characters are always from the range 0-9 or A-Z. *The value per char they represent is 0=0, 1=1, ..., 9-9, A=10, B=11, ... , Z=35 *From the first 9 characters, the first 3 characters represent the days, *the rest represent the (milli)seconds. * *The value of the days can be found this way: *When you have the string of 3 characters, you must convert them from base36 to base10, *where the MSB is in the first char. *Unfortenately the century's are not in SYS(2015) so you can only extract the years 00-99. *Now you have a number of the Days, where: *Jan 1st '00 = 1 *Jan 2st '00 = 2 *Jan 1st '01 = 368 *etc * *You see the years have 367 days with no day 0. *This way you can find the year and days since jan 1st. *Because this routine returns a datetime, the century is filled with the century together with rollover. *If the default VPF Century and Rollover settings are not correct for you, you can supply them to this routine *by giving them as the 3rd and 4th parameter. (This is optional) * *Now the time: *When you have the string of 6 characters, you must convert them from base36 to base10, *where the MSB is in the first char. *Now you have the time in millisecs since midnight. *Because the datetime cannot return milliseconds, you can get the millisecs of the datetime by using the following syntax: *nDateTime=CONVERT2015(cSys2015,@nMillisecs) *nDateTime will have the Datetime, nMillisecs will have the milliSecs of this datetime LOCAL nVal1, nVal2, nVal3, nVal4, nVal5, nVal6, nVal7, nVal8, nVal9, nDay * Convert each char from '0-9,A-Z' to 0-35 nVal1 = ASC(SUBSTR(nString, 2)) - IIF(ASC(SUBSTR(nString, 2)) < 65, 48, 55) nVal2 = ASC(SUBSTR(nString, 3)) - IIF(ASC(SUBSTR(nString, 3)) < 65, 48, 55) nVal3 = ASC(SUBSTR(nString, 4)) - IIF(ASC(SUBSTR(nString, 4)) < 65, 48, 55) nVal4 = ASC(SUBSTR(nString, 5)) - IIF(ASC(SUBSTR(nString, 5)) < 65, 48, 55) nVal5 = ASC(SUBSTR(nString, 6)) - IIF(ASC(SUBSTR(nString, 6)) < 65, 48, 55) nVal6 = ASC(SUBSTR(nString, 7)) - IIF(ASC(SUBSTR(nString, 7)) < 65, 48, 55) nVal7 = ASC(SUBSTR(nString, 8)) - IIF(ASC(SUBSTR(nString, 8)) < 65, 48, 55) nVal8 = ASC(SUBSTR(nString, 9)) - IIF(ASC(SUBSTR(nString, 9)) < 65, 48, 55) nVal9 = ASC(SUBSTR(nString, 10)) - IIF(ASC(SUBSTR(nString, 10)) < 65, 48, 55) *Convert the day from BASE36 to BASE10 nDay = nVal1 * 1296 + nVal2 * 36 + nVal3 nDay2 = nDay *In the SYS(2015) world, every year has 367 days nYear = INT(nDay / 367) *Add the right century to this year, because SYS(2015) only has years 0-99 nYear = nCentury * 100 + IIF(nYear < nRollover OR nYear = 0, 100, 0) + nYear *Strip the year off, so you only have the days since Jan 1st nDay = MOD(nDay, 367) *Convert the millisecs from BASE36 to BASE10 nSeconds = (nVal4 * 60466176 + nVal5 * 1679616 + nVal6 * 46656 + nVal7 * 1296 + nVal8 * 36 + nVal9) nSeconds2 = nSeconds *Get the Millisecs from the seconds. nMilliSecs = MOD(nSeconds, 1000) *Strip the millisecs from the seconds nSeconds = INT(nSeconds / 1000) * NDay must be substracted by 1 because nDay=1 is Jan 1st, not day 0 IF lAsNumber RETURN (nDay2 * (24 * 60 * 60)) + (nSeconds2 / 1000.0) ELSE RETURN TRANSFORM(DTOT(DATE(nYear, 1, 1) + nDay - 1) + nSeconds) + '.' + PADL(nMilliSecs, 3, '0') ENDIF ENDPROC