***
*** 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
* 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
* 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
lcMsg = transform(lnMonth,"@L 99")+"/" ;
+transform(lnDay,"@L 99")+"/" ;
+transform(lnYear,"@L 9999")+" " ;
+transform(lnHour,"@L 99")+":" ;
+transform(lnMinute,"@L 99")+":" ;
+transform(lnSecond,"@L 99")+" " ;
+lcAMPM
ENDIF
RETURN lcMsg