亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

解剖SQLSERVER 第四篇 OrcaMDF里對dates類型數

系統(tǒng) 2251 0
原文: 解剖SQLSERVER 第四篇 OrcaMDF里對dates類型數據的解析(譯)

解剖SQLSERVER 第四篇 ?OrcaMDF里對dates類型數據的解析(譯)

http://improve.dk/parsing-dates-in-orcamdf/

在SQLSERVER里面有幾種不同的date相關類型,當前OrcaMDF 支持三種最常用的date類型:date,datetime,smalldatetime

?

SqlDate實現

date 類型在三種類型之中是最簡單的,他是一個3個字節(jié)的定長類型,存儲了日期值它支持的日期范圍從0001-01-01到9999-12-31

默認值是1900-01-01

比較坑爹的是.NET里面還沒有任何標準實現能夠支持3個字節(jié)的整數類型,只有short類型和int類型,但是,他們要不太大要不太小

另外,要正確讀取日期值,對于.NET的4字節(jié)整型我們必須執(zhí)行一些轉變去獲取正確的數字

一旦我們獲取到date的值,我們可以創(chuàng)建一個默認的datetime類型并且添加天數進去

      
        public
      
      
        class
      
      
         SqlDate : ISqlType

{

    
      
      
        public
      
      
        bool
      
      
         IsVariableLength

    {

        
      
      
        get
      
       { 
      
        return
      
      
        false
      
      
        ; }

    }



    
      
      
        public
      
      
        short
      
      ?
      
         FixedLength

    {

        
      
      
        get
      
       { 
      
        return
      
      
        3
      
      
        ; }

    }



    
      
      
        public
      
      
        object
      
       GetValue(
      
        byte
      
      
        [] value)

    {

        
      
      
        if
      
       (value.Length != 
      
        3
      
      
        )

            
      
      
        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[
      
        2
      
      ] << 
      
        16
      
      ) + (value[
      
        1
      
      ] << 
      
        8
      
      ) + value[
      
        0
      
      
        ];



        
      
      
        return
      
      
        new
      
       DateTime(
      
        1
      
      , 
      
        1
      
      , 
      
        1
      
      
        ).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(
      
        2028
      
      , 
      
        09
      
      , 
      
        09
      
      
        ), Convert.ToDateTime(type.GetValue(input)));

input 
      
      = 
      
        new
      
      
        byte
      
      [] { 
      
        0x71
      
      , 
      
        0x5c
      
      , 
      
        0x0b
      
      
         };

Assert.AreEqual(
      
      
        new
      
       DateTime(
      
        2039
      
      , 
      
        07
      
      , 
      
        17
      
      
        ), Convert.ToDateTime(type.GetValue(input)));

}

        [Test]


      
      
        public
      
      
        void
      
      
         Length()

{


      
      
        var
      
       type = 
      
        new
      
      
         SqlDate();

Assert.Throws
      
      <ArgumentException>(() => type.GetValue(
      
        new
      
      
        byte
      
      [
      
        2
      
      
        ]));

Assert.Throws
      
      <ArgumentException>(() => type.GetValue(
      
        new
      
      
        byte
      
      [
      
        4
      
      
        ]));

}

}

}
      
    

?

SqlDateTime實現

date類型只能存儲日期,而datetime類型不但能存儲date也能存儲time

datetime存儲8字節(jié)定長數據值,第一部分是time(4字節(jié)),而第二部分是date(4字節(jié))

計算date部分跟上面介紹date類型基本上一樣,不過這一次date部分是一個四字節(jié)整數,比上面的例子容易處理多了,上面的date類型是3個字節(jié)

time部分存儲為自午夜時的ticks數,一個tick就是1/300th 秒,為了顯示tick值,我們首先定義一個常量,常量值是10d/3d

time的各個部分實際同樣存儲在同一個整型值里面(比如時間,分鐘,秒,毫秒),所以我們要獨立訪問這些單獨的部分,我們必須

要執(zhí)行一些轉換 (包括取模和相除)

      
        部分     計算

小時   X 
      
      / 
      
        300
      
       / 
      
        60
      
       / 
      
        60
      
      
        

分鐘   X 
      
      / 
      
        300
      
       / 
      
        60
      
       % 
      
        60
      
      
        

秒     X 
      
      / 
      
        300
      
       % 
      
        60
      
      
        

毫秒   X 
      
      % 
      
        300
      
       * 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
      
      
        8
      
      
        ; }

    }



    
      
      
        public
      
      
        object
      
       GetValue(
      
        byte
      
      
        [] value)

    {

        
      
      
        if
      
       (value.Length != 
      
        8
      
      
        )

            
      
      
        throw
      
      
        new
      
       ArgumentException(
      
        "
      
      
        Invalid value length: 
      
      
        "
      
       +
      
         value.Length);



        
      
      
        int
      
       time = BitConverter.ToInt32(value, 
      
        0
      
      
        );

        
      
      
        int
      
       date = BitConverter.ToInt32(value, 
      
        4
      
      
        );



        
      
      
        return
      
      
        new
      
       DateTime(
      
        1900
      
      , 
      
        1
      
      , 
      
        1
      
      , time/
      
        300
      
      /
      
        60
      
      /
      
        60
      
      , time/
      
        300
      
      /
      
        60
      
      %
      
        60
      
      , time/
      
        300
      
      %
      
        60
      
      , (
      
        int
      
      )Math.Round(time%
      
        300
      
      *
      
        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(
      
        2001
      
      , 
      
        09
      
      , 
      
        25
      
      , 
      
        05
      
      , 
      
        39
      
      , 
      
        26
      
      , 
      
        820
      
      
        ), (DateTime)type.GetValue(input));

input 
      
      = 
      
        new
      
      
        byte
      
      [] { 
      
        0xb6
      
      , 
      
        0x87
      
      , 
      
        0xf0
      
      , 
      
        0x00
      
      , 
      
        0xd1
      
      , 
      
        0x8b
      
      , 
      
        0x00
      
      , 
      
        0x00
      
      
         };

Assert.AreEqual(
      
      
        new
      
       DateTime(
      
        1997
      
      , 
      
        12
      
      , 
      
        31
      
      , 
      
        14
      
      , 
      
        35
      
      , 
      
        44
      
      , 
      
        607
      
      
        ), (DateTime)type.GetValue(input));

input 
      
      = 
      
        new
      
      
        byte
      
      [] { 
      
        0x2d
      
      , 
      
        0xfd
      
      , 
      
        0x1c
      
      , 
      
        0x01
      
      , 
      
        0x4a
      
      , 
      
        0x75
      
      , 
      
        0x00
      
      , 
      
        0x00
      
      
         };

Assert.AreEqual(
      
      
        new
      
       DateTime(
      
        1982
      
      , 
      
        03
      
      , 
      
        18
      
      , 
      
        17
      
      , 
      
        17
      
      , 
      
        36
      
      , 
      
        790
      
      
        ), (DateTime)type.GetValue(input));

input 
      
      = 
      
        new
      
      
        byte
      
      [] { 
      
        0xff
      
      , 
      
        0x81
      
      , 
      
        0x8b
      
      , 
      
        0x01
      
      , 
      
        0x7f
      
      , 
      
        0x24
      
      , 
      
        0x2d
      
      , 
      
        0x00
      
      
         };

Assert.AreEqual(
      
      
        new
      
       DateTime(
      
        9999
      
      , 
      
        12
      
      , 
      
        31
      
      , 
      
        23
      
      , 
      
        59
      
      , 
      
        59
      
      , 
      
        997
      
      
        ), (DateTime)type.GetValue(input));

}

        [Test]


      
      
        public
      
      
        void
      
      
         Length()

{


      
      
        var
      
       type = 
      
        new
      
      
         SqlDateTime();

Assert.Throws
      
      <ArgumentException>(() => type.GetValue(
      
        new
      
      
        byte
      
      [
      
        9
      
      
        ]));

Assert.Throws
      
      <ArgumentException>(() => type.GetValue(
      
        new
      
      
        byte
      
      [
      
        7
      
      
        ]));

}

}

}
      
    

?

?

SqlSmallDateTime實現

Smalldatetime 是一個不錯的數據類型當你需要存儲范圍值內的日期值(1900~2079)并且他能精確到秒

大多數場景下,精確到秒已經足夠了,在一個范圍的時間間隔內和精確值不需要太精確的情況下會節(jié)省很多空間

smalldatetime 數據類型會只占用4個字節(jié),前2個字節(jié)存儲自午夜的分鐘數,后2個字節(jié)存儲日期,默認值是1900-1-1

處理的方法跟datetime差不多,只不過使用更小的范圍

      
        部分     計算

小時    X 
      
      / 
      
        60
      
      
        

分鐘    X 
      
      % 
      
        60
      
    
      
        public
      
      
        class
      
      
         SqlSmallDateTime : ISqlType

{

    
      
      
        public
      
      
        bool
      
      
         IsVariableLength

    {

        
      
      
        get
      
       { 
      
        return
      
      
        false
      
      
        ; }

    }



    
      
      
        public
      
      
        short
      
      ?
      
         FixedLength

    {

        
      
      
        get
      
       { 
      
        return
      
      
        4
      
      
        ; }

    }



    
      
      
        public
      
      
        object
      
       GetValue(
      
        byte
      
      
        [] value)

    {

        
      
      
        if
      
       (value.Length != 
      
        4
      
      
        )

            
      
      
        throw
      
      
        new
      
       ArgumentException(
      
        "
      
      
        Invalid value length: 
      
      
        "
      
       +
      
         value.Length);



        
      
      
        ushort
      
       time = BitConverter.ToUInt16(value, 
      
        0
      
      
        );

        
      
      
        ushort
      
       date = BitConverter.ToUInt16(value, 
      
        2
      
      
        );



        
      
      
        return
      
      
        new
      
       DateTime(
      
        1900
      
      , 
      
        1
      
      , 
      
        1
      
      , time / 
      
        60
      
      , time % 
      
        60
      
      , 
      
        0
      
      
        ).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(
      
        1926
      
      , 
      
        11
      
      , 
      
        22
      
      , 
      
        11
      
      , 
      
        23
      
      , 
      
        0
      
      
        ), Convert.ToDateTime(type.GetValue(input)));

input 
      
      = 
      
        new
      
      
        byte
      
      [] { 
      
        0x49
      
      , 
      
        0x03
      
      , 
      
        0x99
      
      , 
      
        0x09
      
      
         };

Assert.AreEqual(
      
      
        new
      
       DateTime(
      
        1906
      
      , 
      
        9
      
      , 
      
        24
      
      , 
      
        14
      
      , 
      
        1
      
      , 
      
        0
      
      
        ), Convert.ToDateTime(type.GetValue(input)));

}

        [Test]


      
      
        public
      
      
        void
      
      
         Length()

{


      
      
        var
      
       type = 
      
        new
      
      
         SqlSmallDateTime();

Assert.Throws
      
      <ArgumentException>(() => type.GetValue(
      
        new
      
      
        byte
      
      [
      
        3
      
      
        ]));

Assert.Throws
      
      <ArgumentException>(() => type.GetValue(
      
        new
      
      
        byte
      
      [
      
        5
      
      
        ]));

}

}

}
      
    

?

第四篇完

解剖SQLSERVER 第四篇 OrcaMDF里對dates類型數據的解析


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产福利视精品永久免费 | 全黄冷激性性视频 | 日韩午夜片 | 波多野结衣一区二区在线 | 精品一二区 | 国产成在线观看免费视频成本人 | 九九九影院 | 99九九视频 | 九九99香蕉在线视频网站 | 欧美日韩中文一区二区三区 | 在线观看一区二区精品视频 | 欧美日韩片 | 精品在线播放 | 免费人成黄页网站在线观看 | 一道本一区二区三区 | 免费h片在线观看网址最新 免费v片在线观看无遮挡 | 92国产福利久久青青草原 | 日韩视频免费一区二区三区 | 国产欧美一区二区另类精品 | 欧洲激情乱子伦 | 久久精品影院永久网址 | 97婷婷狠狠成人免费视频 | 不卡免费播放 | 伊人久久国产 | 性做久久久久久久久25的美女 | 亚洲精品福利一区二区 | 国产欧美日韩综合 | 2018一级毛片免费观看 | 天天干天天插天天 | 久久a热6| 色桃花网 | 久久精品亚洲99一区二区 | 国产精品福利在线观看入口 | 亚洲欧美一二三区 | 精品中文字幕一区在线 | 三级不卡 | 亚洲精品欧洲一区二区三区 | 一级色视频 | 亚洲欧美日韩综合 | 夭天干天天做天天免费看 | 国产成人拍精品视频网 |