Skip to content

Commit 5cd6509

Browse files
authored
feat(firestore): add timestamp expressions (#9728)
* Add timestampTrunc, timestampDiff and timestampExtract expressions * Add changeset * Fix formatting * Fix variable names to follow camelCase * Generate documentation * Fix the int64 documentation error * Fix formatting * Add a test for isoWeek for timestampTruncate
1 parent 44ad4cc commit 5cd6509

12 files changed

Lines changed: 1547 additions & 12 deletions

File tree

.changeset/cool-dragons-compete.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'firebase': minor
3+
'@firebase/firestore': minor
4+
---
5+
6+
Add support for timestamp_trunc, timestamp_diff and timestamp_extract expressions

common/api-review/firestore-lite-pipelines.api.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,14 @@ export abstract class Expression {
764764
/* Excluded from this release type: _readUserData */
765765
timestampAdd(unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression;
766766
/* Excluded from this release type: _readUserData */
767+
timestampDiff(start: Expression, unit: Expression): FunctionExpression;
768+
/* Excluded from this release type: _readUserData */
769+
timestampDiff(start: string | Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day'): FunctionExpression;
770+
/* Excluded from this release type: _readUserData */
771+
timestampExtract(part: TimePart, timezone?: string | Expression): FunctionExpression;
772+
/* Excluded from this release type: _readUserData */
773+
timestampExtract(part: Expression, timezone?: string | Expression): FunctionExpression;
774+
/* Excluded from this release type: _readUserData */
767775
timestampSubtract(unit: Expression, amount: Expression): FunctionExpression;
768776
/* Excluded from this release type: _readUserData */
769777
timestampSubtract(unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression;
@@ -1481,6 +1489,9 @@ export function switchOn(condition: BooleanExpression, result: Expression, ...ot
14811489
// @beta
14821490
export type TimeGranularity = 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'week(monday)' | 'week(tuesday)' | 'week(wednesday)' | 'week(thursday)' | 'week(friday)' | 'week(saturday)' | 'week(sunday)' | 'isoWeek' | 'month' | 'quarter' | 'year' | 'isoYear';
14831491

1492+
// @beta
1493+
export type TimePart = TimeGranularity | 'dayofweek' | 'dayofyear';
1494+
14841495
// @beta
14851496
export function timestampAdd(timestamp: Expression, unit: Expression, amount: Expression): FunctionExpression;
14861497

@@ -1490,6 +1501,30 @@ export function timestampAdd(timestamp: Expression, unit: 'microsecond' | 'milli
14901501
// @beta
14911502
export function timestampAdd(fieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression;
14921503

1504+
// @beta
1505+
export function timestampDiff(endFieldName: string, startFieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression;
1506+
1507+
// @beta
1508+
export function timestampDiff(endFieldName: string, startExpression: Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression;
1509+
1510+
// @beta
1511+
export function timestampDiff(endExpression: Expression, startFieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression;
1512+
1513+
// @beta
1514+
export function timestampDiff(endExpression: Expression, startExpression: Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression;
1515+
1516+
// @beta
1517+
export function timestampExtract(fieldName: string, part: TimePart, timezone?: string | Expression): FunctionExpression;
1518+
1519+
// @beta
1520+
export function timestampExtract(fieldName: string, part: Expression, timezone?: string | Expression): FunctionExpression;
1521+
1522+
// @beta
1523+
export function timestampExtract(timestampExpression: Expression, part: TimePart, timezone?: string | Expression): FunctionExpression;
1524+
1525+
// @beta
1526+
export function timestampExtract(timestampExpression: Expression, part: Expression, timezone?: string | Expression): FunctionExpression;
1527+
14931528
// @beta
14941529
export function timestampSubtract(timestamp: Expression, unit: Expression, amount: Expression): FunctionExpression;
14951530

common/api-review/firestore-pipelines.api.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,14 @@ export abstract class Expression {
767767
/* Excluded from this release type: _readUserData */
768768
timestampAdd(unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression;
769769
/* Excluded from this release type: _readUserData */
770+
timestampDiff(start: Expression, unit: Expression): FunctionExpression;
771+
/* Excluded from this release type: _readUserData */
772+
timestampDiff(start: string | Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day'): FunctionExpression;
773+
/* Excluded from this release type: _readUserData */
774+
timestampExtract(part: TimePart, timezone?: string | Expression): FunctionExpression;
775+
/* Excluded from this release type: _readUserData */
776+
timestampExtract(part: Expression, timezone?: string | Expression): FunctionExpression;
777+
/* Excluded from this release type: _readUserData */
770778
timestampSubtract(unit: Expression, amount: Expression): FunctionExpression;
771779
/* Excluded from this release type: _readUserData */
772780
timestampSubtract(unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression;
@@ -1523,6 +1531,9 @@ export function switchOn(condition: BooleanExpression, result: Expression, ...ot
15231531
// @beta
15241532
export type TimeGranularity = 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'week(monday)' | 'week(tuesday)' | 'week(wednesday)' | 'week(thursday)' | 'week(friday)' | 'week(saturday)' | 'week(sunday)' | 'isoWeek' | 'month' | 'quarter' | 'year' | 'isoYear';
15251533

1534+
// @beta
1535+
export type TimePart = TimeGranularity | 'dayofweek' | 'dayofyear';
1536+
15261537
// @beta
15271538
export function timestampAdd(timestamp: Expression, unit: Expression, amount: Expression): FunctionExpression;
15281539

@@ -1532,6 +1543,30 @@ export function timestampAdd(timestamp: Expression, unit: 'microsecond' | 'milli
15321543
// @beta
15331544
export function timestampAdd(fieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression;
15341545

1546+
// @beta
1547+
export function timestampDiff(endFieldName: string, startFieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression;
1548+
1549+
// @beta
1550+
export function timestampDiff(endFieldName: string, startExpression: Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression;
1551+
1552+
// @beta
1553+
export function timestampDiff(endExpression: Expression, startFieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression;
1554+
1555+
// @beta
1556+
export function timestampDiff(endExpression: Expression, startExpression: Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression;
1557+
1558+
// @beta
1559+
export function timestampExtract(fieldName: string, part: TimePart, timezone?: string | Expression): FunctionExpression;
1560+
1561+
// @beta
1562+
export function timestampExtract(fieldName: string, part: Expression, timezone?: string | Expression): FunctionExpression;
1563+
1564+
// @beta
1565+
export function timestampExtract(timestampExpression: Expression, part: TimePart, timezone?: string | Expression): FunctionExpression;
1566+
1567+
// @beta
1568+
export function timestampExtract(timestampExpression: Expression, part: Expression, timezone?: string | Expression): FunctionExpression;
1569+
15351570
// @beta
15361571
export function timestampSubtract(timestamp: Expression, unit: Expression, amount: Expression): FunctionExpression;
15371572

docs-devsite/firestore_lite_pipelines.expression.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ export declare abstract class Expression
180180
| [sum()](./firestore_lite_pipelines.expression.md#expressionsum) | | <b><i>(Public Preview)</i></b> Creates an aggregation that calculates the sum of a numeric field across multiple stage inputs. |
181181
| [timestampAdd(unit, amount)](./firestore_lite_pipelines.expression.md#expressiontimestampadd) | | <b><i>(Public Preview)</i></b> Creates an expression that adds a specified amount of time to this timestamp expression. |
182182
| [timestampAdd(unit, amount)](./firestore_lite_pipelines.expression.md#expressiontimestampadd) | | <b><i>(Public Preview)</i></b> Creates an expression that adds a specified amount of time to this timestamp expression. |
183+
| [timestampDiff(start, unit)](./firestore_lite_pipelines.expression.md#expressiontimestampdiff) | | <b><i>(Public Preview)</i></b> Creates an expression that calculates the difference between this timestamp and another timestamp. |
184+
| [timestampDiff(start, unit)](./firestore_lite_pipelines.expression.md#expressiontimestampdiff) | | <b><i>(Public Preview)</i></b> Creates an expression that calculates the difference between this timestamp and another timestamp. |
185+
| [timestampExtract(part, timezone)](./firestore_lite_pipelines.expression.md#expressiontimestampextract) | | <b><i>(Public Preview)</i></b> Creates an expression that extracts a specified part from this timestamp expression. |
186+
| [timestampExtract(part, timezone)](./firestore_lite_pipelines.expression.md#expressiontimestampextract) | | <b><i>(Public Preview)</i></b> Creates an expression that extracts a specified part from this timestamp expression. |
183187
| [timestampSubtract(unit, amount)](./firestore_lite_pipelines.expression.md#expressiontimestampsubtract) | | <b><i>(Public Preview)</i></b> Creates an expression that subtracts a specified amount of time from this timestamp expression. |
184188
| [timestampSubtract(unit, amount)](./firestore_lite_pipelines.expression.md#expressiontimestampsubtract) | | <b><i>(Public Preview)</i></b> Creates an expression that subtracts a specified amount of time from this timestamp expression. |
185189
| [timestampToUnixMicros()](./firestore_lite_pipelines.expression.md#expressiontimestamptounixmicros) | | <b><i>(Public Preview)</i></b> Creates an expression that converts this timestamp expression to the number of microseconds since the Unix epoch (1970-01-01 00:00:00 UTC). |
@@ -4818,6 +4822,146 @@ field("timestamp").timestampAdd("day", 1);
48184822
48194823
```
48204824

4825+
## Expression.timestampDiff()
4826+
4827+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
4828+
>
4829+
4830+
Creates an expression that calculates the difference between this timestamp and another timestamp.
4831+
4832+
<b>Signature:</b>
4833+
4834+
```typescript
4835+
timestampDiff(start: Expression, unit: Expression): FunctionExpression;
4836+
```
4837+
4838+
#### Parameters
4839+
4840+
| Parameter | Type | Description |
4841+
| --- | --- | --- |
4842+
| start | [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The expression evaluating to the starting timestamp. |
4843+
| unit | [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The expression evaluates to a unit of time, must be one of 'microsecond', 'millisecond', 'second', 'minute', 'hour', 'day'. |
4844+
4845+
<b>Returns:</b>
4846+
4847+
[FunctionExpression](./firestore_lite_pipelines.functionexpression.md#functionexpression_class)
4848+
4849+
A new [Expression](./firestore_pipelines.expression.md#expression_class) representing the difference as an integer.
4850+
4851+
### Example
4852+
4853+
4854+
```typescript
4855+
// Calculate the difference determined by fields 'startTime' and 'unit'.
4856+
field("endTime").timestampDiff(field("startTime"), field("unit"));
4857+
4858+
```
4859+
4860+
## Expression.timestampDiff()
4861+
4862+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
4863+
>
4864+
4865+
Creates an expression that calculates the difference between this timestamp and another timestamp.
4866+
4867+
<b>Signature:</b>
4868+
4869+
```typescript
4870+
timestampDiff(start: string | Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day'): FunctionExpression;
4871+
```
4872+
4873+
#### Parameters
4874+
4875+
| Parameter | Type | Description |
4876+
| --- | --- | --- |
4877+
| start | string \| [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The field name of the starting timestamp. |
4878+
| unit | 'microsecond' \| 'millisecond' \| 'second' \| 'minute' \| 'hour' \| 'day' | The unit of time for the difference (e.g., "day", "hour"). |
4879+
4880+
<b>Returns:</b>
4881+
4882+
[FunctionExpression](./firestore_lite_pipelines.functionexpression.md#functionexpression_class)
4883+
4884+
A new [Expression](./firestore_pipelines.expression.md#expression_class) representing the difference as an integer.
4885+
4886+
### Example
4887+
4888+
4889+
```typescript
4890+
// Calculate the difference in days between 'endTime' and 'startTime' fields.
4891+
field("endTime").timestampDiff("startTime", "day");
4892+
4893+
```
4894+
4895+
## Expression.timestampExtract()
4896+
4897+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
4898+
>
4899+
4900+
Creates an expression that extracts a specified part from this timestamp expression.
4901+
4902+
<b>Signature:</b>
4903+
4904+
```typescript
4905+
timestampExtract(part: TimePart, timezone?: string | Expression): FunctionExpression;
4906+
```
4907+
4908+
#### Parameters
4909+
4910+
| Parameter | Type | Description |
4911+
| --- | --- | --- |
4912+
| part | [TimePart](./firestore_lite_pipelines.md#timepart) | The part to extract from the timestamp (e.g., "year", "month", "day"). |
4913+
| timezone | string \| [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The timezone to use for extraction. Valid values are from the TZ database (e.g., "America/Los\_Angeles") or in the format "Etc/GMT-1." |
4914+
4915+
<b>Returns:</b>
4916+
4917+
[FunctionExpression](./firestore_lite_pipelines.functionexpression.md#functionexpression_class)
4918+
4919+
A new [Expression](./firestore_pipelines.expression.md#expression_class) representing the extracted part as an integer.
4920+
4921+
### Example
4922+
4923+
4924+
```typescript
4925+
// Extract the year from the 'createdAt' field.
4926+
field('createdAt').timestampExtract('year')
4927+
4928+
```
4929+
4930+
## Expression.timestampExtract()
4931+
4932+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
4933+
>
4934+
4935+
Creates an expression that extracts a specified part from this timestamp expression.
4936+
4937+
<b>Signature:</b>
4938+
4939+
```typescript
4940+
timestampExtract(part: Expression, timezone?: string | Expression): FunctionExpression;
4941+
```
4942+
4943+
#### Parameters
4944+
4945+
| Parameter | Type | Description |
4946+
| --- | --- | --- |
4947+
| part | [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The expression evaluating to the part to extract. |
4948+
| timezone | string \| [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The timezone to use for extraction. Valid values are from the TZ database (e.g., "America/Los\_Angeles") or in the format "Etc/GMT-1." |
4949+
4950+
<b>Returns:</b>
4951+
4952+
[FunctionExpression](./firestore_lite_pipelines.functionexpression.md#functionexpression_class)
4953+
4954+
A new [Expression](./firestore_pipelines.expression.md#expression_class) representing the extracted part as an integer.
4955+
4956+
### Example
4957+
4958+
4959+
```typescript
4960+
// Extract the part specified by the field 'extractionPart' from 'createdAt'.
4961+
field('createdAt').timestampExtract(field('extractionPart'))
4962+
4963+
```
4964+
48214965
## Expression.timestampSubtract()
48224966

48234967
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.

0 commit comments

Comments
 (0)