Optimal way to store datetime values in SQLite database (Delphi)

后端 未结 5 1278
无人及你
无人及你 2021-02-08 16:29

I will be storing datetime values in an SQLite database (using Delphi and the DISqlite library). The nature of the db is such that it will never need to be transferred between c

相关标签:
5条回答
  • 2021-02-08 16:29

    For this I usually use an Integer data type and store the Unix timestamp value alike (eq # seconds since 1-1-2000 for example). Calculating this t/from a TDateTime is equal to multiplying/diving with/by 86400 and adding a constant for the 'since'.

    If you need more precision You could use the DateTime as a FILETIME (eg int64) which has 100 ns increments. There are conversion routines in SysUtils for that and your timestamp is stored in UTC.

    0 讨论(0)
  • 2021-02-08 16:32

    I don't know if this answer is applicable to the DISqlite library but...
    Below is some code that illustrates what works for me using both Delphi 2010 and Tim Anderson's SQLite3 wrapper.

    SQL to create field:

      sSQL :=  'CREATE TABLE [someTable] (' +
                '  [somefield1] VARCHAR(12),' +
                '  [somefield2] VARCHAR(12),' +
                '  [myDateTime] DATETIME );';
    

    SQL to populate field:

     sSQL := 'INSERT INTO someTable(somefield1, somefield2, myDateTime)' + 
             '  VALUES ( "baloney1", "baloney2","' + FloatToStr(Now) + '");';
    

    Example of retrieving data from field:

    var
    sDBFilePathString: string;
    sl3tbl: TSqliteTable;
    fsldb : TSQLiteDatabase;
    FromdbDTField : TDateTime;
    
    begin
       ...
       ... 
        fsldb := TSQLiteDatabase.Create(sDBFilePathString); 
        sl3tbl := fsldb.GetTable('SELECT * FROM someTable');
        FromdbDateTime := StrToFloat(sl3tbl.FieldAsString(sl3tbl.FieldIndex['myDateTime']));
        Showmessage('DT: ' + DateTimeToStr(FromdbDTField));
    end;
    

    Result:

    **DT: 10/10/2013 1:09:53 AM**
    

    Like I mentioned on the first line - I don't know if this will work with the DISqlite library but if it does its a pretty clean way of handling things. I leave it to you to make things prettier or more elegant.

    0 讨论(0)
  • 2021-02-08 16:34

    If your concern is only human readable format at database level, you can store two separate fields, for example:

    DELPHI_DATE REAL (DOUBLE, if possible, but I don't know SQLite), Indexed. All your programmatic queries and comparisons should use this field.

    HUMAN_READABLE_DATE Varchar(23) with format 'YYYY-MM-DD HH:MM:SS.SSS'. Maybe indexed (if really necessary). Majority of human input queries should include this field and you can use (as said by others) SQLite date functions.

    It has some drawbacks:

    • Space consumption at database and network traffic grows,
    • insert operations will take a bit more because necessary conversion,
    • no automatic synch between values if updated outside your program

    If it is suitable for your particular needs, is up to you.

    0 讨论(0)
  • 2021-02-08 16:50

    You could use one of the SQLite supported string formats, eg. YYYY-MM-DD HH:MM:SS.SSS.

    It would be just as easy as YYYYMMDDHHNNSS - you still wouldn't need to scan for separators, since all the numbers are fixed length - and you would get SQLite date function support.

    If you need SQLite date function support, I would go with that method.

    If not, I'd recommend using REAL values. You can still compare them to each other (higher numbers are later in time), and consider date and time separately (before and after the decimal point respectively) without converting to TDateTime.

    0 讨论(0)
  • 2021-02-08 16:52

    One compromise would be to stick with REAL values, but store them as julian dates by using Delphi's DateTimeToJulianDate. That way they remain fast for reading, there's little performance lost in the converation, and they're still in a format that makes sense outside of Delphi.

    0 讨论(0)
提交回复
热议问题