解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)
解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)
http://improve.dk/parsing-dates-in-orcamdf/
在SQLSERVER里面有几种不同的date相关类型,当前OrcaMDF 支持三种最常用的date类型:date,datetime,smalldatetime
SqlDate实现
date 类型在三种类型之中是最简单的,他是一个3个字节的定长类型,存储了日期值它支持的日期范围从0001-01-01到9999-12-31
默认值是1900-01-01
比较坑爹的是.NET里面还没有任何标准实现能够支持3个字节的整数类型,只有short类型和int类型,但是,他们要不太大要不太小
另外,要正确读取日期值,对于.NET的4字节整型我们必须执行一些转变去获取正确的数字
一旦我们获取到date的值,我们可以创建一个默认的datetime类型并且添加天数进去
public class SqlDate : ISqlType
{
public bool IsVariableLength
{
get { return false; }
} public short? FixedLength
{
get { return ; }
} public object GetValue(byte[] value)
{
if (value.Length != )
throw new ArgumentException("Invalid value length: " + value.Length); // Magic needed to read a 3 byte integer into .NET's 4 byte representation.
// Reading backwards due to assumed little endianness.
int date = (value[] << ) + (value[] << ) + value[]; return new DateTime(, , ).AddDays(date);
}
}
相关测试
using System;
using NUnit.Framework;
using OrcaMDF.Core.Engine.SqlTypes;
namespace OrcaMDF.Core.Tests.Engine.SqlTypes
{
[TestFixture]
public class SqlDateTests
{
[Test]
public void GetValue()
{
var type = new SqlDate();
var input = new byte[] { 0xf6, 0x4c, 0x0b };
Assert.AreEqual(new DateTime(, , ), Convert.ToDateTime(type.GetValue(input)));
input = new byte[] { 0x71, 0x5c, 0x0b };
Assert.AreEqual(new DateTime(, , ), Convert.ToDateTime(type.GetValue(input)));
}
[Test]
public void Length()
{
var type = new SqlDate();
Assert.Throws<ArgumentException>(() => type.GetValue(new byte[]));
Assert.Throws<ArgumentException>(() => type.GetValue(new byte[]));
}
}
}
SqlDateTime实现
date类型只能存储日期,而datetime类型不但能存储date也能存储time
datetime存储8字节定长数据值,第一部分是time(4字节),而第二部分是date(4字节)
计算date部分跟上面介绍date类型基本上一样,不过这一次date部分是一个四字节整数,比上面的例子容易处理多了,上面的date类型是3个字节
time部分存储为自午夜时的ticks数,一个tick就是1/300th 秒,为了显示tick值,我们首先定义一个常量,常量值是10d/3d
time的各个部分实际同样存储在同一个整型值里面(比如时间,分钟,秒,毫秒),所以我们要独立访问这些单独的部分,我们必须
要执行一些转换 (包括取模和相除)
部分 计算
小时 X / / /
分钟 X / / %
秒 X / %
毫秒 X % * 10d / 3d
public class SqlDateTime : ISqlType
{
private const double CLOCK_TICK_MS = 10d/3d; public bool IsVariableLength
{
get { return false; }
} public short? FixedLength
{
get { return ; }
} public object GetValue(byte[] value)
{
if (value.Length != )
throw new ArgumentException("Invalid value length: " + value.Length); int time = BitConverter.ToInt32(value, );
int date = BitConverter.ToInt32(value, ); return new DateTime(, , , time///, time//%, time/%, (int)Math.Round(time%*CLOCK_TICK_MS)).AddDays(date);
}
}
相关测试
using System;
using NUnit.Framework;
using OrcaMDF.Core.Engine.SqlTypes;
namespace OrcaMDF.Core.Tests.Engine.SqlTypes
{
[TestFixture]
public class SqlDateTimeTests
{
[Test]
public void GetValue()
{
var type = new SqlDateTime();
byte[] input;
input = new byte[] { 0x5e, 0x3b, 0x5d, 0x00, 0x25, 0x91, 0x00, 0x00 };
Assert.AreEqual(new DateTime(, , , , , , ), (DateTime)type.GetValue(input));
input = new byte[] { 0xb6, 0x87, 0xf0, 0x00, 0xd1, 0x8b, 0x00, 0x00 };
Assert.AreEqual(new DateTime(, , , , , , ), (DateTime)type.GetValue(input));
input = new byte[] { 0x2d, 0xfd, 0x1c, 0x01, 0x4a, 0x75, 0x00, 0x00 };
Assert.AreEqual(new DateTime(, , , , , , ), (DateTime)type.GetValue(input));
input = new byte[] { 0xff, 0x81, 0x8b, 0x01, 0x7f, 0x24, 0x2d, 0x00 };
Assert.AreEqual(new DateTime(, , , , , , ), (DateTime)type.GetValue(input));
}
[Test]
public void Length()
{
var type = new SqlDateTime();
Assert.Throws<ArgumentException>(() => type.GetValue(new byte[]));
Assert.Throws<ArgumentException>(() => type.GetValue(new byte[]));
}
}
}
SqlSmallDateTime实现
Smalldatetime 是一个不错的数据类型当你需要存储范围值内的日期值(1900~2079)并且他能精确到秒
大多数场景下,精确到秒已经足够了,在一个范围的时间间隔内和精确值不需要太精确的情况下会节省很多空间
smalldatetime 数据类型会只占用4个字节,前2个字节存储自午夜的分钟数,后2个字节存储日期,默认值是1900-1-1
处理的方法跟datetime差不多,只不过使用更小的范围
部分 计算
小时 X /
分钟 X %
public class SqlSmallDateTime : ISqlType
{
public bool IsVariableLength
{
get { return false; }
} public short? FixedLength
{
get { return ; }
} public object GetValue(byte[] value)
{
if (value.Length != )
throw new ArgumentException("Invalid value length: " + value.Length); ushort time = BitConverter.ToUInt16(value, );
ushort date = BitConverter.ToUInt16(value, ); return new DateTime(, , , time / , time % , ).AddDays(date);
}
}
相关测试
using System;
using NUnit.Framework;
using OrcaMDF.Core.Engine.SqlTypes;
namespace OrcaMDF.Core.Tests.Engine.SqlTypes
{
[TestFixture]
public class SqlSmallDateTimeTests
{
[Test]
public void GetValue()
{
var type = new SqlSmallDateTime();
var input = new byte[] { 0xab, 0x02, 0x5d, 0x26 };
Assert.AreEqual(new DateTime(, , , , , ), Convert.ToDateTime(type.GetValue(input)));
input = new byte[] { 0x49, 0x03, 0x99, 0x09 };
Assert.AreEqual(new DateTime(, , , , , ), Convert.ToDateTime(type.GetValue(input)));
}
[Test]
public void Length()
{
var type = new SqlSmallDateTime();
Assert.Throws<ArgumentException>(() => type.GetValue(new byte[]));
Assert.Throws<ArgumentException>(() => type.GetValue(new byte[]));
}
}
}
第四篇完
解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)的更多相关文章
- 解剖SQLSERVER 第五篇 OrcaMDF里读取Bits类型数据(译)
解剖SQLSERVER 第五篇 OrcaMDF里读取Bits类型数据(译) http://improve.dk/reading-bits-in-orcamdf/ Bits类型的存储跟SQLSERVE ...
- 解剖SQLSERVER 第八篇 OrcaMDF 现在支持多数据文件的数据库(译)
解剖SQLSERVER 第八篇 OrcaMDF 现在支持多数据文件的数据库(译) http://improve.dk/orcamdf-now-supports-databases-with-mult ...
- 解剖SQLSERVER 第七篇 OrcaMDF 特性概述(译)
解剖SQLSERVER 第七篇 OrcaMDF 特性概述(译) http://improve.dk/orcamdf-feature-recap/ 时间过得真快,这已经过了大概四个月了自从我最初介绍我 ...
- 解剖SQLSERVER 第十篇 OrcaMDF Studio 发布+ 特性重温(译)
解剖SQLSERVER 第十篇 OrcaMDF Studio 发布+ 特性重温(译) http://improve.dk/orcamdf-studio-release-feature-recap/ ...
- 解剖SQLSERVER 第六篇 对OrcaMDF的系统测试里避免regressions(译)
解剖SQLSERVER 第六篇 对OrcaMDF的系统测试里避免regressions (译) http://improve.dk/avoiding-regressions-in-orcamdf-b ...
- 解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译)
解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译) http://improve.dk/the-anatomy-of-row-amp-page-compre ...
- 解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意损坏数据库(译)
解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意损坏数据库(译) http://improve.dk/corrupting-databases-purpose-usin ...
- 解剖SQLSERVER 第十一篇 对SQLSERVER的多个版本进行自动化测试(译)
解剖SQLSERVER 第十一篇 对SQLSERVER的多个版本进行自动化测试(译) http://improve.dk/automated-testing-of-orcamdf-against ...
- 解剖SQLSERVER 第三篇 数据类型的实现(译)
解剖SQLSERVER 第三篇 数据类型的实现(译) http://improve.dk/implementing-data-types-in-orcamdf/ 实现对SQLSERVER数据类型的解 ...
随机推荐
- sublime插件 cssComb实现css自动排序及格式化
cssComb是一个实现css代码自动排序,当然顺便也实现了代码的格式化 安装: 首先需要打开sublime搜索安装csscomb插件(前提是已经安装了sublime的package control) ...
- Git 在团队中的最佳实践--如何正确使用Git Flow[转]
原文地址:http://www.cnblogs.com/cnblogsfans/p/5075073.html Git的优点 Git的优点很多,但是这里只列出我认为非常突出的几点. 由于是分布式,所有本 ...
- CentOS下MySQL数据库安装
前辈们总是说,要边学边记录,要总结.所以,开始把每天学到的内容一点一点记录. 复杂的理论不懂,只会目前安装,安好后就开始玩咯! 1.在官网下载相应的rpm安装包 下载地址:http://dev.mys ...
- [linux] 默认权限修改(umask)
1 文件默认权限 对于目录,默认权限=777-umask 对于文件,默认权限=666-umask(文件默认无执行权限) 默认权限修改: vim /etc/bashrc 71行是普通用户的更改,73是超 ...
- VS2012常用快捷键
Ctrl+K,D ----格式化全部代码 Ctrl+K,F ----格式化选中的代码 Ctrl+K,C ----注释选定内容 Ctrl+K,U ----取消注释选定内容 Ctrl+J或者 Ctrl+S ...
- Rails中用CSV导出中文真心有技巧
require 'csv' class PartRequestsController < ApplicationController def render_csv_header(filename ...
- String的方法运用
public class StringUse { public static void main(String[] args) { int count = 0; String s=new String ...
- UIAlertController、UIAlertAction 警告框
NS_CLASS_AVAILABLE_IOS(8_0) @interface UIAlertAction : NSObject <NSCopying> //创建操作 + (instan ...
- SSMS错误:A connection was successfully established with the server, but then an error occurred during the login process
参考: 系统太慢,实在搞不清是哪里的问题,祭出重装大法 需要安装的工具还真多,先装主要的吧.VS2013, SQL SERVER 2012,搞定.. 连个数据库试试,出错了: A connection ...
- session和cookie的简单理解
0. 引子,我们为什么要cookie和session 因为http请求是无状态的(不能记录用户的登录状态等),所以需要某种机制来保存用户的登录状态等信息,在下次访问web服务的时候,不用再 ...