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

解剖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條評論
主站蜘蛛池模板: 狠狠地射| 在线观看不卡视频 | 天天操夜夜爱 | 久热天堂| 亚洲高清国产一区二区三区 | 欧美毛片基地 | 色老头成人免费视频天天综合 | 天天综合天天综合色在线 | 夜鲁夜鲁夜鲁在线观看福利 | 色视频在线播放 | 亚洲人和日本人hd | 五月天婷婷在线免费观看 | 国产一区二区亚洲精品天堂 | 久久精品综合国产二区 | 国产v片成人影院在线观看 国产v视频 | 成年看片永远免费 | 99在线热播精品免费 | 久久久久亚洲精品美女 | 欧美十区| 夜夜爱夜夜爽夜夜做夜夜欢 | 精品一区二区三区视频在线观看免 | 日韩视频精品 | 桃花福利视频在线观看 | 日日噜噜夜夜躁躁狠狠 | 同性女女黄h片在线播放 | 男女很黄很色床视频网站免 | 国产在线精品一区二区中文 | 韩国精品一区 | 日本九九视频 | 四虎影视永久地址www成人 | 欧美香蕉爽爽人人爽观看猫咪 | 99久久综合 | 免费人成年短视频在线观看网站 | 国产日韩一区二区三区在线播放 | 亚欧成人毛片一区二区三区四区 | 国产亚洲精品在天天在线麻豆 | 精品国产自 | 欧美日韩亚洲精品一区 | 成人18免费网站 | 国产精品欧美日韩一区二区 | 最新69成人精品毛片 |