工作了好几年了,最近入职一家公司,需要操作非常古老的数据库dbf文件,网上其实也有大把的现有的库文件支持操作dbf文件,但是没有发现对浮点数怎么转换,特别是 dbf里面的日期类型的转化,找了半天的资料,也发帖了 但是没有实质性的解决,没办法自己动手和以前的大学同学一起研究了几天时间(当然中间也干其他的事情),终于解决了。。也不知道这篇文章有没有人看 先大致写下~
dbf具体分析以及每个字段代表什么意思这里就不说了 网上也有,但是用现成的库得到数据,如货币型特别是时间型数据的转化这里就特比说下
dbf中浮点数大部分就是货币类型,占用四个字节,其实就是比如13.4元 ,乘以10000转换为16进制放到dbf中 不说了直接上部分代码
int CDBF::bytesToInt( unsigned char* bytes,int size /*= 4*/ )
{
int addr = bytes[0];
addr |= (bytes[1] << 8);
addr |= (bytes[2] << 16);
addr |= (bytes[3] << 24);
return addr;
}
void CDBF::intToByte( int i,unsigned char *bytes,int size /*= 4*/ )
{
//byte[] bytes = new byte[4];
memset(bytes,0,sizeof(unsigned char) * size);
bytes[0] = (unsigned char) (0xff & i);
bytes[1] = (unsigned char) ((0xff00 & i) >> 8);
bytes[2] = (unsigned char) ((0xff0000 & i) >> 16);
bytes[3] = (unsigned char) ((0xff000000 & i) >> 24);
return ;
}
特别注意的是必须是unsigned char * 不能用char *,否则测试发现部分浮点数转换的数值不正确
至于日期型数据,就负载了 前4个字节是年月日 后4个直接是总共的毫秒数 当初可是逆向分析了大半天 不敢独享,先写出来吧 若有人用到 在做具体分析吧
void CDBF::GetTimeToBinary( unsigned char *buf )
{
CTime curTime = CTime::GetCurrentTime() ;//获取当前的时间并保存到curTime
CTime startTime = CTime(2017,8,30,0,0,1) ;
unsigned char startbuf[4] = {0x8c, 0x81, 0x25, 0x00};
int baseDays = bytesToInt(startbuf, 4);
CTimeSpan timeSpan;
timeSpan = curTime - startTime;
int lDiffDays = timeSpan.GetDays();
int NowDays = baseDays + lDiffDays;
//拼接前4个字节 表示年月日
intToByte(NowDays, buf, 4);
//拼接后4个字节
int nDay = curTime.GetDay() ;
int nHour = curTime.GetHour() ;
int nMin = curTime.GetMinute() ;
int nSec = curTime.GetSecond() ;
//总共的毫秒数
int nTotalMillSenconds = (nHour*60 + nMin)*60000 + nSec*1000 - 1;
intToByte(nTotalMillSenconds, buf+4, 4);
}