Compartir a través de


DATETRUNC (Transact-SQL)

Se aplica a: Sql Server 2022 (16.x) Azure SQL Database Azure SQL Instancia administrada punto de conexión de SQL Analytics en Microsoft Fabric Warehouse en Microsoft Fabric

La función DATETRUNC devuelve una fecha de entrada truncada a un datepart especificado.

Nota:

DATETRUNC se introdujo en SQL Server 2022 (16.x).

Sintaxis

DATETRUNC ( datepart , date )

Argumentos

datepart

Especifica la precisión para el truncamiento. En esta tabla se enumeran todos los valores datepart válidos para DATETRUNC, dado que también se trata de una parte válida del tipo de fecha de entrada.

datepart Abreviaturas Notas de truncamiento
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y dayofyear se trunca de la misma manera que day
day dd, d day se trunca de la misma manera que dayofyear
week wk, ww Trunque al primer día de la semana. En T-SQL, el primer día de la semana se define mediante la configuración T-SQL @@DATEFIRST. Para un entorno inglés de EE. UU., @@DATEFIRST el valor predeterminado es 7 (domingo).
iso_week isowk, isoww Trunca hasta el primer día de una semana ISO. El primer día de la semana del sistema de calendario ISO8601 es el lunes.
hour hh
minute mi, n
second ss, s
millisecond ms
microsecond mcs

Nota:

No se admiten las partes de fecha de día de la semana, zona horaria y T-SQL nanosegundos para DATETRUNC.

date

Acepta cualquier expresión, columna o variable definida por el usuario que pueda resolverse en cualquier tipo de fecha u hora T-SQL válido. Los tipos válidos son los siguientes:

  • smalldatetime
  • datetime
  • date
  • time
  • datetime2
  • datetimeoffset

No confunda el parámetro date con el tipo de datos date.

DATETRUNC también acepta un literal de cadena (de cualquier tipo de cadena) que se puede resolver en un datetime2(7).

Tipos de valores devueltos

El tipo de datos devuelto para DATETRUNC es dinámico. DATETRUNC devuelve una fecha truncada del mismo tipo de datos (y, si procede, la misma escala de tiempo fraccionaria) que la fecha de entrada. Por ejemplo, si DATETRUNC recibiera una fecha de entrada datetimeoffset(3), devolvería un valor datetimeoffset(3). Si recibiera un literal de cadena capaz de resolverse en un valor datetime2(7), DATETRUNC devolvería un valor datetime2(7).

Precisión de la escala de tiempo fraccionaria

Los milisegundos tienen una escala de tiempo fraccionaria de 3 (.123), los microsegundos tienen una escala de tiempo fraccionaria de 6 (.123456) y los nanosegundos tienen una escala de tiempo fraccionaria de 9 (.123456789). Los tipos de datos time, datetime2 y datetimeoffset permiten una escala de tiempo fraccionaria máxima de 7 (.1234567). Por lo tanto, para truncar hasta el millisecond elemento datepart, la escala de tiempo fraccionarcional debe ser al menos 3. Del mismo modo, para truncar hasta el microsecond elemento datepart, la escala de tiempo fraccionarcional debe ser al menos 6. DATETRUNC no admite el nanosecond elemento datepart , ya que ningún tipo de fecha de T-SQL admite una escala de tiempo fraccionaria de 9.

Ejemplos

A. Usar diferentes opciones de datepart

En los ejemplos siguientes se muestra el uso de los distintas opciones de datepart:

DECLARE @d datetime2 = '2021-12-08 11:30:15.1234567';
SELECT 'Year', DATETRUNC(year, @d);
SELECT 'Quarter', DATETRUNC(quarter, @d);
SELECT 'Month', DATETRUNC(month, @d);
SELECT 'Week', DATETRUNC(week, @d); -- Using the default DATEFIRST setting value of 7 (U.S. English)
SELECT 'Iso_week', DATETRUNC(iso_week, @d);
SELECT 'DayOfYear', DATETRUNC(dayofyear, @d);
SELECT 'Day', DATETRUNC(day, @d);
SELECT 'Hour', DATETRUNC(hour, @d);
SELECT 'Minute', DATETRUNC(minute, @d);
SELECT 'Second', DATETRUNC(second, @d);
SELECT 'Millisecond', DATETRUNC(millisecond, @d);
SELECT 'Microsecond', DATETRUNC(microsecond, @d);

Este es el conjunto de resultados.

Year        2021-01-01 00:00:00.0000000
Quarter     2021-10-01 00:00:00.0000000
Month       2021-12-01 00:00:00.0000000
Week        2021-12-05 00:00:00.0000000
Iso_week    2021-12-06 00:00:00.0000000
DayOfYear   2021-12-08 00:00:00.0000000
Day         2021-12-08 00:00:00.0000000
Hour        2021-12-08 11:00:00.0000000
Minute      2021-12-08 11:30:00.0000000
Second      2021-12-08 11:30:15.0000000
Millisecond 2021-12-08 11:30:15.1230000
Microsecond 2021-12-08 11:30:15.1234560

B. Configuración @@DATEFIRST

En los ejemplos siguientes se muestra el uso de la @@DATEFIRST configuración con datepartweek:

DECLARE @d datetime2 = '2021-11-11 11:11:11.1234567';

SELECT 'Week-7', DATETRUNC(week, @d); -- Uses the default DATEFIRST setting value of 7 (U.S. English)

SET DATEFIRST 6;
SELECT 'Week-6', DATETRUNC(week, @d);

SET DATEFIRST 3;
SELECT 'Week-3', DATETRUNC(week, @d);

Este es el conjunto de resultados.

Week-7  2021-11-07 00:00:00.0000000
Week-6  2021-11-06 00:00:00.0000000
Week-3  2021-11-10 00:00:00.0000000

C. Literales de fecha

En los ejemplos siguientes se muestra el uso de literales del parámetro date:

SELECT DATETRUNC(month, '1998-03-04');

SELECT DATETRUNC(millisecond, '1998-03-04 10:10:05.1234567');

DECLARE @d1 char(200) = '1998-03-04';
SELECT DATETRUNC(millisecond, @d1);

DECLARE @d2 nvarchar(max) = '1998-03-04 10:10:05';
SELECT DATETRUNC(minute, @d2);

Este es el conjunto de resultados. Todos los resultados son de tipo datetime2(7).

1998-03-01 00:00:00.0000000
1998-03-04 10:10:05.1230000
1998-03-04 00:00:00.0000000
1998-03-04 10:10:00.0000000

D. Variables y el parámetro date

En los ejemplos siguientes se muestra el uso del parámetro date:

DECLARE @d datetime2 = '1998-12-11 02:03:04.1234567';
SELECT DATETRUNC(day, @d);

Este es el conjunto de resultados.

1998-12-11 00:00:00.0000000

E. Columnas y el parámetro date

La columna TransactionDate de la tabla Sales.CustomerTransactions actúa como argumento column de ejemplo para el parámetro date:

USE WideWorldImporters;
GO

SELECT CustomerTransactionID,
    DATETRUNC(month, TransactionDate) AS MonthTransactionOccurred,
    InvoiceID,
    CustomerID,
    TransactionAmount,
    SUM(TransactionAmount) OVER (
        PARTITION BY CustomerID ORDER BY TransactionDate,
            CustomerTransactionID ROWS UNBOUNDED PRECEDING
        ) AS RunningTotal,
    TransactionDate AS ActualTransactionDate
FROM [WideWorldImporters].[Sales].[CustomerTransactions]
WHERE InvoiceID IS NOT NULL
    AND DATETRUNC(month, TransactionDate) >= '2015-12-01';

F. Expresiones y el parámetro date

El parámetro date acepta cualquier expresión que pueda resolverse en un tipo de fecha T-SQL o cualquier literal de cadena que pueda resolverse en un elemento datetime2(7). La columna TransactionDate de la tabla Sales.CustomerTransactions actúa como argumento artificial para ejemplificar el uso de un elemento expression para el parámetro date:

SELECT DATETRUNC(m, SYSDATETIME());

SELECT DATETRUNC(yyyy, CONVERT(date, '2021-12-1'));

USE WideWorldImporters;
GO
SELECT DATETRUNC(month, DATEADD(month, 4, TransactionDate))
FROM Sales.CustomerTransactions;
GO

G. Truncamiento de date a un datepart que representa su máxima precisión

Si el datepart tiene la misma precisión máxima de unidad que el tipo de fecha de entrada, el truncamiento de la fecha de entrada a este datepart no tendría ningún efecto.

Ejemplo 1

DECLARE @d datetime = '2015-04-29 05:06:07.123';
SELECT 'Input', @d;
SELECT 'Truncated', DATETRUNC(millisecond, @d);

Este es el conjunto de resultados. La fecha y hora de entrada y el parámetro de fecha truncada son los mismos.

Input     2015-04-29 05:06:07.123
Truncated 2015-04-29 05:06:07.123

Ejemplo 2

DECLARE @d date = '2050-04-04';
SELECT 'Input', @d;
SELECT 'Truncated', DATETRUNC(day, @d);

Este es el conjunto de resultados. La fecha y hora de entrada y el parámetro de fecha truncada son los mismos.

Input     2050-04-04
Truncated 2050-04-04

Example 3: Precisión smalldatetime

smalldatetime solo es preciso hasta el minuto más cercano, aunque tenga un campo para segundos. Por lo tanto, truncarlo al minuto o al segundo más cercano no tendría ningún efecto.

DECLARE @d smalldatetime = '2009-09-11 12:42:12'
SELECT 'Input', @d;
SELECT 'Truncated to minute', DATETRUNC(minute, @d)
SELECT 'Truncated to second', DATETRUNC(second, @d);

Este es el conjunto de resultados. El valor smalldatetime de entrada es el mismo que los dos valores truncados:

Input                2009-09-11 12:42:00
Truncated to minute  2009-09-11 12:42:00
Truncated to second  2009-09-11 12:42:00

Ejemplo 4: Precisión datetime

datetime solo es preciso hasta 3,33 milisegundos. Por lo tanto, truncar una fecha y hora a un milisegundo podría producir resultados diferentes de lo que espera el usuario. Sin embargo, este valor truncado es igual que el valor de datetime almacenado internamente.

DECLARE @d datetime = '2020-02-02 02:02:02.002';
SELECT 'Input', @d;
SELECT 'Truncated', DATETRUNC(millisecond, @d);

Este es el conjunto de resultados. La fecha truncada es la misma que la fecha almacenada. Esto puede ser diferente de lo que espera en función de la DECLARE instrucción .

Input     2020-02-02 02:02:02.003
Truncated 2020-02-02 02:02:02.003

Comentarios

Se produce un error si el truncamiento de fecha intenta retroceder a una fecha anterior a la fecha mínima admitida por ese tipo de datos. Este error solo se produce cuando se usa datepart week . No se puede producir cuando se usa datepart iso_week , ya que todos los tipos de fecha de T-SQL coincidentemente usan un lunes para sus fechas mínimas. Este es un ejemplo con el mensaje de error del resultado correspondiente:

DECLARE @d date= '0001-01-01 00:00:00';
SELECT DATETRUNC(week, @d);
Msg 9837, Level 16, State 3, Line 84
An invalid date value was encountered: The date value is less than the minimum date value allowed for the data type.

Se produce un DATEPART error si la DATETRUNC función o el tipo de datos de fecha de entrada no admiten el elemento datepart usado. Este error se puede producirse cuando:

  1. Se usa un elemento datepart no admitido por DATETRUNC (es decir, weekday, tzoffset o nanosecond)

  2. Un elemento datepart relacionado con time se usa con el tipo de datos date o un datepart relacionado con date se usa con el tipo de datos time. Este es un ejemplo con el mensaje de error del resultado correspondiente:

    DECLARE @d time = '12:12:12.1234567';
    SELECT DATETRUNC(year, @d);
    
    Msg 9810, Level 16, State 10, Line 78
    The datepart year is not supported by date function datetrunc for data type time.
    
  3. El elemento datepart requiere una precisión de escala de tiempo fraccionaria mayor que el tipo de datos que admite. Para obtener más información, consulte Precisión de escala de tiempo fraccionaria. Este es un ejemplo con el mensaje de error del resultado correspondiente:

    DECLARE @d datetime2(3) = '2021-12-12 12:12:12.12345';
    SELECT DATETRUNC(microsecond, @d);
    
    Msg 9810, Level 16, State 11, Line 81
    The datepart microsecond is not supported by date function datetrunc for data type datetime2.