Extract binary data from a file 
Author Message
 Extract binary data from a file

I am parsing a non-standard database into a VFP table. Within the file,
nested between strings, is the dos timedate stamp of each of the records,
as a double word. I need to convert it to a datetime field. HOW?????? Every
thing I have tried fails, Foxpro does not even give the correct value for
the double word, let alone turn it into a datetime data type.



Sat, 22 Jul 2000 03:00:00 GMT  
 Extract binary data from a file

The following documents and shows how to create / breakout a DOS type
Timestamp. While you might have to alter it a bit to get what you need, it
should give you a good start.

Rick

*** ------------------------------------------------------------------ ***
***
***  These routines create and display standard DOS timestamps
***
*** ------------------------------------------------------------------ ***
*!
*! Standard DOS TimeStamp is stored in the following format:
*!  32 bit integer (viewed logically NOT as would be in INTEL memory)
*!
*!  7 bits (31-25) - Year offset from 1980  Valid 0-127
*!  4 bits (24-21) - Month       Valid 1-12 (not 0, 13-15)
*!  5 bits (20-16) - Day        Valid 1-31 (not 0)
*!  5 bits (15-11) - Hour       Valid 0-23 (not 24-31)
*!  6 bits (10-05) - Minute       Valid 0-59 (not 60-63)
*!  5 bits (04-00) - Seconds (two at a time) Valid 0-29 (not 30-31)
*!
*! Notes: Earliest valid date 1/1/1980 and only good thru 12/31/2107
*!    Can't have "odd" seconds
*!
*** ------------------------------------------------------------------ ***
***
FUNCTION cr_tmstmp && Create standard DOS timestamp from date & time
PARAMETER zdDate, zcTime
* Notes:  zdDate is a date between {1/1/1980} and {12/31/2107}
*         zcTime is a character string in 24 hour "HH:MM:SS" format
* Returns: Integer Timestamp
*
* Example: ? cr_tmstmp(date(), time())
*
PRIVATE lnTmStmp
lnTmStmp = 0
IF BETWEEN(zdDate, {1/1/1980}, {12/31/2107});
  AND LEN(zcTime) = 8)
 lnTmStmp = lnTmStmp + YEAR(zdDate) - 1980       && lnYear
 lnTmStmp = lnTmStmp*16 + MONTH(zdDate)        && lnMonth
 lnTmStmp = lnTmStmp*32 + DAY(zdDate)        && lnDay
 lnTmStmp = lnTmStmp*32 + VAL(substr(zcTime, 1,2))    && lnHour
 lnTmStmp = lnTmStmp*64 + VAL(substr(zcTime, 4,2))    && lnMinute
 lnTmStmp = lnTmStmp*32 + INT(VAL(substr(zcTime, 7,2)) / 2) && lnSecond
ENDIF
RETURN int(lnTmStmp)

*** ------------------------------------------------------------------ ***

FUNCTION bo_dttm && break out date and time from timestamp
PARAMETER zx_DtTm
* Notes:  zx_DtTm is either a number or a character string representing
number
* Returns: Character String w/ "MM/DD/YYYY HH:MM:SS xM" or Error message
*          [Change lcMsg at end of procedure to generate alternate output]
*
* Example: ? bo_dttm(510165755)
*          ? bo_dttm("510165755")
*
PRIVATE lnDtTm, lnYear, lnMonth, lnDay, lnHour, lnMinute, lnSecond, lcAMPM
PRIVATE llOK, lcMsg
llOK = .T.
lcMsg = ""
IF TYPE('zx_DtTm') = "N"
 lnDtTm = INT(zx_DtTm)
ELSE
 IF TYPE('zx_DtTm') = "C"
  lnDtTm = INT(VAL(zx_DtTm))
 ELSE
  llOK = .F.
 ENDIF
ENDIF
DO WHILE llOK && not really a LOOP - just a way to handle errors more easily
 lnSecond = MOD(lnDtTm, 32) * 2
 IF !BETWEEN(lnSecond, 0, 60)
  lcMsg = "Seconds out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lnDtTm = INT(lnDtTm/32)
 lnMinute = MOD(lnDtTm, 64)
 IF !BETWEEN(lnMinute, 0, 60)
  lcMsg = "Minutes out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lnDtTm = INT(lnDtTm/64)
 lnHour = MOD(lnDtTm, 32)
 IF !BETWEEN(lnHour, 0, 24)
  lcMsg = "Hours out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lcAMPM = "am"
 DO CASE
 CASE BETWEEN(lnHour,0,11)
  * good enuff
 CASE lnHour=12
  lcAMPM = "pm"
 CASE BETWEEN(lnHour,13,24)
  lcAMPM = "pm"
  lnHour = lnHour - 12
 ENDCASE
 lnDtTm = INT(lnDtTm/32)
 lnDay = MOD(lnDtTm, 32)
 IF !BETWEEN(lnDay, 1, 31)
  lcMsg = "Day out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lnDtTm = INT(lnDtTm/32)
 lnMonth = MOD(lnDtTm, 16)
 IF !BETWEEN(lnMonth, 1, 12)
  lcMsg = "Month out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lnDtTm = INT(lnDtTm/16)
 lnYear = lnDtTm+1980
 EXIT
ENDDO
IF llOK






    +lcAMPM
ENDIF
RETURN lcMsg

*** ------------------------------------------------------------------ ***

Quote:

>I am parsing a non-standard database into a VFP table. Within the file,
>nested between strings, is the dos timedate stamp of each of the records,
>as a double word. I need to convert it to a datetime field. HOW?????? Every
>thing I have tried fails, Foxpro does not even give the correct value for
>the double word, let alone turn it into a datetime data type.



Sat, 22 Jul 2000 03:00:00 GMT  
 Extract binary data from a file

The following documents and shows how to create / breakout a DOS type
Timestamp. While you might have to alter it a bit to get what you need, it
should give you a good start.

Rick

*** ------------------------------------------------------------------ ***
***
***  These routines create and display standard DOS timestamps
***
*** ------------------------------------------------------------------ ***
*!
*! Standard DOS TimeStamp is stored in the following format:
*!  32 bit integer (viewed logically NOT as would be in INTEL memory)
*!
*!  7 bits (31-25) - Year offset from 1980  Valid 0-127
*!  4 bits (24-21) - Month       Valid 1-12 (not 0, 13-15)
*!  5 bits (20-16) - Day        Valid 1-31 (not 0)
*!  5 bits (15-11) - Hour       Valid 0-23 (not 24-31)
*!  6 bits (10-05) - Minute       Valid 0-59 (not 60-63)
*!  5 bits (04-00) - Seconds (two at a time) Valid 0-29 (not 30-31)
*!
*! Notes: Earliest valid date 1/1/1980 and only good thru 12/31/2107
*!    Can't have "odd" seconds
*!
*** ------------------------------------------------------------------ ***
***
FUNCTION cr_tmstmp && Create standard DOS timestamp from date & time
PARAMETER zdDate, zcTime
* Notes:  zdDate is a date between {1/1/1980} and {12/31/2107}
*         zcTime is a character string in 24 hour "HH:MM:SS" format
* Returns: Integer Timestamp
*
* Example: ? cr_tmstmp(date(), time())
*
PRIVATE lnTmStmp
lnTmStmp = 0
IF BETWEEN(zdDate, {1/1/1980}, {12/31/2107});
  AND LEN(zcTime) = 8)
 lnTmStmp = lnTmStmp + YEAR(zdDate) - 1980       && lnYear
 lnTmStmp = lnTmStmp*16 + MONTH(zdDate)        && lnMonth
 lnTmStmp = lnTmStmp*32 + DAY(zdDate)        && lnDay
 lnTmStmp = lnTmStmp*32 + VAL(substr(zcTime, 1,2))    && lnHour
 lnTmStmp = lnTmStmp*64 + VAL(substr(zcTime, 4,2))    && lnMinute
 lnTmStmp = lnTmStmp*32 + INT(VAL(substr(zcTime, 7,2)) / 2) && lnSecond
ENDIF
RETURN int(lnTmStmp)

*** ------------------------------------------------------------------ ***

FUNCTION bo_dttm && break out date and time from timestamp
PARAMETER zx_DtTm
* Notes:  zx_DtTm is either a number or a character string representing
number
* Returns: Character String w/ "MM/DD/YYYY HH:MM:SS xM" or Error message
*          [Change lcMsg at end of procedure to generate alternate output]
*
* Example: ? bo_dttm(510165755)
*          ? bo_dttm("510165755")
*
PRIVATE lnDtTm, lnYear, lnMonth, lnDay, lnHour, lnMinute, lnSecond, lcAMPM
PRIVATE llOK, lcMsg
llOK = .T.
lcMsg = ""
IF TYPE('zx_DtTm') = "N"
 lnDtTm = INT(zx_DtTm)
ELSE
 IF TYPE('zx_DtTm') = "C"
  lnDtTm = INT(VAL(zx_DtTm))
 ELSE
  llOK = .F.
 ENDIF
ENDIF
DO WHILE llOK && not really a LOOP - just a way to handle errors more easily
 lnSecond = MOD(lnDtTm, 32) * 2
 IF !BETWEEN(lnSecond, 0, 60)
  lcMsg = "Seconds out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lnDtTm = INT(lnDtTm/32)
 lnMinute = MOD(lnDtTm, 64)
 IF !BETWEEN(lnMinute, 0, 60)
  lcMsg = "Minutes out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lnDtTm = INT(lnDtTm/64)
 lnHour = MOD(lnDtTm, 32)
 IF !BETWEEN(lnHour, 0, 24)
  lcMsg = "Hours out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lcAMPM = "am"
 DO CASE
 CASE BETWEEN(lnHour,0,11)
  * good enuff
 CASE lnHour=12
  lcAMPM = "pm"
 CASE BETWEEN(lnHour,13,24)
  lcAMPM = "pm"
  lnHour = lnHour - 12
 ENDCASE
 lnDtTm = INT(lnDtTm/32)
 lnDay = MOD(lnDtTm, 32)
 IF !BETWEEN(lnDay, 1, 31)
  lcMsg = "Day out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lnDtTm = INT(lnDtTm/32)
 lnMonth = MOD(lnDtTm, 16)
 IF !BETWEEN(lnMonth, 1, 12)
  lcMsg = "Month out of range"
  llOK = .F.
  EXIT  && a way out
 ENDIF
 lnDtTm = INT(lnDtTm/16)
 lnYear = lnDtTm+1980
 EXIT
ENDDO
IF llOK






    +lcAMPM
ENDIF
RETURN lcMsg

*** ------------------------------------------------------------------ ***

Quote:

>I am parsing a non-standard database into a VFP table. Within the file,
>nested between strings, is the dos timedate stamp of each of the records,
>as a double word. I need to convert it to a datetime field. HOW?????? Every
>thing I have tried fails, Foxpro does not even give the correct value for
>the double word, let alone turn it into a datetime data type.



Sat, 22 Jul 2000 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. ODBC - extracting data from Access .MDB file

2. Extract data from delimited text file

3. Reading binary data files

4. Reading binary data from a file

5. General data type change to Memo(Binary) data type

6. extracting data from foxpro2.0

7. Extracting data to excel

8. extracting data from a foxapp?

9. Messaging and Workflow apps with VFP (aka Extracting data from Exchange)

10. Extract data from MS Excel spreadsheet to Foxpro 2.6 dbf format

11. How to extract the difference data records from two similar tables

12. Extracting data from remote Sql View

 

 
Powered by phpBB® Forum Software