SQLite時間處理

來源:互聯網
上載者:User

標籤:

 sqlite資料庫處理時間問題 和 日期時間函數

首先,sqlite資料庫在時間處理上和sqlserver還有oracle不同,下面根據自己做過的執行個體總結一下. 建立了一個Log資料表: 

LogID   SourceID   OperatorID   LogType LogLevel   LogTime                    LogContent
1     aaa.aspx     0       2     1       2011-08-18 16:44:32.000   aaaa
2     bbb.aspx     1       2     2       2011-08-18 16:38:32.000   bbbb
3     ccc.aspx     2       3     3       2011-09-02                   cccc
4     ddd.aspx     3       1     4       2011-08-15                   dddd
5     eee.aspx     4       1     3       2011-08-18                   eee

普通的sqlserver的查詢語句如下:select * from Log whereLogTime=‘2011-09-02‘可以查詢出"‘2011-09-02"的資料。

而在sqlite資料庫中,寫上面的語句,查詢不到任何資料;說明sqlserver於sqlite對於時間處理上是不同的。那麼如何寫一條以時間為查詢條件的sql語句才能在sqlite資料庫中把想要的結果查詢出來呢?請看::::

select * from Log where datetime(LogTime)=datetime(‘2011-08-18 16:38:32.000‘)

sqlite資料查詢語句,必須對時間欄位和傳入的時間參數做轉換.即加上datetime()轉換. 執行了上面的語句,就可以得到要尋找到結果。如果按照sqlserver的寫法,那麼是不會得到查詢結果的。另外,一些錯誤的查詢語句如下:

1: select * from Log where datetime(LogTime)=datetime(‘2011-08-18‘),這條語句只能查詢到一條資料,就是對應LogID=5的那條,而不 會得到LogID=1和LogID=2的資料。可見,sqlite對於時間是非常嚴格的。精確度非常高。

2:select * fromLog where datetime(LogTime)=datetime(‘2011-8-18‘),這條語句是查詢不到任何結果,因為sqlite的時間要求是 yyyy-MM-dd或者yyyy-MM-dd hh:mm:ss的。當月數為10以下,那麼必須寫成0x的形式(如:05),所以在做開發的時候一定要對入庫的時間做相應處理。

3: select *from Log where datetime(LogTime)=datetime(‘2011-08-9‘),同樣的,這條語句也查詢不到任何結果,應該把9改成09,就可以得到查詢結果了。

SQLite 日期時間函數
SQLite並沒有datatime欄位類型,但是可以在字串類型欄位中儲存時間,並提供了一些比較實用的日期時間操作函數

strftime(日期時間格式, 日期時間字串, 修正符, 修正符, ……)
strftime( 日期時間格式, 日期時間字串 ) 也就等價於AAuto中的:
time( 日期時間字串,日期時間格式 ) ,sqlite與AAuto 使用的格式化文法也一樣。
參考:http://www.aau.cn/doc/reference/libraries/kernel/time/time.html

strftime() 函數返回一個經過格式化的日期時間,
它可以用下面的符號對日期和時間進行格式化:

%d    一月中的第幾天 01-31
%f    小數形式的秒,SS.SSSS
%H    小時 00-24
%j    一年中的第幾天 01-366
%J    Julian Day Numbers
%m    月份 01-12
%M    分鐘 00-59
%s    從 1970-01-01日開始計算的秒數
%S    秒 00-59
%w    星期,0-6,0是星期天
%W    一年中的第幾周 00-53
%Y    年份 0000-9999
%%    % 百分比符號

date,time,datetime,julianday 函數

date(日期時間字串, 修正符, 修正符, ……)  等價於  strftime(“%Y-%m-%d”,…)
time(日期時間字串, 修正符, 修正符, ……)  等價於 strftime(“%H:%M:%S”,…) 
datetime(日期時間字串, 修正符, 修正符, ……) 等價於 strftime(“%Y-%m-%d %H:%M:%S”,…) 
julianday(日期時間字串, 修正符, 修正符, ……) 等價於strftime(“%J”,…)

日期時間字串
可以用以下幾種格式:
格式有嚴格的要求2008-06-15 03:35:28 日期只能用‘-‘分隔,時間只能用‘:‘ 分隔,不足二位元的必須補零

  • YYYY-MM-DD
  • YYYY-MM-DD HH:MM
  • YYYY-MM-DD HH:MM:SS
  • YYYY-MM-DD HH:MM:SS.SSS
  • YYYY-MM-DDTHH:MM
  • YYYY-MM-DDTHH:MM:SS
  • YYYY-MM-DDTHH:MM:SS.SSS
  • HH:MM
  • HH:MM:SS
  • HH:MM:SS.SSS
  • now
  • DDDD.DDDD
    在第五種到第七種格式(ISO8601)中的“T”是一個分割日期和時間的字元;
    第八種到第十種格式只代表2000-01-01日的時間,
    第十一種格式的’now’表示返回一個當前的日期和時間,使用格林威治時間(UTC);
    第十二種格式表示一個Julian Day Numbers。

    修正符: 日期和時間可以使用下面的修正符來更改日期或時間:

  • NNN days
  • NNN hours
  • NNN minutes
  • NNN.NNNN seconds
  • NNN months
  • NNN years
  • start of month
  • start of year
  • start of week
  • start of day
  • weekday N
  • unixepoch
  • localtime
  • utc 前六個修正符就是簡單的增加指定數值的時間和日期;第七到第十個修正符表示返回當前日期的開始;第十一個修正符表示返回下一個星期是N的日期和時間;第十二個修正符表示返回從1970-01-01開始算起的秒數;第十三個修正符表示返回本地時間。

    下面舉一些例子:
  • 電腦目前時間 SELECTdate(‘now’)
  • 電腦當前月份的最後一天SELECT date(‘now’,’start of month’,’+1 month’,’-1 day’)
  • 計算UNIX 時間戳記1092941466表示的日期和時間 SELECT datetime(‘1092941466’,’unixepoch’)
  • 計算 UNIX 時間戳記1092941466 表示的本地日期和時間 SELECT datetime(‘1092941466’,’unixepoch’,’localtime’)
  • 電腦當前UNIX 時間戳記 SELECT strftime(‘%s’,’now’)
  • 兩個日期之間相差多少天SELECT jolianday(‘now’)-jolianday(‘1981-12-23’)
  • 兩個日期時間之間相差多少秒SELECT julianday(‘now‘)*86400 - julianday(‘2004-01-01 02:34:56‘)*86400
  • 計算今年十月份第一個星期二的日期 SELECT date(‘now‘,‘start of year‘,‘+9 months‘,‘weekday 2‘);
  • 取大於現在時間的資料select * from 表 where 日期欄位>datetime(‘now‘,‘localtime‘)
  • 比較日期指定部份,舉一反三,同樣使用strftime格式式日期來對日、周、年比較 select * from 表 where strftime(‘%m‘,日期欄位)=strftime(‘%m‘,‘now‘)
  • 大於指定時間的第一條        select title,pubtime from article where pubtime>‘2008-06-15 03:35:28‘ orderby pubtime asc Limit 1 Offset 0
  • 小於指定時間的第一條select title,pubtime from article where pubtime<‘2008-06-15 03:35:28‘ orderby pubtime desc Limit 1 Offset 0

    簡單樣本:
    SELECT
        datetime(CHANGE_DATE,‘localtime‘),
        strftime(‘%Y-%m-%d‘,CHANGE_DATE,‘localtime‘),
        datetime(‘now‘,‘localtime‘),
        strftime(‘%Y-%m-%d‘,‘now‘,‘localtime‘),
        DATE(‘now‘,‘localtime‘),
        time(‘now‘,‘Localtime‘),
        time(‘2010-11-27 01:12:21‘,‘Localtime‘,‘-8 hour‘) as Time
    FROM SALARY_HISTORY ;

    SELECT * FROM SALARY_HISTORY WHEREdate(CHANGE_DATE,‘Localtime‘)=Date(‘now‘,‘Localtime‘)

 SQLite 時間的儲存與查詢


一 時間的儲存
   經過GOOGLE發現大多數的解決方案為datetime.ToString("s")來解決的,經過測試此方法雖然解決的問題,但還不夠完美。

因為這樣格式化出來的時間在用工具SQLite Developer 查看時顯示的時間看起來很怪,不直觀。而且如果在SQLite Developer

手動修改了時間,在程式中會報錯,因為這個時候儲存的時間格式發現了改變。經過測試發現datetime.ToString("yyyy-MM-dd

hh:mm:ss")可以很好的解決這個問題。

二 時間的查詢
   如果你用SQLite作開發,一定少不了時間的查詢,一定會讓你動不少腦精。因為和別的資料庫不一樣,就如要查詢2009.3.20

11:00:00領取工資的有多少人的SQL怎麼寫呢,你一定會寫成:

   select count(*) from T where statue=‘1‘ and [date]=‘2009-03-2011:00:00‘

仔細查看會發現有問題,因為沒有結果,實際表中是有結果的,這是為什麼,其實我也不沒有搞清楚。這個問題還是在國外的一個

論壇發現解決方案的。只要改一下上面的語句就可以了

 select count(*) from T where statue=‘1‘ anddatetime([date])=datetime(‘2009-03-20 11:00:00‘)

 or
 
  select count(*) from T where statue=‘1‘ and datetime([date])=‘2009-03-2011:00:00‘

 記住2009-03-20不能寫成為2009-3-20.


  以上方法經過測目前沒有發現問題,當然我也是初次使用SQLite來開發一個小項目,也許還有問題沒有發現出來,請各位指教!

 Sqlite 查詢時間格式處理  

Windows 下沒有strptime,sqlite查詢時間戳記欄位後得出的是char*,要轉成time_t很不爽。臨時解決方案如下:

1、sql語句需要格式化時間戳記欄位:
string strSql = "select strftime(‘%%Y%%m%%d%%H%%M%%S‘,mytime) as mytimefrom mytable“;

2、寫一個C函數進行轉換:
long TimeStamp2Time_t(char* pszTimeStamp /*"YYYYMMDDhhmmss"*/)
{
    int ttt[6][4]={{0,5,4,1900}
                   ,{4,4,2,1}
                   ,{6,3,2,0}
                   ,{8,2,2,0}
                   ,{10,1,2,0}
                   ,{12,0,2,0}};

    time_t t=time(NULL); struct tm* mytm = localtime(&t);
    for(int i=0;i<6;i++)
    {
        char tmp[5]="";
       memcpy(tmp,((char*)pszTimeStamp)+ttt[i][0],ttt[i][2]);
        *(((int*)mytm)+ttt[i][1])=atoi(tmp)-ttt[i][3];
    }

    return mktime(mytm);
}

       

SQLite支援5個日期和時間函數如下:

S.N.

函數

例子

1

date(timestring, modifiers...)

This returns the date in this format: YYYY-MM-DD

2

time(timestring, modifiers...)

This returns the time as HH:MM:SS

3

datetime(timestring, modifiers...)

This returns YYYY-MM-DD HH:MM:SS

4

julianday(timestring, modifiers...)

This returns the number of days since noon in Greenwich on November 24, 4714 B.C.

5

strftime(timestring, modifiers...)

This returns the date formatted according to the format string specified as the first argument formatted as per formatters explained below.

上述五個日期和時間函數時間字串作為參數。後跟零個或多個修飾符的時間字串。 strftime()函數還需要一個格式字串作為其第一個參數。下面的部分將給予您詳細的時間字串和改性劑的不同類型。

5.1    時間字串:

一時間字串可以在任何採用以下格式:

S.N.

時間字串

例子

1

YYYY-MM-DD

2010-12-30

2

YYYY-MM-DD HH:MM

2010-12-30 12:10

3

YYYY-MM-DD HH:MM:SS.SSS

2010-12-30 12:10:04.100

4

MM-DD-YYYY HH:MM

30-12-2010 12:10

5

HH:MM

12:10

6

YYYY-MM-DDTHH:MM

2010-12-30 12:10

7

HH:MM:SS

12:10:01

8

YYYYMMDD HHMMSS

20101230 121001

9

now

2013-05-07

可以使用“T”作為一個文字字元分隔日期和時間。

5.2    修飾符

隨後的時間字串可以由零個或多個的修飾符將改變日期和/或任何上述五大功能返回時間。修飾符應用於從左側到右側和下面的修飾符可在SQLite使用:

  • NNN days
  • NNN hours
  • NNN minutes
  • NNN.NNNN seconds
  • NNN months
  • NNN years
  • start of month
  • start of year
  • start of day
  • weekday N
  • unixepoch
  • localtime
  • utc
5.3    格式化:

SQLite 提供了非常方便的函數strftime() 來格式化任何日期和時間。可以使用以下替換格式化的日期和時間:

替代

描述

%d

Day of month, 01-31

%f

Fractional seconds, SS.SSS

%H

Hour, 00-23

%j

Day of year, 001-366

%J

Julian day number, DDDD.DDDD

%m

Month, 00-12

%M

Minute, 00-59

%s

Seconds since 1970-01-01

%S

Seconds, 00-59

%w

Day of week, 0-6 (0 is Sunday)

%W

Week of year, 01-53

%Y

Year, YYYY

%%

% symbol

5.4    例子

讓我們嘗試不同的例子,現在使用SQLite的提示的。以下計算當前的日期:

sqlite> SELECT date(‘now‘);
2013-05-07

以下計算當前月份的最後一天:

sqlite> SELECT date(‘now‘,‘start of month‘,‘+1 month‘,‘-1 day‘);
2013-05-31

以下計算給定的日期和時間的UNIX時間戳記1092941466:

sqlite> SELECT datetime(1092941466, ‘unixepoch‘);
2004-08-19 18:51:06

以下計算UNIX時間戳記1092941466抵消本地時區的日期和時間:

sqlite> SELECT datetime(1092941466, ‘unixepoch‘, ‘localtime‘);
2004-08-19 11:51:06

以下計算當前的UNIX時間戳記:

sqlite> SELECT datetime(1092941466, ‘unixepoch‘, ‘localtime‘);
1367926057

以下計算的美國“獨立宣言”簽署以來的天數:

sqlite> SELECT julianday(‘now‘) - julianday(‘1776-07-04‘);
86504.4775830326

以下一個特別的時刻在2004年以來的秒數計算:

sqlite> SELECT strftime(‘%s‘,‘now‘) - strftime(‘%s‘,‘2004-01-01 02:34:56‘);
295001572

以下計算日期為當年10月的第一個星期二:

sqlite> SELECT date(‘now‘,‘start of year‘,‘+9 months‘,‘weekday 2‘);
2013-10-01

以下計算時間自UNIX紀元秒(類似strftime(‘%s‘,‘now‘) ,除了包括小數部分):

sqlite> SELECT (julianday(‘now‘) - 2440587.5)*86400.0;
1367926077.12598

UTC與本地時間值之間進行轉換,格式化日期時間,使用UTC或localtime修改如下:

sqlite> SELECT time(‘12:00‘, ‘localtime‘);
05:00:00
sqlite>  SELECT time(‘12:00‘, ‘utc‘);
19:00:00

SQLite時間處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.