From f434149960fce2efd3a6027b8cd6448fd4fa08d5 Mon Sep 17 00:00:00 2001
From: Natalie <nat@metabase.com>
Date: Mon, 14 Nov 2022 15:16:50 -0500
Subject: [PATCH] docs - datetimeAdd and datetimeSubtract (#26431)

---
 .../query-builder/expressions-list.md         |   8 +-
 .../query-builder/expressions/concat.md       |   2 +-
 .../query-builder/expressions/datetimeadd.md  | 149 ++++++++++++++++++
 .../expressions/datetimesubtract.md           | 149 ++++++++++++++++++
 .../query-builder/expressions/regexextract.md |   2 +-
 .../query-builder/expressions/substring.md    |   2 +-
 6 files changed, 305 insertions(+), 7 deletions(-)
 create mode 100644 docs/questions/query-builder/expressions/datetimeadd.md
 create mode 100644 docs/questions/query-builder/expressions/datetimesubtract.md

diff --git a/docs/questions/query-builder/expressions-list.md b/docs/questions/query-builder/expressions-list.md
index 43d9795e952..7b7453c22db 100644
--- a/docs/questions/query-builder/expressions-list.md
+++ b/docs/questions/query-builder/expressions-list.md
@@ -32,8 +32,8 @@ For an introduction to expressions, check out [Writing expressions in the notebo
   - [coalesce](./expressions/coalesce.md)
   - [concat](./expressions/concat.md)
   - [contains](#contains)
-  - [datetimeAdd](#datetimeadd)
-  - [datetimeSubtract](#datetimesubtract)
+  - [datetimeAdd](./expressions/datetimeadd.md)
+  - [datetimeSubtract](./expressions/datetimesubtract.md)
   - [day](#day)
   - [endswith](#endswith)
   - [exp](#exp)
@@ -268,7 +268,7 @@ Example: `contains([Status], "Class")`. If `Status` were "Classified", the expre
 
 Related: [regexextract](#regexextract).
 
-### datetimeAdd
+### [datetimeAdd](./expressions/datetimeadd.md)
 
 Adds some unit of time to a date or timestamp value.
 
@@ -280,7 +280,7 @@ Syntax: `datetimeAdd(column, amount, unit)`.
 
 Example: `datetimeAdd("March 25, 2021, 12:52:37", 1, "month")` would return `April 25, 2021, 12:52:37`.
 
-### datetimeSubtract
+### [datetimeSubtract](./expressions/datetimesubtract.md)
 
 Subtracts some unit of time from a date or timestamp value.
 
diff --git a/docs/questions/query-builder/expressions/concat.md b/docs/questions/query-builder/expressions/concat.md
index 865795e4a51..3e8e98d0ad8 100644
--- a/docs/questions/query-builder/expressions/concat.md
+++ b/docs/questions/query-builder/expressions/concat.md
@@ -93,4 +93,4 @@ concat([City], ", ", [Country])
 ## Further reading
 
 - [Custom expressions documentation](../expressions.md)
-- [Custom expressions tutorial](https://www.metabase.com/learn/questions/)
\ No newline at end of file
+- [Custom expressions tutorial](https://www.metabase.com/learn/questions/custom-expressions)
\ No newline at end of file
diff --git a/docs/questions/query-builder/expressions/datetimeadd.md b/docs/questions/query-builder/expressions/datetimeadd.md
new file mode 100644
index 00000000000..9ac5206c9e0
--- /dev/null
+++ b/docs/questions/query-builder/expressions/datetimeadd.md
@@ -0,0 +1,149 @@
+---
+title: DatetimeAdd
+---
+
+# DatetimeAdd
+
+`datetimeAdd` takes a datetime value and adds some unit of time to it. This function is useful when you're working with time series data that's marked by a "start" and an "end", such as sessions or subscriptions data.
+
+| Syntax                                                                              | Example                                              |
+|-------------------------------------------------------------------------------------|------------------------------------------------------|
+| `datetimeAdd(column, amount, unit)`                                                 | `datetimeAdd("March 25, 2021, 12:52:37", 1, "month")`|
+| Takes a timestamp or date value and adds the specified number of time units to it.  | `April 25, 2021, 12:52:37`                           |
+
+## Parameters
+
+- Units can be any of: "year", "quarter", "month", "day", "hour", "second", or "millisecond".
+- Amounts can be negative: `datetimeAdd("March 25, 2021, 12:52:37", -1, "month")` will return `February 25, 2021, 12:52:37`.
+
+## Calculating an end date
+
+Let's say you're a coffee connoisseur, and you want to keep track of the freshness of your beans:
+
+| Coffee                 | Opened On  | Finish By  |
+|------------------------|------------|------------|
+| DAK Honey Dude         | 2022-10-31 | 2022-11-14 |
+| NO6 Full City Espresso | 2022-11-07 | 2022-11-21 |
+| Ghost Roaster Giakanja | 2022-11-27 | 2022-12-11 |
+
+Here, **Finish By** is a custom column with the expression:
+
+```
+datetimeAdd([Opened On], 14, 'day')
+```
+
+You can use the [`between`](../expressions-list.md#between) or [`interval`](../expressions-list.md#interval) expressions to check if a given date falls between your start and end datetimes.
+
+## Accepted data types
+
+| [Data type](https://www.metabase.com/learn/databases/data-types-overview#examples-of-data-types) | Works with `datetimeAdd`  |
+| ----------------------- | -------------------- |
+| String                  | ❌                   |
+| Number                  | ❌                   |
+| Timestamp               | ✅                   |
+| Boolean                 | ❌                   |
+| JSON                    | ❌                   |
+
+This table uses `timestamp` and `datetime` interchangeably---just make sure that your dates and times aren't stored as string or a number data types in your database.
+
+## Limitations
+
+You can use `datetimeAdd` to _calculate_ relative dates given a column of date values, but unfortunately Metabase doesn't currently let you _generate_ a relative date (such as today's date).
+
+For example, if you want to check if today's date falls between **Opened On** and **Finish By** in the [Coffee example](#calculating-an-end-date):
+
+- Ask your database admin if there's table in your database that stores dates for reporting (sometimes called a date dimension table).
+- Create a new question using the date dimension table, with a filter for "Today".
+- Turn the "Today" question into a model.
+- Create a left join between **Coffee** and the "Today" model on `[Opened On] <= [Today]` and `[Finish By] >= [Today]`.
+
+The result should give you a **Today** column that's non-empty if today's date falls inside the coffee freshness window:
+
+| Coffee                 | Opened On  | Finish By  | Today      | 
+|------------------------|------------|------------|------------|
+| DAK Honey Dude         | 2022-10-31 | 2022-11-14 | 2022-11-10 |
+| NO6 Full City Espresso | 2022-11-07 | 2022-11-21 | 2022-11-10 |
+| Ghost Roaster Giakanja | 2022-11-27 | 2022-12-11 |            |
+
+## Related functions
+
+This section covers functions and formulas that work the same way as the Metabase `datetimeAdd` expression, with notes on how to choose the best option for your use case.
+
+**[Metabase expressions](../expressions-list.md)**
+
+- [datetimeSubtract](#datetimesubtract)
+
+**Other tools**
+
+- [SQL](#sql)
+- [Spreadsheets](#spreadsheets)
+- [Python](#python)
+
+### datetimeSubtract
+
+`datetimeSubtract` and `datetimeAdd` are interchangeable, since you can use a negative number for `amount`. It's generally a good idea to avoid double negatives (such as subtracting a negative number).
+
+```
+datetimeSubtract([Opened On], -14, "day")
+```
+
+does the same thing as
+
+```
+datetimeAdd([Opened On], 14, 'day')
+```
+
+### SQL
+
+When you run a question using the [query_builder](https://www.metabase.com/glossary/query_builder), Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results.
+
+If our [coffee sample data](#calculating-an-end-date) is stored in a PostgreSQL database:
+
+```sql
+SELECT opened_on + INTERVAL '14 days' AS finish_by
+FROM coffee
+```
+
+is equivalent to the Metabase `datetimeAdd` expression:
+
+```
+datetimeAdd([Opened On], 14, 'day')
+```
+
+### Spreadsheets
+
+If our [coffee sample data](#calculating-an-end-date) is in a spreadsheet where "Opened On" is in column A with a date format, the spreadsheet function
+
+```
+A:A + 14
+```
+
+produces the same result as
+
+```
+datetimeAdd([Opened On], 14, 'day')
+```
+
+Most spreadsheet tools require use different functions for different time units (for example, you'd use a different function to add "months" to a date). `datetimeAdd` makes it easy for you to convert all of those functions to a single consistent syntax.
+
+### Python
+
+Assuming the [coffee sample data](#calculating-an-end-date) is in a `pandas` dataframe column called `df`, you can import the `datetime` module and use the `timedelta` function:
+
+```
+df['Finish By'] = df['Opened On'] + datetime.timedelta(days=14)
+```
+
+is equivalent to
+
+```
+datetimeAdd([Opened On], 14, 'day')
+```
+
+## Further reading
+
+- [Custom expressions documentation](../expressions.md)
+- [Custom expressions tutorial](https://www.metabase.com/learn/questions/custom-expressions)
+- [Time series comparisons](https://www.metabase.com/learn/questions/time-series-comparisons)
+- [How to compare one time period to another](https://www.metabase.com/learn/dashboards/compare-times)
+- [Working with dates in SQL](https://www.metabase.com/learn/sql-questions/dates-in-sql)
diff --git a/docs/questions/query-builder/expressions/datetimesubtract.md b/docs/questions/query-builder/expressions/datetimesubtract.md
new file mode 100644
index 00000000000..6e23feac7e8
--- /dev/null
+++ b/docs/questions/query-builder/expressions/datetimesubtract.md
@@ -0,0 +1,149 @@
+---
+title: DatetimeSubtract
+---
+
+# DatetimeSubtract
+
+`datetimeSubtract` takes a datetime value and subtracts some unit of time from it. You might want to use this function when working with time series data that's marked by a "start" and an "end", such as sessions or subscriptions data.
+
+| Syntax                                                                                    | Example                                                   |
+|-------------------------------------------------------------------------------------------|-----------------------------------------------------------|
+| `datetimeSubtract(column, amount, unit)`                                                  | `datetimeSubtract("March 25, 2021, 12:52:37", 1, "month")`|
+| Takes a timestamp or date value and subtracts the specified number of time units from it. | `February 25, 2021, 12:52:37`                             |
+
+## Parameters
+
+- Units can be any of: "year", "quarter", "month", "day", "hour", "second", or "millisecond".
+- Amounts can be negative: `datetimeSubtract("March 25, 2021, 12:52:37", -1, "month")` will return `April 25, 2021, 12:52:37`.
+
+## Calculating a start date
+
+Let's say you're planning a fun night out. You know it takes 30 minutes to get from place to place, and you need to figure out what time you have to leave to get to each of your reservations:
+
+| Event   | Arrive By           | Depart At           |
+|---------|---------------------|---------------------|
+| Drinks  | 2022-11-12 18:30:00 | 2022-11-12 18:00:00 |
+| Dinner  | 2022-11-12 20:00:00 | 2022-11-12 19:30:00 |
+| Dancing | 2022-11-13 00:00:00 | 2022-11-12 23:30:00 |
+
+Here, **Depart At** is a custom column with the expression:
+
+```
+datetimeSubtract([Arrive By], 30, "minute")
+```
+
+You can use the [`between`](../expressions-list.md#between) or [`interval`](../expressions-list.md#interval) expressions to check if a given date falls between your start and end datetimes.
+
+## Accepted data types
+
+| [Data type](https://www.metabase.com/learn/databases/data-types-overview#examples-of-data-types) | Works with `datetimeSubtract`  |
+| ----------------------- | -------------------- |
+| String                  | ❌                   |
+| Number                  | ❌                   |
+| Timestamp               | ✅                   |
+| Boolean                 | ❌                   |
+| JSON                    | ❌                   |
+
+This table uses `timestamp` and `datetime` interchangeably---just make sure that your dates and times aren't stored as string or a number data types in your database.
+
+## Limitations
+
+You can use `datetimeSubtract` to calculate relative dates given a column of date values, but unfortunately Metabase doesn't currently let you _generate_ a relative date (such as today's date).
+
+What if you want to check if today's date falls between **Arrive By** and **Depart At** in our [events example](#calculating-a-start-date)?
+
+1. Ask your database admin if there's table in your database that stores datetimes for reporting (sometimes called a date dimension table).
+2. Create a new question using the date dimension table, with a filter for "Today".
+3. Turn the "Today" question into a model.
+4. Create a left join between **Events** and the "Today" model on `[Arrive By] <= [Today]` and `[Depart At] >= [Today]`.
+
+The result should give you an **Today** column that's non-empty for events that are happening while the night is still young:
+
+| Event   | Arrive By           | Depart At           | Today               |
+|---------|---------------------|---------------------|---------------------|
+| Drinks  | 2022-11-12 18:30:00 | 2022-11-12 18:00:00 | 2022-11-12 00:00:00 |
+| Dinner  | 2022-11-12 20:00:00 | 2022-11-12 19:30:00 | 2022-11-12 00:00:00 |
+| Dancing | 2022-11-13 00:00:00 | 2022-11-12 23:30:00 |                     |
+
+## Related functions
+
+This section covers functions and formulas that work the same way as the Metabase `datetimeSubtract` expression, with notes on how to choose the best option for your use case.
+
+**[Metabase expressions](../expressions-list.md)**
+
+- [datetimeAdd](#datetimeadd)
+
+**Other tools**
+
+- [SQL](#sql)
+- [Spreadsheets](#spreadsheets)
+- [Python](#python)
+
+### datetimeAdd
+
+`datetimeSubtract` and `datetimeAdd` are interchangeable, since you can use a negative number for `amount`. We could use either expression for our [events example](#calculating-a-start-date), but you should try to avoid "double negatives" (such as subtracting a negative number).
+
+```
+datetimeAdd([Arrive By], -30, "minute")
+```
+
+does the same thing as
+
+```
+datetimeSubtract([Arrive By], 30, "minute")
+```
+
+### SQL
+
+When you run a question using the [query builder](https://www.metabase.com/glossary/query_builder), Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results.
+
+If our [events sample data](#calculating-a-start-date) is stored in a PostgreSQL database:
+
+```sql
+SELECT arrive_by - INTERVAL '30 minutes' AS depart_at
+FROM events
+```
+
+is equivalent to the Metabase `datetimeSubtract` expression:
+
+```
+datetimeSubtract([Arrive By], 30, "minute")
+```
+
+### Spreadsheets 
+
+Assuming the [events sample data](#calculating-a-start-date) is in a spreadsheet where "Arrive By" is in column A with a datetime format, the spreadsheet function
+
+```
+A:A - 30/(60*24)
+```
+
+produces the same result as
+
+```
+datetimeSubtract([Arrive By], 30, "minute")
+```
+
+Most spreadsheets require you to use different calculations for different time units (for example, you'd need to use a different calculation to subtract "days" from a date). `datetimeSubtract` makes it easy for you to convert all of those functions to a single consistent syntax.
+
+### Python
+
+If our [events sample data](#calculating-a-start-date) is in a `pandas` dataframe column called `df`, you can import the `datetime` module and use the `timedelta` function:
+
+```
+df['Depart At'] = df['Arrive By'] - datetime.timedelta(minutes=30)
+```
+
+is equivalent to
+
+```
+datetimeSubtract([Arrive By], 30, "minute")
+```
+
+## Further reading
+
+- [Custom expressions documentation](../expressions.md)
+- [Custom expressions tutorial](https://www.metabase.com/learn/questions/custom-expressions)
+- [Time series comparisons](https://www.metabase.com/learn/questions/time-series-comparisons)
+- [How to compare one time period to another](https://www.metabase.com/learn/dashboards/compare-times)
+- [Working with dates in SQL](https://www.metabase.com/learn/sql-questions/dates-in-sql)
\ No newline at end of file
diff --git a/docs/questions/query-builder/expressions/regexextract.md b/docs/questions/query-builder/expressions/regexextract.md
index 93085331781..bfab1d90d13 100644
--- a/docs/questions/query-builder/expressions/regexextract.md
+++ b/docs/questions/query-builder/expressions/regexextract.md
@@ -137,4 +137,4 @@ regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")
 ## Further reading
 
 - [Custom expressions documentation](../expressions.md)
-- [Custom expressions tutorial](https://www.metabase.com/learn/questions/)
+- [Custom expressions tutorial](https://www.metabase.com/learn/questions/custom-expressions)
diff --git a/docs/questions/query-builder/expressions/substring.md b/docs/questions/query-builder/expressions/substring.md
index efb5f43e8d6..be8b2ce135b 100644
--- a/docs/questions/query-builder/expressions/substring.md
+++ b/docs/questions/query-builder/expressions/substring.md
@@ -149,4 +149,4 @@ substring([Mission ID], 9, 3)
 ## Further reading
 
 - [Custom expressions documentation](../expressions.md)
-- [Custom expressions tutorial](https://www.metabase.com/learn/questions/)
+- [Custom expressions tutorial](https://www.metabase.com/learn/questions/custom-expressions)
-- 
GitLab