How to store and get datetime value in SQLite - sqlite

My table contains Birthdate field which has datatype as datetime.
I want to get all records having birthday today.
How can I get it?

Try this query:
SELECT * FROM mytable
WHERE strftime('%m-%d', 'now') = strftime('%m-%d', birthday)

Having a special datetime type has always seemed like unnecessary overhead to me, integers are fast, flexible, and use less space.
For general datetime values use Unix Epoch timestamps. Easy to work with, extremely flexible, as well as timezone (and even calender!) agnostic. (I recently wrote an article on using them, which I really have to plug...)
That said, if you're only interested in dates in the Gregorian calendar you may want to use a large integer in the following format: YYYYMMDD, eg 19761203. For you particular usage you could even create a four digit integer like MMDD, say 1703 — that's got to result in fast selects!

SQLite has very poor support for storing dates. You can use the method suggested by Nick D above but bear in mind that this query will result in full table scan since dates are not indexed correctly in SQLite (actually SQLite does not support dates as a built-in type at all).
If you really want to do a fast query then you'll have to add a separate (integral) column for storing the birth day (1-31) and attach an index for it in the database.
If you only want to compare dates then you can add a single (INTEGER) column that will store the date UTC value (but this trick won't allow you to search for individual date components easily).
Good Luck

Related

Range query on cloudsearch date

I have a dynamodb table which stores creation_date epoch in string format. This date is neither hash key nor sort key. Ultimate goal is querying the creation_date for a range i.e. I need all the ids in the give time range.
The table schema is:
id, version, creation_date, info.
id is hash key and version is sort key.
I was thinking of creating a cloudsearch domain and link that to dynamodb table. Is it possible to use a range query in cloudsearch using java if the date is in string format? If yes how?
Here’s how you can accomplish this in DynamoDB using a GSI with a hash key of creation_y_m and a GSI range key of creation_date.
When you’re querying for a range of creation dates, you need to do a bit of date manipulation to find out all of the months in between your two dates, but then you can query your GSI with a key condition expression like this one.
creation_y_m = 2019-02 AND creation_date BETWEEN 2019-02-05T12:00.00Z AND 2019-02-18T06:00:00Z
Given that most of your queries are a two week range, you will usually only have to make only one or two queries to get all of the items.
You may need to backfill the creation_y_m field, but it’s fairly straightforward to do that by scanning your table and updating each item to have the new attribute.
There are, of course, many variations on this. You could tweak how granular your hash key is (maybe you want just year, maybe you want year-month-day). You could use epoch time instead of ISO 8601 strings.

SQLite: select all rows made in a specific month

i want to get all entries from a SQLite table, which have the timestamp from the same month.
For example, the user can type in "July" and then i want to get all entries made in the 7. month.
The current "time"-column is a simple string and in the Format (DD.MM.YYYY HH:MM:SS)
Is there a way to do this with SQLite or will i need to use code in my program?
Assuming that your time strings have a fixed length, you could use a query like this:
SELECT * FROM MyTable WHERE time LIKE '__.07%';
However, you should always stored dates in one of the supported date/time formats so that you are able to use the built-int date/time functions.

Add julian date column to an SQLite table

This is easy, but I can't figure it out from the SQLite FAQ and vignette for ALTER TABLE.
I have a date column, but to find a time difference, I need to use julian dates, so I feel like I might as well add a julian date column because I'll be doing this a lot. But I can't figure out how to do it.
I've gone through a bunch of iterations, but I don't think I'm clicking with the SQLite philosophy of the ALTER TABLE and INSERT INTO commands. Thanks!
But I have no idea how to permanently
add a column to a table that is a
function of other columns in that
table. Is this not common usage?
You can't add a calculated column in an SQLite table. But you can do that with a VIEW.
CREATE TABLE TableWithDates (
ID INTEGER PRIMARY KEY,
Iso8601 TEXT
);
CREATE VIEW ViewWithDates AS
SELECT ID, Iso8601, JULIANDAY(Iso8601) AS Julian
FROM TableWithDates;
sqlite> INSERT INTO TableWithDates VALUES (1, CURRENT_TIMESTAMP);
sqlite> SELECT * FROM TableWithDates;
1|2010-12-23 21:13:26
sqlite> SELECT * FROM ViewWithDates;
1|2010-12-23 21:13:26|2455554.3843287
There are no DATE or TIME types in Sqlite. You're free to select what makes sense for you. If it's just timestamps for logging or something, STRING should be ok. If you're going to do datetime comparisons and math (which you are according to the question), INTEGER would be best.
This page discuses built-in functions for use. If you use INTEGER to store seconds since epoch, you can use subtraction to find a time difference.

How to format date and time values for SQLite?

Can't believe I have to ask this here. Even googling didn't help.
I want to do this:
insert into atable (adatefield,atimefield,adatetimefield) values (A,B,C);
adatefield is defined as DATE
atimefield is defined as TIME
adatetimefield is defined as DATETIME
What do I put for A, B and C?
It's nice that it's free but the documentation for SQLite is awful.
A date, time and datetime field will actually all store datetime, it just depends on what you insert into it, and they will all work with date strings.
You can
insert into atable values("2010-11-16","14:12:22","2010-11-16 14:12:22");
or you can actually just insert "2010-11-16 14:12:22" into all the fields and then select them back with:
select date(adatefield), time(atimefield), datetime(adatetimefield) from atable;
If however you want to make sure that the fields only contain exactly a date,time or datetime and you're inserting from variables, then you can
insert into atable values(date(thedate),time(thedate),datetime(thedate));
Sqlites typelessness makes some things really easy, but can confuse or complicate some other things.

Cast Date in Informix

I have never used Informix before and I'm trying to write a query that will return records over the last 365 days.
Here is the query I have been trying to use:
Select * from Visit where vis_mod_dt between today-365 and today;
That returns no records even though I know that there is data for the last 365 days. I am guessing that the vis_mod_dt in not a true date column, although it displays as '12/31/1899' I have tried to cast this column using:
select * from visit where date(vis_mod_dt) between today-365 and today;
This still returns no data.
Any ideas?
Informix DATE format
Be aware that the date 1899-12-31 corresponds to the internal date representation of zero (0). That is, internally, Informix stores DATE values in a 4-byte integer, and counts the number of days since 1899-12-31, so Day 1 was 1900-01-01 (and since it knows that 1900 was not a leap year, Day 60 was 1900-03-01).
That fact makes me worry about what is in your table. However, if the data in your table cannot be converted to a DATE upon request, normally you would get an error.
What is your table schema?
It would be sensible for you to establish the schema either using DB-Access and the Info/Tables option, or use DB-Schema:
dbschema -d dbase -t visit
The DB-Schema output is more suitable for adding to your question.
The query expressions using 'TODAY-365' and 'TODAY' should work fine - if there is data to select.
DBDATE environment variable
There is an environment variable, DBDATE, that you may need to set to get things to work - to convert from a string representation to dates. Since you are probably based in the UK (from your icon), then you may want and need to set the value of DBDATE to:
export DBDATE=DMY4/
This says that dates consist of the day, the month, a 4-digit year and the '/' is used as the preferred separator. You won't be surprised to learn that the presumed default value is usually 'MDY4/', for US format; I use 'Y4MD-' habitually, so I see DATE value the same as DATETIME YEAR TO DAY, which is the ISO 8601:2004 notation for a date. (It has many benefits: it is unambiguous, and naive sorting algorithms sort such dates into date order.) There's actually a lot of mechanism in the background in IDS (IBM Informix Dynamic Server - which, I assume, is the DBMS that you are using; there are some alternatives that are also Informix DBMS) such that strings with 2-digit dates will usually be converted correctly (but they are ambiguous and undesirable), and separators other than '/' will be recognized on input, but the slash will be used on 'output' (when converting DATE to string).
Information needed to improve the answer to this question - 1st Edition.
If what is here does not help, then I recommend editing your question to include:
The table schema.
A few (2-4) rows of data that you think should be selected but aren't.
Platform and version information. It can help to have the version down to the level of detail of IDS 11.50.FC4W1; occasionally it matters. Most usually, the first three digits are what affect things, of course.
If your table is big (many columns), try to select the key columns (vis_mod_dt is by far the most important one). Ideally, you won't need any scroll bars in the display.
Make sure you don't include any sensitive information.
Information needed to improve the answer to this question - 2nd Edition
I will help you if you pay attention to the questions I ask you. I cannot help you if you do not pay attention to the questions I ask. And please edit your question rather than adding information as an 'answer'.
What is the table schema? What is the output from:
SELECT t.tabid, t.tabname, c.colno, c.colname, c.coltype, c.collength
FROM "informix".systables AS t, "informix".syscolumns AS c
WHERE t.tabid = c.tabid
AND t.tabname = "visit"
ORDER BY t.tabid, c.colno;
What do you get from:
SELECT TODAY, TODAY-365 FROM "informix".systables WHERE tabid = 1;
Do you have the environment variable DBDATE set? If so, what is its value?
Do you have the environment variables CLIENT_LOCALE or DB_LOCALE set? If so, what are their values?
Which version of Informix are you using?
Which platform are you using it on?
Which language or tool are you using to run the query.
Note: if you cannot copy'n'paste the queries above, then you probably do not need to include the quoted '"informix".' attributes on the system catalog; however, as written, the queries will work on any extant Informix database - OnLine 5.x, SE 5.x or 7.x, IDS 7.x, XPS 8.x, IDS 9.x or 10.x or 11.x - and any mode of database (unlogged, logged, MODE ANSI). I'd use the JOIN notation except that some of the older versions don't support it - though you have to be on very old versions for that to be a problem.
This is a little confusing, because when I run the following, I get data:
select count(*) from visit where vis_mod_dt between "10/01/2008" and "10/01/2009"
how about unloading the table to ascii file, examine the unloaded vis_mod_dt values to see if they conform to DBDATE=MDY4 (mmddyyyy) format?.. if they do, ALTER vis_mod_dt to TYPE DATE if it's not a DATE column, then LOAD the unloaded table back in.
the: "BETWEEN today-365 AND today" part of your SELECT statement works for me in my apps.

Resources