我们来分析一下DateTime的数据需求,DateTime主体要求是保存时间,年月日时分秒。在.net的DateTime结构中提供ToBinary()方法,将DateTime序列化成long型数值。这篇文章描述的也正是一种时间序列化方法。

数据位分析:

年->     4位有效数字,最大数字 9999,       二进制 10011100001111,               位数 14 。

月->     2位有效数字,最大数字 12,           二进制 1100,                                 位数 4 。

日->     2位有效数字,最大数字 31,           二进制 11111,                               位数 5 。

时->     2位有效数字,最大数字 23,           二进制 10111,                               位数 5 。

分->     2位有效数字,最大数字 59,           二进制 111011,                              位数 6 。

秒->     2位有效数字,最大数字 59,           二进制 111011,                              位数 6 。

毫秒->  3位有效数字,最大数字 999,         二进制 1111100111,                       位数 10 。

钠秒->  9位有效数字,最大数字 999999999,二进制 111011100110101100100111111111,位数 30 。

注意:在.net中 DateTime精度是100钠秒。

百钠秒->  7位有效数字,最大数字 9999999,二进制 100110001001011001111111,位数 24 。

十万钠秒->  4位有效数字,最大数字 9999,二进制 10011100001111,位数 14 。

采用毫秒融入后,最终时间数据是:

年 + 月 + 日 + 时 + 分 + 秒 + 毫秒 + 10万钠秒

采用百钠秒融入后,最终时间数据是:

年 + 月 + 日 + 时 + 分 + 秒 + 百钠秒

yyyy-MM-dd HH:mm:ss.fffffff

所需位数是:14 + 4 + 5 + 5 + 6 + 6 + 10 + 14 = 64。

和long类型长度一致,不得不说是一个巧合,是偶然也是必然。在.net中,正是使用long类型来序列化DateTime结构。

using System;
public class 自定义时间
{
private const UInt32 DEFAULT_FOUR_BITS = 0xf;
private const UInt32 DEFAULT_FIVE_BITS = 0x1f;
private const UInt32 DEFAULT_SIX_BITS = 0x3f;
private const UInt32 DEFAULT_TEN_BITS = 0x3ff;
private const UInt32 DEFAULT_FOURTEEN_BITS = 0x3fff;
private const UInt32 DEFAULT_TWENTY_FOUR_BITS = 0xffffff;


private const byte DEFAULT_MOVE_FOUR_BITES = 4;
private const byte DEFAULT_MOVE_FIVE_BITES = 5;
private const byte DEFAULT_MOVE_SIX_BITES = 6;
private const byte DEFAULT_MOVE_TEN_BITES = 10;
private const byte DEFAULT_MOVE_THIRTEEN_BITES = 13;
private const byte DEFAULT_MOVE_TWENTY_FOUR_BITES = 24;

public Int64 时间数据 { get; set; }

public int
{
get
{
return (int)(时间数据 & DEFAULT_FOURTEEN_BITS);
}
set
{
时间数据
|= (UInt32)value;
}
}

public int
{
get
{
return (int)((时间数据 >> DEFAULT_MOVE_THIRTEEN_BITES) & DEFAULT_FOUR_BITS);
}
set
{
时间数据
|= (UInt32)value << DEFAULT_MOVE_THIRTEEN_BITES;
}
}

public int
{
get
{
return (int)((时间数据 >> DEFAULT_MOVE_THIRTEEN_BITES + DEFAULT_MOVE_FOUR_BITES) & DEFAULT_FIVE_BITS);
}
set
{
时间数据
|= (UInt32)value << (DEFAULT_MOVE_THIRTEEN_BITES + DEFAULT_MOVE_FOUR_BITES);
}
}

public int
{
get
{
return (int)((时间数据 >> DEFAULT_MOVE_THIRTEEN_BITES + DEFAULT_MOVE_FOUR_BITES + DEFAULT_MOVE_FIVE_BITES) & DEFAULT_FIVE_BITS);
}
set
{
时间数据
|= (UInt32)value << (DEFAULT_MOVE_THIRTEEN_BITES + DEFAULT_MOVE_FOUR_BITES + DEFAULT_MOVE_FIVE_BITES);
}
}

public int
{
get
{
return (int)((时间数据 >> DEFAULT_MOVE_THIRTEEN_BITES + DEFAULT_MOVE_FOUR_BITES + DEFAULT_MOVE_FIVE_BITES * 2) & DEFAULT_SIX_BITS);
}
set
{
时间数据
|= (UInt32)value << (DEFAULT_MOVE_THIRTEEN_BITES + DEFAULT_MOVE_FOUR_BITES + DEFAULT_MOVE_FIVE_BITES * 2);
}
}

public int
{
get;
set;
}

public int 毫秒
{
get;
set;
}

public int 纳秒
{
get;
set;
}

public 自定义时间()
{
时间数据
= 0;
}

public override string ToString()
{
return string.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}",年,月,日,时,分,秒,毫秒);
}

public string ToLongString()
{
return string.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}", 年, 月, 日, 时, 分, 秒, 纳秒);
}

public static void Test()
{
自定义时间 time
= new 自定义时间();
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
//参数初始化
int year = 2011;
int month = 6;
int day = 30;
int hour = 12;
int minute = 10;
int second = 10;
int millisecond = 333;
int ns = 333333333;

time.年
= year;
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
Console.WriteLine(time.ToString());
time.月
= month;
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
Console.WriteLine(time.ToString());
time.日
= day;
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
Console.WriteLine(time.ToString());
time.时
= hour;
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
Console.WriteLine(time.ToString());
time.分
= minute;
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
Console.WriteLine(time.ToString());
time.秒
= second;
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
Console.WriteLine(time.ToString());
time.毫秒
= millisecond;
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
Console.WriteLine(time.ToString());
time.纳秒
= ns;
Console.WriteLine(
"当前数据二进制输出 {0}", Convert.ToString(time.时间数据, 2));
Console.WriteLine(time.ToLongString());
}
}

在这个示例代码中省略了大长度位操作的代码(秒、毫秒、钠秒),如各位有兴趣,可以自行处理。大长度位操作会在第四篇随笔中进行探讨。

下一篇:

网络通信基础:基础位操作(三)枚举位域处理

posted on 2011-06-30 11:00  醉卧天南  阅读(1682)  评论(1编辑  收藏  举报