Skip to content

Commit 5ec543c

Browse files
authored
date time: introduce the trunc and date_format_style (#2305)
1 parent b5da5e1 commit 5ec543c

File tree

6 files changed

+400
-92
lines changed

6 files changed

+400
-92
lines changed

docs/en/sql-reference/00-sql-reference/10-data-types/datetime.md

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
22
title: Date & Time
3-
description: Basic Date and Time data type.
3+
description: Databend's Date and Time data type supports standardization and compatibility with various SQL standards, making it easier for users migrating from other database systems.
44
---
55

66
import FunctionDescription from '@site/src/components/FunctionDescription';
77

8-
<FunctionDescription description="Introduced or updated: v1.2.705"/>
8+
<FunctionDescription description="Introduced or updated: v1.2.745"/>
99

1010
## Date and Time Data Types
1111

@@ -231,7 +231,45 @@ SELECT SUBTRACT_MINUTES(TO_DATE('1000-01-01'), 1);
231231

232232
## Formatting Date and Time
233233

234-
In Databend, certain date and time functions like [TO_DATE](../../20-sql-functions/05-datetime-functions/to-date.md) and [TO_TIMESTAMP](../../20-sql-functions/05-datetime-functions/to-timestamp.md) require you to specify the desired format for date and time values. To handle date and time formatting, Databend makes use of the chrono::format::strftime module, which is a standard module provided by the chrono library in Rust. This module enables precise control over the formatting of dates and times. The following content is excerpted from [https://docs.rs/chrono/latest/chrono/format/strftime/index.html](https://docs.rs/chrono/latest/chrono/format/strftime/index.html):
234+
In Databend, certain date and time functions like [TO_DATE](../../20-sql-functions/05-datetime-functions/to-date.md) and [TO_TIMESTAMP](../../20-sql-functions/05-datetime-functions/to-timestamp.md) require you to specify the desired format for date and time values.
235+
236+
### Date Format Styles
237+
238+
Databend supports two date format styles that can be selected using the `date_format_style` setting:
239+
240+
- **MySQL** (default): Uses MySQL-compatible format specifiers like `%Y`, `%m`, `%d`, etc.
241+
- **Oracle**: Uses format specifiers like `YYYY`, `MM`, `DD`, etc., which follow a standardized format to ensure compatibility with common SQL standards.
242+
243+
To switch between format styles, use the `date_format_style` setting:
244+
245+
```sql
246+
-- Set Oracle-style date format
247+
SETTINGS (date_format_style = 'Oracle') SELECT to_string('2024-04-05'::DATE, 'YYYY-MM-DD');
248+
249+
-- Set MySQL date format style (default)
250+
SETTINGS (date_format_style = 'MySQL') SELECT to_string('2024-04-05'::DATE, '%Y-%m-%d');
251+
```
252+
253+
### Week Start Configuration
254+
255+
Databend provides a `week_start` setting that defines which day is considered the first day of the week:
256+
257+
- `week_start = 1` (default): Monday is considered the first day of the week
258+
- `week_start = 0`: Sunday is considered the first day of the week
259+
260+
This setting affects week-related date functions like `DATE_TRUNC` and `TRUNC` when using `WEEK` as the precision parameter:
261+
262+
```sql
263+
-- Set Sunday as the first day of the week
264+
SETTINGS (week_start = 0) SELECT DATE_TRUNC(WEEK, to_date('2024-04-05'));
265+
266+
-- Set Monday as the first day of the week (default)
267+
SETTINGS (week_start = 1) SELECT DATE_TRUNC(WEEK, to_date('2024-04-05'));
268+
```
269+
270+
### MySQL Format Specifiers
271+
272+
To handle date and time formatting, Databend makes use of the chrono::format::strftime module, which is a standard module provided by the chrono library in Rust. This module enables precise control over the formatting of dates and times. The following content is excerpted from [https://docs.rs/chrono/latest/chrono/format/strftime/index.html](https://docs.rs/chrono/latest/chrono/format/strftime/index.html):
235273

236274
| Spec. | Example | Description |
237275
| ----- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -268,7 +306,7 @@ In Databend, certain date and time functions like [TO_DATE](../../20-sql-functio
268306
| %p | AM | AM or PM in 12-hour clocks. |
269307
| %M | 34 | Minute number (00–59), zero-padded to 2 digits. |
270308
| %S | 60 | Second number (00–60), zero-padded to 2 digits. |
271-
| %f | 026490000 | The fractional seconds (in nanoseconds) since last whole second. |
309+
| %f | 026490000 | The fractional seconds (in nanoseconds) since last whole second. Databend recommends converting the Integer string into an Integer first, other than using this specifier. See [Converting Integer to Timestamp](/sql/sql-functions/datetime-functions/to-timestamp#example-2-converting-integer-to-timestamp) for an example. |
272310
| %.f | .026490 | Similar to .%f but left-aligned. These all consume the leading dot. |
273311
| %.3f | .026 | Similar to .%f but left-aligned but fixed to a length of 3. |
274312
| %.6f | .026490 | Similar to .%f but left-aligned but fixed to a length of 6. |
@@ -334,3 +372,49 @@ It is possible to override the default padding behavior of numeric specifiers %?
334372
The typical strftime implementations have different (and locale-dependent) formats for this specifier. While Chrono's format for %+ is far more stable, it is best to avoid this specifier if you want to control the exact output.
335373

336374
- %s: This is not padded and can be negative. For the purpose of Chrono, it only accounts for non-leap seconds so it slightly differs from ISO C strftime behavior.
375+
376+
### Oracle Format Specifiers
377+
378+
When `date_format_style` is set to 'Oracle', the following format specifiers are supported:
379+
380+
| Oracle Format | Description | Example Output (for '2024-04-05 14:30:45.123456') |
381+
|---------------|----------------------------------------------|---------------------------------------------------|
382+
| YYYY | 4-digit year | 2024 |
383+
| YY | 2-digit year | 24 |
384+
| MMMM | Full month name | April |
385+
| MON | Abbreviated month name | Apr |
386+
| MM | Month number (01-12) | 04 |
387+
| DD | Day of month (01-31) | 05 |
388+
| DY | Abbreviated day name | Fri |
389+
| HH24 | Hour of day (00-23) | 14 |
390+
| HH12 | Hour of day (01-12) | 02 |
391+
| AM/PM | Meridian indicator | PM |
392+
| MI | Minute (00-59) | 30 |
393+
| SS | Second (00-59) | 45 |
394+
| FF | Fractional seconds | 123456 |
395+
| UUUU | ISO week-numbering year | 2024 |
396+
| TZH:TZM | Time zone hour and minute with colon | +08:00 |
397+
| TZH | Time zone hour | +08 |
398+
399+
Examples comparing MySQL and Oracle format styles with the same data:
400+
401+
```sql
402+
-- MySQL format style (default)
403+
SELECT to_string('2022-12-25'::DATE, '%m/%d/%Y');
404+
405+
┌────────────────────────────────┐
406+
│ to_string('2022-12-25', '%m/%d/%Y') │
407+
├────────────────────────────────┤
408+
12/25/2022
409+
└────────────────────────────────┘
410+
411+
-- Oracle format style (same data as MySQL example above)
412+
SETTINGS (date_format_style = 'Oracle')
413+
SELECT to_string('2022-12-25'::DATE, 'MM/DD/YYYY');
414+
415+
┌────────────────────────────────┐
416+
│ to_string('2022-12-25', 'MM/DD/YYYY') │
417+
├────────────────────────────────┤
418+
12/25/2022
419+
└────────────────────────────────┘
420+
```

docs/en/sql-reference/00-sql-reference/31-system-tables/system-settings.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: system.settings
33
---
44
import FunctionDescription from '@site/src/components/FunctionDescription';
55

6-
<FunctionDescription description="Introduced or updated: v1.2.466"/>
6+
<FunctionDescription description="Introduced or updated: v1.2.745"/>
77

88
Stores the system settings of the current session.
99

@@ -13,6 +13,7 @@ SELECT * FROM system.settings;
1313
name |value |default |level |description |type |
1414
--------------------------------------------+------------+------------+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+
1515
collation |binary |binary |SESSION|Sets the character collation. Available values include "binary" and "utf8". |String|
16+
date_format_style |MySQL |MySQL |SESSION|Sets the date format style for datetime functions. Available values: "MySQL" (using %Y, %m format) and "Oracle" (using YYYY, MM format for standard SQL compatibility). |String|
1617
ddl_column_type_nullable |1 |1 |SESSION|If columns are default nullable when create or alter table |UInt64|
1718
efficiently_memory_group_by |0 |0 |SESSION|Memory is used efficiently, but this may cause performance degradation. |UInt64|
1819
enable_aggregating_index_scan |1 |1 |SESSION|Enable scanning aggregating index data while querying. |UInt64|
@@ -78,4 +79,4 @@ table_lock_expire_secs |5 |5 |SESSION|S
7879
timezone |Japan |UTC |GLOBAL |Sets the timezone. |String|
7980
unquoted_ident_case_sensitive |0 |0 |SESSION|Determines whether Databend treats unquoted identifiers as case-sensitive. |UInt64|
8081
use_parquet2 |1 |1 |SESSION|Use parquet2 instead of parquet_rs when infer_schema(). |UInt64|
81-
```
82+
week_start |1 |1 |SESSION|Specifies the first day of the week (Used by week-related date functions). 0 for Sunday, 1 for Monday. |UInt64|

docs/en/sql-reference/10-sql-commands/20-query-syntax/settings.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,51 @@ SETTINGS (timezone = 'America/Toronto') SELECT timezone(), now();
6565
└──────────────────────────────────────────────┘
6666
```
6767

68+
This example demonstrates how to use the date_format_style setting to switch between MySQL and Oracle date formatting styles:
69+
70+
```sql
71+
-- Default MySQL style date formatting
72+
SELECT to_string('2024-04-05'::DATE, '%b');
73+
74+
┌────────────────────────────────┐
75+
│ to_string('2024-04-05', '%b') │
76+
├────────────────────────────────┤
77+
│ Apr │
78+
└────────────────────────────────┘
79+
80+
-- Oracle style date formatting
81+
SETTINGS (date_format_style = 'Oracle') SELECT to_string('2024-04-05'::DATE, 'MON');
82+
83+
┌────────────────────────────────┐
84+
│ to_string('2024-04-05', 'MON') │
85+
├────────────────────────────────┤
86+
│ Apr │
87+
└────────────────────────────────┘
88+
```
89+
90+
This example shows how the week_start setting affects week-related date functions:
91+
92+
```sql
93+
-- Default week_start = 1 (Monday as first day of week)
94+
SELECT date_trunc(WEEK, to_date('2024-04-03')); -- Wednesday
95+
96+
┌────────────────────────────────────────┐
97+
│ date_trunc(WEEK, to_date('2024-04-03')) │
98+
├────────────────────────────────────────┤
99+
2024-04-01
100+
└────────────────────────────────────────┘
101+
102+
-- Setting week_start = 0 (Sunday as first day of week)
103+
SETTINGS (week_start = 0) SELECT date_trunc(WEEK, to_date('2024-04-03')); -- Wednesday
104+
105+
┌────────────────────────────────────────┐
106+
│ date_trunc(WEEK, to_date('2024-04-03')) │
107+
├────────────────────────────────────────┤
108+
2024-03-31
109+
└────────────────────────────────────────┘
110+
```
111+
68112
This example allows the COPY INTO operation to utilize up to 100 threads for parallel processing:
69113

70114
```sql
71-
SETTINGS (max_threads = 100) COPY INTO ...
72-
```
115+
SETTINGS (max_threads = 100) COPY INTO ...

0 commit comments

Comments
 (0)