> 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 >An interesting way to skin the cat - thanks.