1. 先说一下应用场景:有时间,需要在不同平台不同语言编写的系统之间通信,如果牵扯到时间,就需要转换一致。这儿的应用场景是,在VC++下面使用SYSTEMTIME取得的时间,需要发送到C#编写的系统解析,相反,C#使用DateTime取得的时间,也需要发送到VC++编写的程序解析。
2. 实现步聚,难点主要在于VC++这一端:
2.1 需要先将SYSTEMTIME时间转换成64位整数,返过来也需要转64位整数转抽象为SYSTEMTIME结构时间,2个方法如下:
__int64 SystemTimeToInt64(const SYSTEMTIME& itime)
{
FILETIME ft;
SystemTimeToFileTime(&itime, &ft);
ULARGE_INTEGER ularge;
ularge.LowPart = ft.dwLowDateTime;
ularge.HighPart = ft.dwHighDateTime;
__int64 int64 = ularge.QuadPart;
return int64;
}
SYSTEMTIME Int64ToSystemTime(const __int64& itime)
{
FILETIME ft;
SYSTEMTIME st;
ULARGE_INTEGER ularge;
__int64 tmptimeA, tmptimeB;
tmptimeA = itime;
tmptimeB = itime;
ularge.HighPart = (DWORD)(tmptimeA>>32);
ularge.LowPart = (DWORD)((tmptimeB<<32)>>32);
ft.dwLowDateTime = ularge.LowPart;
ft.dwHighDateTime = ularge.HighPart;
FileTimeToSystemTime(&ft, &st);
return st;
}
2.2 由于SYSTEMTIME时间结构和DataTime类取得的时间在年份上相差1600,因此,DataTime时间取Ticks值,SYSTEMTIME将这个整数转换后的时间需要减去1600才是正确的时间,同样SYSTEMTIME时间转换成整数前,需先将年份加上1600,再转换成整数,即对应DataTime的Ticks值。
示例:
VC++端发送:
SYSTEMTIME systime;
GetSystemTime(&systime);
systime.wYear += 1600;
/*Write datatime to buffer.*/
int WriteDateTime(const SYSTEMTIME& time)
{
__int64 net_ulong = 0;
net_ulong = htonll((__int64)SystemTimeToInt64(time));
memcpy_s(m_pDataBuffer+m_nCurIndex,8,(void*)&net_ulong,8);
m_nCurIndex += 8;
return 0;
}
C#接收端:
public DateTime ReadDateTime()
{
byte[] tmpBuffer = new byte[8];
Array.Copy(DataBuffer, CurIndex, tmpBuffer, 0, 8);
long NetLong = BitConverter.ToInt64(tmpBuffer, 0);
long HostLong = IPAddress.NetworkToHostOrder(NetLong);
DateTime OutTime = new DateTime(HostLong);
return OutTime;
}
反过来,C#发送端:
public void WriteDateTime(DateTime src)
{
long Ticks = src.Ticks;
long NetLong = IPAddress.HostToNetworkOrder(Ticks);
byte[] tmpBuffer = BitConverter.GetBytes(NetLong);
Array.Copy(tmpBuffer, 0, DataBuffer, CurIndex, tmpBuffer.Length);
CurIndex += 8;
}
VC++作为接收端:
/*Read a DateTime from buffer */
SYSTEMTIME CUnPacket::ReadDateTime()
{
__int64 data = 0;
memcpy_s((void*)&data,8,m_pDataBuffer+m_nCurIndex,8);
data = ntoh64(data);
m_nCurIndex += 8;
SYSTEMTIME systime;
systime = Int64ToSystemTime(data);
systime.wYear -= 1600;
return systime;
}