How do DATETIME values work in SQLite? - sqlite

I’m creating Android apps and need to save date/time of the creation record. The SQLite docs say, however, "SQLite does not have a storage class set aside for storing dates and/or times" and it's "capable of storing dates and times as TEXT, REAL, or INTEGER values".
Is there a technical reason to use one type over another? And can a single column store dates in any of the three formats from row to row?
I will need to compare dates later. For instance, in my apps I will show all records that are created between date A until date B. I am worried that not having a true DATETIME column could make comparisons difficult.

SQlite does not have a specific datetime type. You can use TEXT, REAL or INTEGER types, whichever suits your needs.
Straight from the DOCS
SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.
SQLite built-in Date and Time functions can be found here.

One of the powerful features of SQLite is allowing you to choose the storage type. Advantages/disadvantages of each of the three different possibilites:
ISO8601 string
String comparison gives valid results
Stores fraction seconds, up to three decimal digits
Needs more storage space
You will directly see its value when using a database browser
Need for parsing for other uses
"default current_timestamp" column modifier will store using this format
Real number
High precision regarding fraction seconds
Longest time range
Integer number
Lowest storage space
Quick operations
Small time range
Possible year 2038 problem
If you need to compare different types or export to an external application, you're free to use SQLite's own datetime conversion functions as needed.

SQLite does not have a storage class set aside for storing dates
and/or times. Instead, the built-in Date And Time Functions of SQLite
are capable of storing dates and times as TEXT, REAL, or INTEGER
values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS"). REAL as Julian
day numbers, the number of days since noon in Greenwich on November
24, 4714 B.C. according to the proleptic Gregorian calendar. INTEGER
as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these
formats and freely convert between formats using the built-in date and
time functions.
Having said that, I would use INTEGER and store seconds since Unix epoch (1970-01-01 00:00:00 UTC).

For practically all date and time matters I prefer to simplify things, very, very simple... Down to seconds stored in integers.
Integers will always be supported as integers in databases, flat files, etc. You do a little math and cast it into another type and you can format the date anyway you want.
Doing it this way, you don't have to worry when [insert current favorite database here] is replaced with [future favorite database] which coincidentally didn't use the date format you chose today.
It's just a little math overhead (eg. methods--takes two seconds, I'll post a gist if necessary) and simplifies things for a lot of operations regarding date/time later.

Store it in a field of type long. See Date.getTime() and new Date(long)

Related

Does the IBM SPSS file format support datetime variables with timezone offset?

I'm working on data from a database with a timestamp column (including timezone offset), with multiple timezone offsets. Is it possible in SPSS to keep the offset information using a particular variable/data type?
I know about the general principle of converting all timestamps to a particular, common timezone — like UTC — but would like to know if SPSS supports date/time types with timezone information.
I have studied the SPSS Documentation about Date and Time Formats, but haven't seen any information about supporting timezones.
Given that SPSS internally stores the datetime value as a numerical value (which is the number of seconds since the epoch, midnight, Oct. 14, 1582) with no meta information, there is no way to keep time zones with the value.
You will therefore need to have another variable (i.e., column) containing the time zone information.

Does SQL Server store DateTime Offset Agnostic?

I've been searching all morning and can't seem to get a handle on this (though I do have a few possible theories). It's also not impossible that this might be a duplicate but please take into account that all the questions I searched, didn't give a definitive answer but were rather too open to interpretation.
In SQL Server (>= 2012), a table column of type datetime, is it stored timezone offset agnostic or is how does it work? From my investigation, it would seem that datetimeoffset is the type that includes the offset with the date/time while datetime simply omits this?
When I read the data from the database, and use CONVERT( datetimeoffset, [My Column] ) it's giving me 2016-09-21 16:49:54.7170000 +00:00 while myself and the server are both in UTC +02:00 which reinforces my belief, am I correct?
What I'm trying to achieve, is allow data to be saved FROM various tz offsets (via a function), then saved into the database in UTC and finally convert the datetime value back to a (possibly different) offset. I don't care about DST / etc as the users browser will give me the current offset at the time of the saving and the viewing user will give me their tz offset at the time of viewing. For historic reports the exact time of day (DST dependent) is irrelevant.
Currently the database tables already use datetime as opposed to datetimeoffset; it's my observation that it's completely fine to continue with this, though at some point, it might be good to change to datetimeoffset in order to then have start recording the historic tz offset?
Any clarity will be greatly appreciated.
TL;DR; Yes. the DateTime (and DateTime2) data type is not time-zone aware.
The long version:
Official documentation of DateTime clearly states that the DateTime data type does not support time zone (nor daylight savings time). Same is true for DateTime2.
You can see in both pages there's a table that describes the data type's properties, and in that table, for both data types, the value for "Time zone offset aware and preservation" and for "Daylight saving aware" is "No".
Time zone offset aware and preservation No
Daylight saving aware No
The description of DateTime is as follows:
Defines a date that is combined with a time of day with fractional seconds that is based on a 24-hour clock.
The description of DateTime2 is as follows:
Defines a date that is combined with a time of day that is based on 24-hour clock.
datetime2 can be considered as an extension of the existing datetime type that has a larger date range, a larger default fractional precision, and optional user-specified precision.
The only data type that is timezone aware is DateTimeOffset:
Defines a date that is combined with a time of a day that has time zone awareness and is based on a 24-hour clock.
Btw, it is recommended to choose DateTime2 over DateTime, both by Microsoft official documentation:
Note
Use the time, date, datetime2 and datetimeoffset data types for new work. These types align with the SQL Standard. They are more portable. time, datetime2 and datetimeoffset provide more seconds precision. datetimeoffset provides time zone support for globally deployed applications.
And by SQL Server professionals: Why You Should Never Use DATETIME Again!:
Datetime also have a bug/feature implicitly converting string literals of format yyyy-mm-dd / yyyy-mm-dd hh:mm:ss - Datetime will try to convert them using local settings, while Datetime2 will always convert them correctly.
Check out this SO post about it.

Sqlite dd/mm/yyyy format. How to avoid conversion?

The program I am currently designing use the dd/mm/yyyy date format, while Sqlite standard format is yyyy-mm-dd. My program make use of quite a lot of date calculations using julianday('yyyy-mm-dd'). I know I could convert the dd/mm/yyyy format to yyyy-mm-dd by using SUBSTR(X,Y) manipulation or by using the code of the language I am designing the db front-end; but i wish to avoid those. Any Idea?
You should always store dates (and timestamps) using native date format that is provided by database engine for following reasons:
Native formats permit native date arithmetic functions to work.
Native formats permit indexes to be consistently applicable, so you can use date comparisons efficiently and use operators like BETWEEN.
Native formats take less space to store on disk. For SQLite, storing date as real number of days from 4174 BC or as integer number of seconds since Jan 1st, 1970 takes 8 bytes. For your representation, it will take at least 10 bytes.
While SQLite does not really have true native date/datetime type (which is big omission in my opinion), it does have 3 permissible formats: TEXT, REAL or INTEGER that are still treated (to some extent) as native datetime formats, and all advantages outlined above still apply.
When you need to display dates in your application, you should use libraries provided by your scripting or other programming languages that know how to display dates in desired format.
In other words, use database to store, compare and retrieve data, and use your application to render it in desired format.

If I'm creating a date/datetime in a column in Sqlite, do I set it to anything other than 'Text'?

Just getting into SQLite and I understand it does not use datatypes the same way as other languages.
I'm building a database and it has to store date and time quite a lot. And I've read a lot about the date and time functions, etc, but I just want to make sure that in my CREATE script I shouldn't have anything other than
BirthDate TEXT
DateTime TEXT
I'm not sure exactly what your question is, but I think the below excerpt may prove to be useful (taken from http://www.sqlite.org/datatype3.html):
SQLite does not have a storage class set aside for storing dates
and/or times. Instead, the built-in Date And Time Functions of SQLite
are capable of storing dates and times as TEXT, REAL, or INTEGER
values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November
24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these
formats and freely convert between formats using the built-in date and
time functions.

How to get sqlalchemy storing datetime as julianday in sqlite?

I don't like how SQLAlchemy treats datetime values with sqlite databases. It stores the values in plain string format. At the same time sqlite recommends using julianday for storing datetime values.
Is there an easy way to change the SQLAlchemy's behaviour here?
PS. Shall I worry about it? May be noone is dealing with julianday just because it's not necessary?
Actually it is not SQLAlchemy that stores dates as plain strings; SQLite itself does not support date types. It's important that you understand that from the outset; Sqlite does provide some functions for dealing with dates, but those are dates stored as text. That's why SQLAlchemy does some magic in transforming the dates to and from python's datetime type: Per the SQLAlchemy's documentation:
SQLite does not have built-in DATE,
TIME, or DATETIME types, and pysqlite
does not provide out of the box
functionality for translating values
between Python datetime objects and a
SQLite-supported format. SQLAlchemy’s
own DateTime and related types provide
date formatting and parsing
functionality when SQlite is used. The
implementation classes are SLDateTime,
SLDate and SLTime. These types
represent dates and times as ISO
formatted strings, which also nicely
support ordering. There’s no reliance
on typical “libc” internals for these
functions so historical dates are
fully supported.
As for using the Julian calendar as opposed to the Gregorian calendar. Are you sure you want that? Might you mean Gregorian dates?

Resources