diff --git a/handwritten/firestore/api-report/firestore.api.md b/handwritten/firestore/api-report/firestore.api.md index df8cc5c85c2..78383dbd1d8 100644 --- a/handwritten/firestore/api-report/firestore.api.md +++ b/handwritten/firestore/api-report/firestore.api.md @@ -1207,6 +1207,10 @@ abstract class Expression implements firestore.Pipelines.Expression, HasUserData sum(): AggregateFunction; timestampAdd(unit: Expression, amount: Expression): FunctionExpression; timestampAdd(unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression; + timestampDiff(start: Expression, unit: Expression): FunctionExpression; + timestampDiff(start: string | Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day'): FunctionExpression; + timestampExtract(part: firestore.Pipelines.TimePart, timezone?: string | Expression): FunctionExpression; + timestampExtract(part: Expression, timezone?: string | Expression): FunctionExpression; timestampSubtract(unit: Expression, amount: Expression): FunctionExpression; timestampSubtract(unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression; timestampToUnixMicros(): FunctionExpression; @@ -2116,6 +2120,8 @@ declare namespace Pipelines { isType, Type, timestampTruncate, + timestampExtract, + timestampDiff, split, ltrim, rtrim, @@ -2709,6 +2715,30 @@ function timestampAdd(timestamp: Expression, unit: 'microsecond' | 'millisecond' // @beta function timestampAdd(fieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', amount: number): FunctionExpression; +// @beta +function timestampDiff(endFieldName: string, startFieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression; + +// @beta +function timestampDiff(endFieldName: string, startExpression: Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression; + +// @beta +function timestampDiff(endExpression: Expression, startFieldName: string, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression; + +// @beta +function timestampDiff(endExpression: Expression, startExpression: Expression, unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | Expression): FunctionExpression; + +// @beta +function timestampExtract(fieldName: string, part: firestore.Pipelines.TimePart, timezone?: string | Expression): FunctionExpression; + +// @beta +function timestampExtract(fieldName: string, part: Expression, timezone?: string | Expression): FunctionExpression; + +// @beta +function timestampExtract(timestampExpression: Expression, part: firestore.Pipelines.TimePart, timezone?: string | Expression): FunctionExpression; + +// @beta +function timestampExtract(timestampExpression: Expression, part: Expression, timezone?: string | Expression): FunctionExpression; + // @beta function timestampSubtract(timestamp: Expression, unit: Expression, amount: Expression): FunctionExpression; diff --git a/handwritten/firestore/dev/src/pipelines/expression.ts b/handwritten/firestore/dev/src/pipelines/expression.ts index 8a32713c36b..fad626b789d 100644 --- a/handwritten/firestore/dev/src/pipelines/expression.ts +++ b/handwritten/firestore/dev/src/pipelines/expression.ts @@ -2396,6 +2396,111 @@ export abstract class Expression ]); } + /** + * @beta + * Creates an expression that calculates the difference between this timestamp and another timestamp. + * + * @example + * ```typescript + * // Calculate the difference determined by fields 'startTime' and 'unit'. + * field("endTime").timestampDiff(field("startTime"), field("unit")); + * ``` + * + * @param start - The expression evaluating to the starting timestamp. + * @param unit - The expression evaluates to a unit of time, must be one of 'microsecond', 'millisecond', 'second', 'minute', 'hour', 'day'. + * @returns A new `Expression` representing the difference as an integer. + */ + timestampDiff(start: Expression, unit: Expression): FunctionExpression; + + /** + * @beta + * Creates an expression that calculates the difference between this timestamp and another timestamp. + * + * @example + * ```typescript + * // Calculate the difference in days between 'endTime' and 'startTime' fields. + * field("endTime").timestampDiff("startTime", "day"); + * ``` + * + * @param start - The field name of the starting timestamp or an expression evaluating to a timestamp. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new `Expression` representing the difference as an integer. + */ + timestampDiff( + start: string | Expression, + unit: 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day', + ): FunctionExpression; + timestampDiff( + start: string | Expression, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, + ): FunctionExpression { + return new FunctionExpression('timestamp_diff', [ + this, + fieldOrExpression(start), + valueToDefaultExpr(unit), + ]); + } + + /** + * @beta + * Creates an expression that extracts a specified part from this timestamp expression. + * + * @example + * ```typescript + * // Extract the year from the 'createdAt' field. + * field('createdAt').timestampExtract('year') + * ``` + * + * @param part - The part to extract from the timestamp (e.g., "year", "month", "day"). + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new `Expression` representing the extracted part as an integer. + */ + timestampExtract( + part: firestore.Pipelines.TimePart, + timezone?: string | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that extracts a specified part from this timestamp expression. + * + * @example + * ```typescript + * // Extract the part specified by the field 'extractionPart' from 'createdAt'. + * field('createdAt').timestampExtract(field('extractionPart')) + * ``` + * + * @param part - The expression evaluating to the part to extract. + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new `Expression` representing the extracted part as an integer. + */ + timestampExtract( + part: Expression, + timezone?: string | Expression, + ): FunctionExpression; + timestampExtract( + part: firestore.Pipelines.TimePart | Expression, + timezone?: string | Expression, + ): FunctionExpression { + const internalPart = isString(part) ? part.toLowerCase() : part; + const args = [this, valueToDefaultExpr(internalPart)]; + if (timezone) { + args.push(valueToDefaultExpr(timezone)); + } + return new FunctionExpression('timestamp_extract', args); + } + /** * @beta * Creates an expression that returns the document ID from a path. @@ -9417,7 +9522,7 @@ export function split( * @example * ```typescript * // Truncate the 'createdAt' timestamp to the beginning of the day. - * field('createdAt').timestampTruncate('day') + * timestampTruncate('createdAt', 'day') * ``` * * @param fieldName Truncate the timestamp value contained in this field. @@ -9438,7 +9543,7 @@ export function timestampTruncate( * @example * ```typescript * // Truncate the 'createdAt' timestamp to the granularity specified in the field 'granularity'. - * field('createdAt').timestampTruncate(field('granularity')) + * timestampTruncate('createdAt', field('granularity')) * ``` * * @param fieldName Truncate the timestamp value contained in this field. @@ -9459,7 +9564,7 @@ export function timestampTruncate( * @example * ```typescript * // Truncate the 'createdAt' timestamp to the beginning of the day. - * field('createdAt').timestampTruncate('day') + * timestampTruncate(field('createdAt'), 'day') * ``` * * @param timestampExpression Truncate the timestamp value that is returned by this expression. @@ -9480,7 +9585,7 @@ export function timestampTruncate( * @example * ```typescript * // Truncate the 'createdAt' timestamp to the granularity specified in the field 'granularity'. - * field('createdAt').timestampTruncate(field('granularity')) + * timestampTruncate(field('createdAt'), field('granularity')) * ``` * * @param timestampExpression Truncate the timestamp value that is returned by this expression. @@ -9508,6 +9613,237 @@ export function timestampTruncate( ); } +/** + * @beta + * Creates an expression that calculates the difference between two timestamps. + * + * @example + * ```typescript + * // Calculate the difference in days between 'endTime' and 'startTime' fields. + * timestampDiff('endTime', 'startTime', 'day') + * ``` + * + * @param endFieldName - The name of the field representing the ending timestamp. + * @param startFieldName - The name of the field representing the starting timestamp. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new `Expression` representing the difference as an integer. + */ +export function timestampDiff( + endFieldName: string, + startFieldName: string, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, +): FunctionExpression; + +/** + * @beta + * Creates an expression that calculates the difference between two timestamps. + * + * @example + * ```typescript + * // Calculate the difference in days between 'endTime' field and a starting timestamp expression. + * timestampDiff('endTime', field('startTime'), 'day') + * ``` + * + * @param endFieldName - The name of the field representing the ending timestamp. + * @param startExpression - The starting timestamp for the difference calculation. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new `Expression` representing the difference as an integer. + */ +export function timestampDiff( + endFieldName: string, + startExpression: Expression, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, +): FunctionExpression; + +/** + * @beta + * Creates an expression that calculates the difference between two timestamps. + * + * @example + * ```typescript + * // Calculate the difference in days between an ending timestamp expression and 'startTime' field. + * timestampDiff(field('endTime'), 'startTime', 'day') + * ``` + * + * @param endExpression - The ending timestamp for the difference calculation. + * @param startFieldName - The name of the field representing the starting timestamp. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new `Expression` representing the difference as an integer. + */ +export function timestampDiff( + endExpression: Expression, + startFieldName: string, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, +): FunctionExpression; + +/** + * @beta + * Creates an expression that calculates the difference between two timestamps. + * + * @example + * ```typescript + * // Calculate the difference in days between two timestamp expressions. + * timestampDiff(field('endTime'), field('startTime'), 'day') + * ``` + * + * @param endExpression - The ending timestamp for the difference calculation. + * @param startExpression - The starting timestamp for the difference calculation. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new `Expression` representing the difference as an integer. + */ +export function timestampDiff( + endExpression: Expression, + startExpression: Expression, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, +): FunctionExpression; +export function timestampDiff( + endFieldNameOrExpression: string | Expression, + startFieldNameOrExpression: string | Expression, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, +): FunctionExpression { + const normalizedEnd = fieldOrExpression(endFieldNameOrExpression); + const normalizedStart = fieldOrExpression(startFieldNameOrExpression); + const normalizedUnit = valueToDefaultExpr(unit); + return normalizedEnd.timestampDiff(normalizedStart, normalizedUnit); +} + +/** + * @beta + * Creates an expression that extracts a specified part from a timestamp. + * + * @example + * ```typescript + * // Extract the year from the 'createdAt' timestamp. + * timestampExtract('createdAt', 'year') + * ``` + * + * @param fieldName - The name of the field representing the timestamp. + * @param part - The part to extract from the timestamp (e.g., "year", "month", "day"). + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new `Expression` representing the extracted part as an integer. + */ +export function timestampExtract( + fieldName: string, + part: firestore.Pipelines.TimePart, + timezone?: string | Expression, +): FunctionExpression; + +/** + * @beta + * Creates an expression that extracts a specified part from a timestamp. + * + * @example + * ```typescript + * // Extract the part specified by the field 'part' from 'createdAt'. + * timestampExtract('createdAt', field('part')) + * ``` + * + * @param fieldName - The name of the field representing the timestamp. + * @param part - The expression evaluating to the part to extract. + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new `Expression` representing the extracted part as an integer. + */ +export function timestampExtract( + fieldName: string, + part: Expression, + timezone?: string | Expression, +): FunctionExpression; + +/** + * @beta + * Creates an expression that extracts a specified part from a timestamp. + * + * @example + * ```typescript + * // Extract the year from the timestamp returned by the expression. + * timestampExtract(field('createdAt'), 'year') + * ``` + * + * @param timestampExpression - The expression evaluating to the timestamp. + * @param part - The part to extract from the timestamp (e.g., "year", "month", "day"). + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new `Expression` representing the extracted part as an integer. + */ +export function timestampExtract( + timestampExpression: Expression, + part: firestore.Pipelines.TimePart, + timezone?: string | Expression, +): FunctionExpression; + +/** + * @beta + * Creates an expression that extracts a specified part from a timestamp. + * + * @example + * ```typescript + * // Extract the part specified by the field 'part' from the timestamp. + * timestampExtract(field('createdAt'), field('part')) + * ``` + * + * @param timestampExpression - The expression evaluating to the timestamp. + * @param part - The expression evaluating to the part to extract. + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new `Expression` representing the extracted part as an integer. + */ +export function timestampExtract( + timestampExpression: Expression, + part: Expression, + timezone?: string | Expression, +): FunctionExpression; +export function timestampExtract( + fieldNameOrExpression: string | Expression, + part: firestore.Pipelines.TimePart | Expression, + timezone?: string | Expression, +): FunctionExpression { + return fieldOrExpression(fieldNameOrExpression).timestampExtract( + valueToDefaultExpr(isString(part) ? part.toLowerCase() : part), + timezone, + ); +} + /** * @beta * Creates an expression that returns the data type of the data in the specified field. diff --git a/handwritten/firestore/dev/src/pipelines/index.ts b/handwritten/firestore/dev/src/pipelines/index.ts index 4dcf2694b61..7cc80f82840 100644 --- a/handwritten/firestore/dev/src/pipelines/index.ts +++ b/handwritten/firestore/dev/src/pipelines/index.ts @@ -147,6 +147,8 @@ export { type, isType, timestampTruncate, + timestampExtract, + timestampDiff, split, ltrim, rtrim, diff --git a/handwritten/firestore/dev/system-test/pipeline.ts b/handwritten/firestore/dev/system-test/pipeline.ts index 8377424c8d2..bdcd5c5a1fb 100644 --- a/handwritten/firestore/dev/system-test/pipeline.ts +++ b/handwritten/firestore/dev/system-test/pipeline.ts @@ -147,6 +147,8 @@ import { type, isType, timestampTruncate, + timestampExtract, + timestampDiff, split, switchOn, nor, @@ -5075,6 +5077,73 @@ describe.skipClassic('Pipeline class', () => { }); }); + it('supports timestamp difference', async () => { + const results = await firestore + .pipeline() + .collection(randomCol.path) + .limit(1) + .replaceWith( + map({ + end: new Timestamp(1741437296, 123456789), + start: new Timestamp(1741428000, 0), + }), + ) + .select( + timestampDiff(field('end'), field('start'), 'hour').as('diffHour'), + field('end').timestampDiff(field('start'), 'minute').as('diffMinute'), + field('end').timestampDiff(field('start'), 'second').as('diffSecond'), + field('start').timestampDiff(field('end'), 'hour').as('diffHourNeg'), + ) + .execute(); + + expectResults(results, { + diffHour: 2, + diffMinute: 154, + diffSecond: 9296, + diffHourNeg: -2, + }); + }); + + it('supports timestamp extraction', async () => { + const results = await firestore + .pipeline() + .collection(randomCol.path) + .limit(1) + .replaceWith( + map({ + ts: new Timestamp(1741437296, 123456789), + }), + ) + .select( + timestampExtract(field('ts'), 'year').as('year'), + field('ts').timestampExtract('month').as('month'), + timestampExtract(field('ts'), 'day').as('day'), + field('ts').timestampExtract('hour').as('hour'), + timestampExtract(field('ts'), 'minute').as('minute'), + field('ts').timestampExtract('second').as('second'), + timestampExtract(field('ts'), 'millisecond').as('millis'), + field('ts').timestampExtract('microsecond').as('micros'), + timestampExtract(field('ts'), 'dayofyear').as('dayOfYear'), + field('ts') + .timestampExtract('hour', 'America/Los_Angeles') + .as('hourLa'), + ) + .execute(); + + expectResults(results, { + year: 2025, + month: 3, + day: 8, + hour: 12, + minute: 34, + second: 56, + millis: 123, + micros: 123456, + dayOfYear: 67, + hourLa: 4, + }); + }); + it('supports split', async () => { const results = await firestore .pipeline() diff --git a/handwritten/firestore/types/firestore.d.ts b/handwritten/firestore/types/firestore.d.ts index 6b88278d4e4..8cd99823648 100644 --- a/handwritten/firestore/types/firestore.d.ts +++ b/handwritten/firestore/types/firestore.d.ts @@ -5580,6 +5580,89 @@ declare namespace FirebaseFirestore { timezone?: string | Expression, ): FunctionExpression; + /** + * @beta + * Creates an expression that calculates the difference between this timestamp and another timestamp. + * + * @example + * ```typescript + * // Calculate the difference determined by fields 'startTime' and 'unit'. + * field("endTime").timestampDiff(field("startTime"), field("unit")); + * ``` + * + * @param start - The expression evaluating to the starting timestamp. + * @param unit - The expression evaluates to a unit of time, must be one of 'microsecond', 'millisecond', 'second', 'minute', 'hour', 'day'. + * @returns A new `Expression` representing the difference as an integer. + */ + timestampDiff(start: Expression, unit: Expression): FunctionExpression; + + /** + * @beta + * Creates an expression that calculates the difference between this timestamp and another timestamp. + * + * @example + * ```typescript + * // Calculate the difference in days between 'endTime' and 'startTime' fields. + * field("endTime").timestampDiff("startTime", "day"); + * ``` + * + * @param start - The field name of the starting timestamp. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new `Expression` representing the difference as an integer. + */ + timestampDiff( + start: string | Expression, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day', + ): FunctionExpression; + + /** + * @beta + * Creates an expression that extracts a specified part from this timestamp expression. + * + * @example + * ```typescript + * // Extract the year from the 'createdAt' field. + * field('createdAt').timestampExtract('year') + * ``` + * + * @param part - The part to extract from the timestamp (e.g., "year", "month", "day"). + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new `Expression` representing the extracted part as an integer. + */ + timestampExtract( + part: TimePart, + timezone?: string | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that extracts a specified part from this timestamp expression. + * + * @example + * ```typescript + * // Extract the part specified by the field 'extractionPart' from 'createdAt'. + * field('createdAt').timestampExtract(field('extractionPart')) + * ``` + * + * @param part - The expression evaluating to the part to extract. + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new `Expression` representing the extracted part as an integer. + */ + timestampExtract( + part: Expression, + timezone?: string | Expression, + ): FunctionExpression; + /** * @beta * Creates an expression that returns the data type of this expression's result, as a string. @@ -5690,6 +5773,12 @@ declare namespace FirebaseFirestore { | 'year' | 'isoYear'; + /** + * @beta + * Specify time parts for `timestampExtract` expressions. + */ + export type TimePart = TimeGranularity | 'dayofweek' | 'dayofyear'; + /** * @beta * An interface that represents a selectable expression. @@ -11268,7 +11357,7 @@ declare namespace FirebaseFirestore { * @example * ```typescript * // Truncate the 'createdAt' timestamp to the beginning of the day. - * field('createdAt').timestampTruncate('day') + * timestampTruncate('createdAt', 'day') * ``` * * @param fieldName Truncate the timestamp value contained in this field. @@ -11289,7 +11378,7 @@ declare namespace FirebaseFirestore { * @example * ```typescript * // Truncate the 'createdAt' timestamp to the granularity specified in the field 'granularity'. - * field('createdAt').timestampTruncate(field('granularity')) + * timestampTruncate('createdAt', field('granularity')) * ``` * * @param fieldName Truncate the timestamp value contained in this field. @@ -11310,7 +11399,7 @@ declare namespace FirebaseFirestore { * @example * ```typescript * // Truncate the 'createdAt' timestamp to the beginning of the day. - * field('createdAt').timestampTruncate('day') + * timestampTruncate(field('createdAt'), 'day') * ``` * * @param timestampExpression Truncate the timestamp value that is returned by this expression. @@ -11331,7 +11420,7 @@ declare namespace FirebaseFirestore { * @example * ```typescript * // Truncate the 'createdAt' timestamp to the granularity specified in the field 'granularity'. - * field('createdAt').timestampTruncate(field('granularity')) + * timestampTruncate(field('createdAt'), field('granularity') * ``` * * @param timestampExpression Truncate the timestamp value that is returned by this expression. @@ -11346,6 +11435,243 @@ declare namespace FirebaseFirestore { timezone?: string | Expression, ): FunctionExpression; + /** + * @beta + * Creates an expression that calculates the difference between two timestamps. + * + * @example + * ```typescript + * // Calculate the difference in days between 'endTime' and 'startTime' fields. + * timestampDiff('endTime', 'startTime', 'day') + * ``` + * + * @param endFieldName - The name of the field representing the ending timestamp. + * @param startFieldName - The name of the field representing the starting timestamp. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new {@code Expression} representing the difference as an integer. + */ + export function timestampDiff( + endFieldName: string, + startFieldName: string, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that calculates the difference between two timestamps. + * + * @example + * ```typescript + * // Calculate the difference in days between 'endTime' field and a starting timestamp expression. + * timestampDiff('endTime', field('startTime'), 'day') + * ``` + * + * @param endFieldName - The name of the field representing the ending timestamp. + * @param startExpression - The starting timestamp for the difference calculation. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new {@code Expression} representing the difference as an integer. + */ + export function timestampDiff( + endFieldName: string, + startExpression: Expression, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that calculates the difference between two timestamps. + * + * @example + * ```typescript + * // Calculate the difference in days between an ending timestamp expression and 'startTime' field. + * timestampDiff(field('endTime'), 'startTime', 'day') + * ``` + * + * @param endExpression - The ending timestamp for the difference calculation. + * @param startFieldName - The name of the field representing the starting timestamp. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new {@code Expression} representing the difference as an integer. + */ + export function timestampDiff( + endExpression: Expression, + startFieldName: string, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that calculates the difference between two timestamps. + * + * @example + * ```typescript + * // Calculate the difference in days between two timestamp expressions. + * timestampDiff(field('endTime'), field('startTime'), 'day') + * ``` + * + * @param endExpression - The ending timestamp for the difference calculation. + * @param startExpression - The starting timestamp for the difference calculation. + * @param unit - The unit of time for the difference (e.g., "day", "hour"). + * @returns A new {@code Expression} representing the difference as an integer. + */ + export function timestampDiff( + endExpression: Expression, + startExpression: Expression, + unit: + | 'microsecond' + | 'millisecond' + | 'second' + | 'minute' + | 'hour' + | 'day' + | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that extracts a specified part from a timestamp. + * + * @example + * ```typescript + * // Extract the year from the 'createdAt' timestamp. + * timestampExtract('createdAt', 'year') + * ``` + * + * @param fieldName - The name of the field representing the timestamp. + * @param part - The part to extract from the timestamp (e.g., "year", "month", "day"). + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new {@code Expression} representing the extracted part as an integer. + */ + export function timestampExtract( + fieldName: string, + part: TimePart, + timezone?: string | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that extracts a specified part from a timestamp. + * + * @example + * ```typescript + * // Extract the part specified by the field 'part' from 'createdAt'. + * timestampExtract('createdAt', field('part')) + * ``` + * + * @param fieldName - The name of the field representing the timestamp. + * @param part - The expression evaluating to the part to extract. + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new {@code Expression} representing the extracted part as an integer. + */ + export function timestampExtract( + fieldName: string, + part: Expression, + timezone?: string | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that extracts a specified part from a timestamp. + * + * @example + * ```typescript + * // Extract the year from the timestamp returned by the expression. + * timestampExtract(field('createdAt'), 'year') + * ``` + * + * @param timestampExpression - The expression evaluating to the timestamp. + * @param part - The part to extract from the timestamp (e.g., "year", "month", "day"). + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new {@code Expression} representing the extracted part as an integer. + */ + export function timestampExtract( + timestampExpression: Expression, + part: TimePart, + timezone?: string | Expression, + ): FunctionExpression; + + /** + * @beta + * Creates an expression that extracts a specified part from a timestamp. + * + * @example + * ```typescript + * // Extract the part specified by the field 'part' from the timestamp. + * timestampExtract(field('createdAt'), field('part')) + * ``` + * + * @param timestampExpression - The expression evaluating to the timestamp. + * @param part - The expression evaluating to the part to extract. + * @param timezone - 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." + * Defaults to "UTC" if not specified. + * @returns A new {@code Expression} representing the extracted part as an integer. + */ + export function timestampExtract( + timestampExpression: Expression, + part: Expression, + timezone?: string | Expression, + ): FunctionExpression; + + /** + * @beta + * + * An enumeration of the different types generated by the Firestore backend. + * + *