What is the difference between TIMESTAMP
, DATE
AND TIMESTAMP with TIMEZONE
?
E.g if I wanted to search for all entries between 01-JAN-1990
and 01-JAN-2000
, how would I do so in each format?
I have been searching for timestamp as:
SELECT COUNT(*) FROM TABLE_NAME WHERE DATE BETWEEN '01-JAN-1990' AND '01-JAN-2000;
But I am not sure what format to use to search for DATE
or TIMESTAMP WITH TIMEZONE
.
Don't compare dates with strings. It can work if your session's
nls_date_format
happens to match the format of the string that you're using. But then your query will immediately fail for someone who has a different configuration. Compare dates with dates, timestamps with timestamps, etc.For dates, you can use either ANSI date literals
or you can use a
to_date
with an explicit format maskNote that a
date
in Oracle always has a day and a time component. If you don't specify a time in yourto_date
, it will default to midnight. If you use an explicitto_date
, you can use a string in any format just so long as it matches the format mask you pass in as the second parameter.For timestamps, you can either use an ANSI timestamp literal
or you can use a
to_timestamp
with an explicit format maskIf you use an explicit
to_timestamp
, you can use a string in any format just so long as it matches the format mask you pass in as the second parameter.For timestamps with time zone, as you may have guessed, you can either use an ANSI timestamp literal
or you can use the
to_timestamp_tz
function with an explicit format maskIf you use an explicit
to_timestamp_tz
, you can use a string in any format just so long as it matches the format mask you pass in as the second parameter.The data types and differences between them are in the documentation. The short version is:
You might find this article interesting too.
Whenever you are comparing datetime values stored in your database you should use values of the same datatype to compare against. You don't want to have to convert every value in the column for comparison, especially if the column is indexed. If you have a DATE column then compare with a DATE - don't compare as a string, and don't rely on implicit conversion of a string. When you do:
you are relying on your NLS_DATE_FORMAT being DD-MON-YYYY and your NLS_DATE_LANGUAGE being English. If someone else runs the same query in another session their settings may cause the query to fail (or in some cases, give wrong results, which can be worse). To avoid the language issue it's better to use month numbers rather than names. If you have a string variable to compare against you should use
TO_DATE()
to convert the string to a DATE using a fixed known format mask - don't rely on NLS. If you have a fixed value you can do the same, or you can use a date literal, which is shorter and unambiguous.With the format you used you are also including any rows which have a the column set to midnight on January 1st 2000, but not any later on that day. That may be what you want, but make sure you understand how
BETWEEN
works. If you're actually looking for dates within that decade, including at any time on December 31st 1999, you can use:For timestamps you can either use
TO_TIMESTAMP()
or a timestamp literal:For timestamps with time zones you can either use
TO_TIMESTAMP_TZ()
or a timestamp literal, with a names time zone region: