Developing Time-Oriented Applications in SQL | Richard T. Snodgrass |
This document outlines temporal data type support for the Sybase DBMS, as described in Chapters 2 & 3. It follows the general outline of the TDB book and is arranged in the following manner.
While SQL-92 supplies six temporal types, Sybase, supplies just two, datetime and smalldatetime, which is similar to SQL-92's TIMESTAMP type. A Sybase datetime comprises of the month, the day of the month, the year, the hour, the minute, the second, and the AM/PM specifier.
The following are mentioned at the standard Sybase reference web page :
datetime columns hold dates between January 1, 1753 and December 31, 9999. datetime values are accurate to 1/300th of a second on platforms that support this level of granularity. Storage size is 8 bytes: 4 bytes for the number of days since the base date of January 1, 1900 and 4 bytes for the time of day.
smalldatetime columns hold dates from January 1, 1900 to June 6, 2079, with accuracy to the minute. Storage size is 4 bytes: 2 bytes for the number of days after January 1, 1900, and 2 bytes for the number of minutes since midnight.
The default way to enter dates is Mmm dd yyyy hh:mm:ss AM/PM, though there are several different ways, either numeric or alphanumeric, as well as different orders, depending on the language; you get use set_language to change the ordering of the default datetime, ie if it's a European language, Day comes before Month. For the different date display types, refer to the standard web page .
The predicates that Sybase supports on datetime are '=', '<', '<', '<=', '>=', and '<>', '!=' for not equals.
Sybase datetime and smalldatetime can be converted to char and varchar implicitly, and from date and smalldate time implicitly. This allows comparisons of the type Birthday="Sep 15 1976". The format of the string must much one of the several formats (called 'styles' in the standard web page). Some of them are dd-mm-yy (style 5 if not including the century, style 105 if including it), dd.mm.yy and so on. Please note that if you provide a datetime without a century, Sybase will store 19 if the year is >= 50, and 20 if the year is <50. for example, entering 97 will yield a default of 1997.
Sybase datetimes can be converted to character strings explicitly (char and varchar), using the convert function. For example, select convert(char(12), getdate(), 3) converts the current date to style "3", dd/mm/yy . For other possible conversions and for the full syntax of convert, refer to this page.
At this point, let's mention the system provided date functions of Sybase. The following extract is from the following web page: http://sybooks.sybase.com:80/dynaweb/group5/srv10024/ref/48491.
All date functions except getdate take arguments. Function names, arguments, and results are listed in the following table.
Function | Argument | Result |
---|---|---|
getdate | () | Returns the current system date and time. |
datename | ( datepart , date ) | Returns the name of the specified part (such as the month "June") of a datetime value, as a character string. If the result is numeric, such as "23" for the day, it is still returned as a character string. |
datepart | ( datepart , date ) | Returns an integer value for the specified part of a datetime value. |
datediff | ( datepart , date1 , date2 ) | Returns date2 - date1 , measured in the specified date part. |
dateadd | ( datepart , numeric_expression , date ) | Returns the date produced by adding the specified number of the specified date parts to the date . numeric_expression can be any numeric type; the value is truncated to an integer. |
The following table lists the date parts, the abbreviations recognized by SQL Server, and the acceptable values.
Date Part | Abbreviation | Values |
---|---|---|
year | yy | 1753 - 9999 (2079 for smalldatetime ) |
quarter | 1 - 4 | |
month | mm | 1 - 12 |
week | wk | 1 - 54 |
day | dd | 1 - 31 |
dayofyear | dy | 1 - 366 |
weekday | dw | 1 - 7 (Sun.-Sat.) |
hour | hh | 0 - 23 |
minute | mi | 0 - 59 |
second | ss | 0 - 59 |
millisecond | ms | 0 - 999 |
If the year is given with two digits, <50 is the next century ("25" is "2025") and >=50 is this century ("50" is "1950"). Milliseconds can be preceded either with a colon or a period. If preceded by a colon, the number means thousandths of a second. If preceded by a period, a single digit means tenths of a second, two digits mean hundredths of a second, and three digits mean thousandths of a second. For example, "12:30:20:1" means twenty and one-thousandth of a second past 12:30; "12:30:20.1" means twenty and one-tenth of a second past 12:30. date - an argument used with dateadd , datediff , datename , and datepart . The date can be either the function getdate , a character string in one of the acceptable date formats , an expression that evaluates to a valid date format, or the name of a datetime column.
For a complete explanation of these functions refer to the above web page.
Sybase does not have an interval datatype. We can simulate an interval by using an integer, so a 3 month interval would be the integer 3, and so would a 3 minute or a 3 second interval be. We can extract dateparts from dates using the function datepart, as discussed above and as shown in the examples, which returns an integer. It would be up to the user to create an additional column, called interval type, if (s)he wished to keep that information as well. Thus in the above tables, i stands for integer, with no "interval type" associated with it.
SQL-92 |
Sybase Equivalent
|
Types: | |
DATE | datetime, ignoring the hour, minute, and second fields |
TIME | datetime, ignoring the century, year, month, and day fields |
TIMESTAMP | datetime (to second granularity) |
TIME WITH TIME ZONE | No equivalent |
TIMESTAMP WITH TIME ZONE | No equivalent |
INTERVAL YEAR TO MONTH | Can be simulated by int |
INTERVAL DAY TO SECOND | Can be simulated by int |
Literals: | |
DATE '1991-01-01' | convert(datetime,"1997-01-01", 105) |
TIME '12:34:56' | convert(datetime,"12:34:56") |
TIMESTAMP '1997-01-01 12:34:56' | convert(datetime,"1997-01-01 12:34:56", 105) |
INTERVAL '3-4' YEAR TO MONTH | 40 (months-- an integer) |
INTERVAL '1 23:45:12' DAY TO SECOND | 171812 (seconds-- an integer) |
Predicates: | |
d1 = d2 | d1 = d2 |
d1 < d2 | d1 < d2 |
d1 <> d2 | d1 <> d2 |
d1 BETWEEN d2 AND d3 | d1 > d2 AND d1 < d3 |
i1 = i2 | i1 = i2 |
i1 < i2 | i1 < i2 |
i1 <> i2 | i1 <> i2 |
i1 BETWEEN i2 AND i3 | i1 > i2 AND i1 < i3 |
d = NULL | d = NULL |
i = NULL | i = NULL |
(d1, i2) OVERLAPS (d3, d4) | d1 <= d4 AND d3 <= dateadd (i2 , d1) |
Datetime Constructors: | |
d + i | dateadd (datepart,n,d) |
i + d | dateadd (datepart,n,d) |
d - i | dateadd (datepart,-n,d) |
d AT i | Not supported |
d AT LOCAL | Not supported |
CURRENT_DATE | Get each datepart using name (yields a string), concatenate them, and convert back to a datetime (or just print out the string value) |
CURRENT_TIME | Get each datepart using name (yields a string), concatenate them, and convert back to a datetime (or just print out the string value) |
CURRENT_TIMESTAMP | getdate() |
Internal Constructors: | |
i1 + i2 | i1 + i2 |
i1 - i2 | i1 - i2 |
d1 - d2 qual | datediff(datepart,d1,d2) |
d1 - d2 INTERVAL MONTH | datediff(month,d2, d1) |
i * n | i * n |
n * i | n * i |
i / i | i / i |
+ i | + i |
- i | - i |
Other Operators: | |
CAST(d AS DATE) | Convert to a datetime using the correct style (d has to be a string value; if it is not, then get each datepart- these are strings - and concatenate them) |
CAST(d AS TIME) | convert as above obtaining the appropriate time fields using datename |
CAST(d AS TIMESTAMP) (where d is a DATE) | d |
CAST(d AS TIMESTAMP) (where d is a TIME) | Get the year, month, day dateparts from the current timestamp, using getdate(), and concatenate them with d, the time- d has to be a string. Then convert back to a datetime. |
CAST(i AS INTERVAL YEAR TO MONTH) | Not possible |
CAST(i AS INTERVAL DAY TO SECOND) | Not possible |
CAST(d AS CHAR) | convert(char,d) |
CAST(i AS CHAR) | convert(char,i) |
CAST(i AS INTEGER) (where i is a DAY) | i is an integer |
CAST(i AS INTEGER) (where i is a HOUR) | i is an integer |
CAST(i AS INTEGER) (where i is a MINUTE) | i is an integer |
CAST(i AS INTEGER) (where i is a SECOND) | i is an integer |
EXTRACT(DAY from d) | datename(day,d) (returns a string) |
EXTRACT(DAY from i) | convert(int, i/86400) |
EXTRACT(HOUR from i) | convert(int, i/3600) |
Operators not in SQL-92: | |
Convert d to Julian day | Not possible |
Convert Julian day n to DATE | Not possible |
Pick the earliest date | No direct equivalent |
Pick the latest date | No direct equivalent |
Pick the last day of the month | No direct equivalent |
Get the next day of the week | No direct equivalent |
SQL-92 |
Sybase Equivalent
|
Types: | |
period | (datetime, datetime) |
Predicates: | |
p equals q | p1 = q1 AND p2 = q2 |
p before q | p2 < q1 |
p before-1 q | q2 < p1 |
p meets q | p2 = q1 |
p meets-1 q | q2 = p1 |
p overlaps q | q1 < p2 < q2 AND p1 < q1 |
p overlaps-1 q | p1 < q2 < p2 AND q1 < p1 |
p during q | q1 < p1 AND p2 < q2 |
p during-1 q | p1 < q1 AND q2 < p2 |
p starts q | p1 = q1 AND p2 < q2 |
p starts-1 q | q1 = p1 AND q2 < p2 |
p finishes q | p2 = q2 AND p1 > q1 |
p finishes-1 q | q2 = p2 AND q1 > p1 |
p OVERLAPS q | p1 < q2 AND q1 < p2 |
p IS NULL | p1 = NULL |
Datetime Constructors: | |
beginning(p) | p1 |
previous(p) | dateadd(datepart,-1,p1) |
last(p) | dateadd(datepart,-1,p2) |
ending(p) | p2 |
Interval Constructors: | |
duration(p) | p2-p1 |
extract_time_zone(p) | not supported |
Period Constructors: | |
p + i | [dateadd(datepart,i,p1) , dateadd(datepart,i,p2) ) |
i + p | Same as above |
p - i | [dateadd(datepart,-i,p1) , dateadd(datepart,-i,p2) ) |
a extend b | Not supported |
p extend q | Not supported |
p extend a | Not supported |
a extend p | Not supported |
p INTERSECT q | Not supported |
p - q | Not supported |
p UNION q | Not supported |
p AT TIME ZONE i | Not supported |
p AT LOCAL | Not supported |
Other Operators: | |
CAST(a AS PERIOD) | [a, dateadd(day,1,a) ) |
CAST(p AS CHAR) | Converting of p1 and p2 separately is supported |
Christopher Cooper, Department of Computer Science,
University of Arizona (ccooper@cs.arizona.edu)
Rachana Shah, Department of Computer Science, University
of Arizona (rachana@cs.arizona.edu)
Jian Yang, Department of Computer Science, University of
Arizona (yangjian@cs.arizona.edu)
April 27, 1999(Last Update)
Miltos Vafiadis, Department of Computer Science,
University of Arizona (mvafiadi@cs.arizona.edu)
December 11, 1997 (Last Update)