PolarDB for Oracle supports seven date/time types for calendar dates, times of day, timestamps, and time intervals. All types accept flexible input formats and support precision down to the microsecond.
Supported types
| Type | Storage | Description | Range | Resolution |
|---|---|---|---|---|
timestamp [ (p) ] [ without time zone ] | 8 bytes | Date and time, no time zone | 4713 BC – 294276 AD | 1 microsecond |
timestamp [ (p) ] with time zone | 8 bytes | Date and time, with time zone | 4713 BC – 294276 AD | 1 microsecond |
date | 4 bytes | Calendar date only | 4713 BC – 5874897 AD | 1 day |
time [ (p) ] [ without time zone ] | 8 bytes | Time of day only | 00:00:00 – 24:00:00 | 1 microsecond |
time [ (p) ] with time zone | 12 bytes | Time of day with time zone | 00:00:00+1559 – 24:00:00-1559 | 1 microsecond |
INTERVAL DAY TO SECOND [(p)] | 1 bytes | Duration from days to seconds | -178000000 – 178000000 years | 1 microsecond |
INTERVAL YEAR TO MONTH | 6 bytes | Duration from years to months | -178000000 – 178000000 years | 1 microsecond |
Type aliases:
timestampis equivalent totimestamp without time zoneper the SQL standard.timestamptzis an accepted abbreviation fortimestamp with time zone(a PostgreSQL extension).
Precision (p)
The optional precision value p specifies the number of fractional digits retained in the seconds field. It applies to time, timestamp, and interval types, and ranges from 0 to 6. By default, there is no explicit bound on precision. If no precision is specified in a constant specification, it defaults to the precision of the literal value (but not more than 6 digits).
Interval field restrictions
The interval type accepts an optional field specifier to restrict which date/time components are stored:
YEAR | MONTH | DAY | HOUR | MINUTE | SECOND
YEAR TO MONTH | DAY TO HOUR | DAY TO MINUTE | DAY TO SECOND
HOUR TO MINUTE | HOUR TO SECOND | MINUTE TO SECONDWhen both a field specifier and p are specified, the specifier must include SECOND, because precision applies only to the seconds field.
Choose a type
| Goal | Recommended type |
|---|---|
| Store a timestamp with time zone awareness | timestamp with time zone (timestamptz) |
| Store a timestamp in a fixed time zone context | timestamp without time zone |
| Store a calendar date only | date |
| Store time of day only | time without time zone |
| Store a duration in days to seconds | INTERVAL DAY TO SECOND |
| Store a duration in years to months | INTERVAL YEAR TO MONTH |
Avoid time with time zone. The SQL standard defines it, but time zone offsets have little meaning without an associated date—daylight saving time boundaries vary by date. Use date, time, timestamp without time zone, and timestamp with time zone to cover all date/time needs.
timestamp variants: timestamp without time zone stores the value as given, with no time zone conversion. timestamp with time zone stores values internally in UTC and converts them to the session time zone on display.
Date input
Date and time literals must be enclosed in single quotes. The SQL syntax is:
type [ (p) ] 'value'Date input is accepted in almost any reasonable format, including ISO 8601, SQL-compatible, and traditional PostgreSQL formats. For ambiguous formats, set the DateStyle parameter to control the interpretation order:
MDY— month/day/yearDMY— day/month/yearYMD— year/month/day
| Example | Description |
|---|---|
1999-01-08 | ISO 8601; January 8 in any mode (recommended) |
January 8, 1999 | Unambiguous in any DateStyle mode |
1/8/1999 | January 8 in MDY mode; August 1 in DMY mode |
1/18/1999 | January 18 in MDY mode; rejected in other modes |
01/02/03 | January 2, 2003 in MDY; February 1, 2003 in DMY; February 3, 2001 in YMD |
1999-Jan-08 | January 8 in any mode |
Jan-08-1999 | January 8 in any mode |
08-Jan-1999 | January 8 in any mode |
99-Jan-08 | January 8 in YMD mode; error in other modes |
08-Jan-99 | January 8; error in YMD mode |
Jan-08-99 | January 8; error in YMD mode |
19990108 | ISO 8601; January 8, 1999 in any mode |
990108 | ISO 8601; January 8, 1999 in any mode |
1999.008 | Year and day of year |
J2451187 | Julian date |
January 8, 99 BC | Year 99 BC |
Time input
time alone is equivalent to time without time zone. If a time zone is included in the input for time without time zone, it is silently ignored.
When using a time zone name that involves daylight saving time rules (such as America/New_York), specify the date as well so the engine can determine whether standard or daylight saving time applies. The resulting offset is stored as-is in a time with time zone value and is not adjusted to the active session time zone.
| Example | Description |
|---|---|
04:05:06.789 | ISO 8601 |
04:05:06 | ISO 8601 |
04:05 | ISO 8601 |
040506 | ISO 8601 |
04:05 AM | Same as 04:05; AM does not affect the stored value |
04:05 PM | Same as 16:05; input hour must be <= 12 |
04:05:06.789-8 | ISO 8601 with time zone as UTC offset |
04:05:06-08:00 | ISO 8601 with time zone as UTC offset |
04:05-08:00 | ISO 8601 with time zone as UTC offset |
040506-08 | ISO 8601 with time zone as UTC offset |
040506+0730 | ISO 8601 with fractional-hour UTC offset |
040506+07:30:00 | UTC offset specified to seconds (not allowed in ISO 8601) |
04:05:06 PST | Time zone specified by abbreviation |
2003-04-12 04:05:06 America/New_York | Time zone specified by full name |
Time zone input formats:
| Example | Description |
|---|---|
PST | Abbreviation (Pacific Standard Time) |
America/New_York | Full IANA time zone name |
PST8PDT | POSIX-style time zone specification |
-8:00:00 | UTC offset for PST |
-8:00 | UTC offset for PST (ISO 8601 extended format) |
-800 | UTC offset for PST (ISO 8601 basic format) |
-8 | UTC offset for PST (ISO 8601 basic format) |
zulu | Military abbreviation for UTC |
z | Short form of zulu (also ISO 8601) |
Timestamp input
Valid timestamp input concatenates a date and a time, followed by an optional time zone and optional AD or BC. The following are all valid:
1999-01-08 04:05:06
1999-01-08 04:05:06 -8:00
January 8 04:05:06 1999 PSTHow PostgreSQL determines the type from a literal:
PostgreSQL does not inspect the literal string content to determine its type. Both of the following are treated as timestamp without time zone:
TIMESTAMP '2004-10-19 10:23:54'
TIMESTAMP '2004-10-19 10:23:54+02' -- time zone offset is ignoredTo store a value as timestamp with time zone, specify the type explicitly:
TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'How timestamp with time zone stores values:
All timestamp with time zone values are stored internally in UTC. On input, explicit time zone offsets are converted to UTC. If no time zone is specified, the system's TimeZone parameter is assumed and the value is converted to UTC. On output, the stored UTC value is converted to the current timezone and displayed as local time.
To view a timestamp in a different time zone, either change the timezone session variable or use the AT TIME ZONE operator:
SELECT '2004-10-19 10:23:54+02'::timestamptz AT TIME ZONE 'America/New_York';Conversions between timestamp without time zone and timestamp with time zone treat the timestamp without time zone value as being in the current timezone local time. Specify a different time zone with AT TIME ZONE.
Special values
The following special input strings are recognized for date and time types. infinity and -infinity are stored as distinct internal values; the rest are shorthand notations converted to ordinary date/time values when read.
| Input string | Valid types | Description |
|---|---|---|
epoch | date, timestamp | 1970-01-01 00:00:00+00 (Unix system time zero) |
infinity | date, timestamp | Later than all other timestamps |
-infinity | date, timestamp | Earlier than all other timestamps |
now | date, time, timestamp | Current transaction's start time |
today | date, timestamp | Midnight (00:00) today |
tomorrow | date, timestamp | Midnight (00:00) tomorrow |
yesterday | date, timestamp | Midnight (00:00) yesterday |
allballs | time | 00:00:00.00 UTC |
The SQL-standard functions CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME, and LOCALTIMESTAMP return the current date or time for the corresponding type. These are SQL functions and are not recognized in data input strings.
now, today, tomorrow, and yesterday work correctly in interactive SQL, but can have surprising behavior when the command is saved to be executed later, for example in prepared statements, views, and function definitions. The string can be converted to a specific time value that continues to be used long after it becomes stale. Use SQL functions instead—for example, CURRENT_DATE + 1 is safer than 'tomorrow'::date.
Date/time output
Set the output format with the DateStyle parameter. Four styles are available; the default is ISO.
| Style | Description | Example |
|---|---|---|
ISO | ISO 8601, SQL standard (default) | 1997-12-17 07:37:16-08 |
SQL | Traditional style | 12/17/1997 07:37:16.00 PST |
Postgres | Original PostgreSQL style | Wed Dec 17 07:37:16 1997 PST |
German | Regional style | 17.12.1997 07:37:16.00 PST |
ISO 8601 specifies uppercase T between date and time. PostgreSQL accepts that on input but outputs a space instead, for readability and consistency with RFC 3339.The datestyle parameter also controls input ordering for ambiguous formats:
datestyle setting | Input ordering | Example output |
|---|---|---|
SQL, DMY | day/month/year | 17/12/1997 15:37:16.00 CET |
SQL, MDY | month/day/year | 12/17/1997 07:37:16.00 PST |
Postgres, DMY | day/month/year | Wed 17 Dec 07:37:16 1997 PST |
For more flexible formatting, use the to_char function.
Time zones
PolarDB for Oracle uses the IANA (Olson) time zone database for historical time zone rules. All timezone-aware values are stored internally in UTC and converted to the time zone specified by the TimeZone parameter before display.
Three forms are accepted when specifying a time zone:
Full time zone name — for example,
America/New_York. Recognized names are listed in thepg_timezone_namesview. Full names encode daylight saving time transition rules, so the UTC offset they represent can vary by date.Time zone abbreviation — for example,
PST. Abbreviations represent a fixed UTC offset and do not encode daylight saving time rules. Recognized abbreviations are listed in thepg_timezone_abbrevsview. You cannot use abbreviations as the value of theTimeZoneorlog_timezoneconfiguration parameters, but they are accepted in date/time input values and with theAT TIME ZONEoperator.POSIX-style specification — use this only when no suitable IANA time zone entry is available.
Abbreviations vs. full names: The difference matters when daylight saving time is in effect. For example, 2014-06-04 12:00 America/New_York and 2014-06-04 12:00 EDT both represent noon Eastern Daylight Time (UTC-4) on that date. But 2014-06-04 12:00 EST always means noon Eastern Standard Time (UTC-5), regardless of the date—so on June 4 it refers to a different instant in time.
Some jurisdictions have used the same abbreviation for different UTC offsets at different times. For example, MSK has meant UTC+3 in some years and UTC+4 in others. PostgreSQL interprets such abbreviations according to what they meant on the specified date.
Time zone names and abbreviations are recognized case-insensitively and are loaded from configuration files under .../share/timezone/ and .../share/timezonesets/.
Setting the session time zone:
-- Set time zone for the current session
SET TIME ZONE 'America/New_York';
-- Equivalent syntax
SET TIMEZONE TO 'America/New_York';The PGTZ environment variable can be set by libpq clients to send a SET TIME ZONE command automatically upon connection.
Interval input
Interval values can be written in three formats.
Verbose syntax:
[@] quantity unit [quantity unit...] [direction]quantity— a number, optionally signedunit—microsecond,millisecond,second,minute,hour,day,week,month,year,decade,century,millennium, or their abbreviations and pluralsdirection—ago(negates all fields) or emptyThe leading
@is optional
Days, hours, minutes, and seconds can be specified without unit labels. '1 12:59:10' is equivalent to '1 day 12 hours 59 min 10 sec'. A combination of years and months can be written with a dash: '200-10' is equivalent to '200 years 10 months'.
ISO 8601 format with designators:
P quantity unit [quantity unit...] [T [quantity unit...]]The string must begin with P. The T separator introduces time-of-day units. The meaning of M depends on whether it appears before or after T.
| Abbreviation | Meaning |
|---|---|
Y | Years |
M | Months (before T) |
W | Weeks |
D | Days |
H | Hours |
M | Minutes (after T) |
S | Seconds |
ISO 8601 alternative format:
P [years-months-days] [T hours:minutes:seconds]Input examples:
| Example | Description |
|---|---|
1-2 | SQL standard format: 1 year 2 months |
3 4:05:06 | SQL standard format: 3 days 4 hours 5 minutes 6 seconds |
1 year 2 months 3 days 4 hours 5 minutes 6 seconds | Traditional PostgreSQL format |
P1Y2M3DT4H5M6S | ISO 8601 format with designators |
P0001-02-03T04:05:06 | ISO 8601 alternative format |
Field specifier interaction:
When writing an interval with a field specifier, unmarked quantities are interpreted relative to the least significant field. INTERVAL '1' YEAR reads as 1 year; INTERVAL '1' reads as 1 second. Field values beyond the least significant allowed field are silently discarded: INTERVAL '1 day 2:03:04' HOUR TO MINUTE drops the seconds field but retains the day field.
Mixed-sign intervals:
According to the SQL standard, all fields of an interval must share the same sign. PostgreSQL traditionally allows fields to have different signs and treats each field as independently signed. If IntervalStyle is set to sql_standard, a leading sign is considered to apply to all fields (but only if no additional signs appear); otherwise the traditional PostgreSQL interpretation is used. To avoid ambiguity when any field is negative, attach an explicit sign to each field.
Fractional units:
Interval values support fractional input, but the internal representation uses only three integer units: months, days, and microseconds.
Fractional units larger than months are truncated to whole months:
'1.5 years'becomes'1 year 6 mons'.Fractional weeks and days are converted assuming 30 days per month and 24 hours per day:
'1.75 months'becomes1 mon 22 days 12:00:00.Only seconds are displayed as fractional on output.
This storage model can produce unexpected results when extracting components:
SELECT EXTRACT(hours FROM '80 minutes'::interval);
-- Result: 1
SELECT EXTRACT(days FROM '80 hours'::interval);
-- Result: 0Use justify_days and justify_hours to normalize days and hours that overflow their standard ranges.
Interval output
Set the interval output format with SET intervalstyle. The default is postgres.
| Style | Year-month interval | Day-time interval | Mixed interval |
|---|---|---|---|
sql_standard | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06 |
postgres | 1 year 2 mons | 3 days 04:05:06 | -1 year -2 mons +3 days -04:05:06 |
postgres_verbose | @ 1 year 2 mons | @ 3 days 4 hours 5 mins 6 secs | @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago |
iso_8601 | P1Y2M | P3DT4H5M6S | P-1Y-2M3DT-4H-5M-6S |
The sql_standard style produces SQL-standard-compliant output when the interval value is year-month only or day-time only with no mixed signs. Otherwise it outputs a year-month literal string followed by a day-time literal string with explicit signs to disambiguate.