Cast Date in Informix - datetime

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.

Related

Makedate function in sqlite

I need to create a date from the year and the day number of the year in sqlite, I have seen that for mysql there is the MAKEDATE () function, which does exactly what I need, but in sqlite it doesn't work.
How could I solve this?
For example:
I have a year 2020 and number day 20, i expected this output = '2020-04-01'
I m not sure about where you are going to use, but Sqlite does provide modifiers that you can use for the various date-time functions.
Check this link. It is not possible to provide the detail explanation here so I m referring to the link.
Below is one such query I prepared using those modifiers, this query calculates the date, by changing now to start of year and adding 20 days (NNN days),
SELECT DATE('now','start of year','20 days');
You can check this query output here.
So natively Sqlite supports this, but I m not sure about the application you will be using SQLite with supports this or not.

Using DATEPART in sql statement to get records with specific year

In Classic ASP:
I can extract the year from a date/time field:
tester=rs.fields("datestamp")
tester=DATEPART("yyyy",tester)
But I cannot seem to figure out how to make this work in a SQL statement to bring all the records from a specific year:
Select * from table1 where DATEPART("yyyy",datestamp)='2012'
and this doesn't work either:
Select * from table1 where DATEPART("yyyy",datestamp)=2012
I've looked through a zillion examples, here and elsewhere, and can't seem to find one that'll make this work. What am I doing wrong?
The function DatePart can extract from any date some values.
The best explanation that i know is here: W3School.com
And this command can be used as a part of SQL string as you want, but in this case you must considerer that the main parameter change.
Sample for filter by Month for less that June:
DATEPART(month, yourvar_withdate) <= 6
Check this explanation: W3School.com-SQL
Sure that you need use a number without quotes to eval. You can check "yy" or year (without quotes) to verify.
One more note, you must have always content on DateStamp field or receive an error.

Oracle 11g SQL loader, time format issue

I am trying to load a .csv file using SQL loader. I get this error message on a column that should store time column:
column TIME.ORA-01843: not a valid month
In my .csv file time has the format HH:MM:SS but I can't understand why Oracle does not recognise it.
Using the command select * from nls_session_parameters; I see that the default time format is HH24.MI.SSXFF. I tried to change the time separator in my csv file but I got the same error result.
I have a very simple control file, that looks like below.
LOAD DATA
INFILE Cycling_Accidents0512.csv
INTO TABLE CYCLING_ACCIDENTS
FIELDS TERMINATED BY ','
(ID,
ACC_ID,
OSGB_EASTING,
OSGB_NORTHING,
WGS_LONG,
WGS_LAT,
POLICE_FORCE,
ACC_SEVERITY,
NUM_VEI,
NUM_CAS,
ACC_DATE,
DAY_WEEK,
TIME,
LOC_AUTH_DIS,
LOC_AUTH_HIGH,
FST_ROAD_CLASS,
FST_ROAD_NUMBER,
ROAD_TYPE,
SPEED_LIMIT,
JUNCT_DETAIL,
JUNCT_CONTROL,
SND_ROAD_CLASS,
SND_ROAD_NUM,
PED_HUM,
PED_PHY,
LIGHT_COND,
WEATH_COND,
ROAD_SUR_COND,
SPEC_COND,
CARR_HAZARDS,
URB_RUR,
POLICE_ATT,
LSOA_ACC_LOC,
VEI_TYPE)
If someone of you can help me to modify the control file in order to make the time format acceptable to Oracle, that would be appreciated. I tried to look up on other web resources but I haven't found anything that could help.
Thanks!
You mentioned querying the session NLS parameters, but the value you showed appears to be NLS_TIME_FORMAT, which is only used internally.
Oracle doesn't have a time-only type, so your field is presumably actually a DATE type (or possibly TIMESTAMP). The values in the column will have a date part, even if you ignore it.
SQL*Loader will use NLS_DATE_FORMAT to interpret the data file value for a DATE field. If that is DD/MM/YYYY then it would liberally interpret a value like 22:41:17 as the 22nd day of the 41st month - hence your error - in the year 17.
You can specify the date format model in the control file:
TIME DATE 'HH24:MI:SS',
The value in the table would have that time, on the first day of the current month.
The SQL*Loader documentation does refer to a TIME data type which I have never seen used, and I can't find any references to it anywhere, including MOS. A quick bit of experimentation hasn't helped. If I make the control file entry:
TIME TIME,
... then the record is rejected with ORA-00933: SQL command not properly ended. The log file also shows the data type as DATETIME HH24.MI.SSXFF, which looks related to the NLS_TIME_FORMAT value. I haven't found a way to make it accept that. If I change the column definition from DATE to TIMESTAMP then I get a different error, ORA-00904: "TO_TIME": invalid identifier, which is even stranger. It almost looks like these data types are defined in SQL*Loader for future use. (This discussion suggests they thought about adding TIME as a database type in 10g, but obviously can't verify that. And this is in the SQL*Loader reference at least back to 9i).

How to store and get datetime value in 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

SQL Server 2005 vs. ASP.net datetime format confusion

I've found a similar question on stack overflow, but it didn't really answer the question I have. I need to make sure that my asp.net application is formatting the date dd/mm/yyyy the same as my SQL Server 2005.
How do I verify the date culture (if that's what it's called) of the server matches how I've programmed my app? Are there specific database settings and OS settings? Is it table-specific? I don't want to transpose my days and months.
thank you
When you get a DateTime out of the database, it should be in a non-cultured format (like the DateTime object, based on the number of ticks since a certain date). It is only when you are converting that value into a string that you need to be concerned with culture. In those cases, you can use yourDateTimeValue.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture) to make sure that the information displays correctly.
I belive that if you use SqlParameters ADO.NET will take care of the rest and you don't have to worry about it. Besides, it's good for defending against SQL Injection attacks too! :)
** Watch out because SQL DateTime columns are non-nullable and their minimum value is 1/1/1753 while .net DateTimes are non-nullable with min values of 1/1/0001. **
If you're pulling data from a real DateTime column, by default it will always be in the same standard format. For saving the data to the column, you might want to specify the SqlDbType.DateTime in your parameter.
i ripped this off of http://bytes.com/forum/thread767920.html :
com.Parameters.Add("#adate", SqlDbType.DateTime).Value = DateTime.Now;
Well, if you keep datetime fields in the DB you shouldn't worry about it.
As long as you keep the dates in app strongly typed (DateTime variables) and send the dates through prepared statements with DBParameter/SqlParameter your DB will take them as is.
If you use strings to hold your dates in code, some casts will ensure you send the right values:
string sqlCmd = #"SELECT *
FROM MyTable
WHERE MyDateField = CONVERT(datetime, '{0}', 101)";
// assuming myDateString is a string with a date in the local format
sqlCmd = string.Format(sqlCmd,
Convert.ToDateTime(myDateString).ToString("yyyyMMdd"));
(the code is ugly, but hopefully it gets the point across)
As others have mentioned, you should be OK as far as storing datetimes culturally. What I would recommend is that you store all of your times as standard UTC time. In SQL Server 2005 and older there is no way to store time zone information, but if everything is stored in universal time, you should be OK because the time can be converted to the local time later on.
SQL Server 2008 does have some datatypes that are aware of time zones, and if you're using .NET 3.5 there are tools to assist with time zone handling/conversions.
Definitely keep times in universal format. This will make a world of a difference if you have to work in multiple time zones.

Resources