¿Cómo agrego minutos a un tipo de datos de tiempo?

10

Tengo un procedimiento almacenado que inserta dos registros en una tabla, la diferencia entre los registros es que la columna de tiempo del segundo registro es @MinToAddposterior a la primera:

CREATE PROCEDURE CreateEntry
    /*Other columns*/
    @StartTime time(2),
    @EndTime time(2),
    @MinutesToAdd smallint
    AS
BEGIN
    SET NOCOUNT ON;

    SET @MinutesToAdd = @MinutesToAdd % 1440;   --Prevent overflow if needed?
    IF (@MinutesToAdd > 0)
    BEGIN
    INSERT INTO ClientNotification (/*Other columns*/ startTime, endTime)
        OUTPUT inserted.id
        VALUES
               (/*Other columns*/ @StartTime, @EndTime),
               (/*Other columns*/ @StartTime + @MinutesToAdd, @EndTime + @MinutesToAdd);
    END
    ELSE
    BEGIN
        /*Whatever ELSE does.*/
    END
END

¿Cuál es la forma correcta de agregar @MinutesToAddminutos a @StartTimey @EndTime?
Tenga en cuenta que estoy usando el timetipo de datos.

Actualización :
una respuesta correcta debe contener la siguiente información:

  • Cómo agregar minutos a un timetipo de datos.
  • Que la solución propuesta no resulta en una pérdida de precisión.
  • Problemas o inquietudes a tener en cuenta en el caso de que los minutos sean demasiado largos para caber en una timevariable, o riesgo de volcar la timevariable. Si no hay problemas, indíquelo.
Trisped
fuente
55
No veo cómo la edición de su pregunta aclara aún más la pregunta en cuestión.
swasheck
@swasheck Explico explícitamente las tres cosas que estoy buscando. También establezco límites en lo que no estoy buscando.
Trisped

Respuestas:

36

No puede usar aritmética abreviada perezosa con los nuevos tipos. Tratar:

DATEADD(MINUTE, @MinutesToAdd, @StartTime)

Tenga en cuenta que aunque haya protegido su @MinutesToAddcontra desbordamiento, no ha protegido el resultado del desbordamiento. Esto no produce un error, sin embargo, es posible que no sea el resultado que espera.

DECLARE @StartTime TIME(0) = '23:59';
DECLARE @MinutesToAdd INT = 20;

SELECT DATEADD(MINUTE, @MinutesToAdd, @StartTime);

Resultado:

00:19:00

Supongo que esto debe pasar por algún tipo de conversión interna, porque no podría obtener ese resultado diciendo:

DECLARE @StartTime TIME(0) = '24:19';

Resultado:

Mensaje 241, Nivel 16, Estado 1, Línea 1 La
conversión falló al convertir la fecha y / o la hora de la cadena de caracteres.

Debe considerar cómo desea manejar los cálculos que conducen a uno @EndTimeo ambos @StartTimey @EndTimeestar en el día siguiente.

Además, para abordar otro nuevo requisito en su "respuesta ideal", no hay pérdida de precisión. Según la documentación , el tipo de retorno de DATEADDes el mismo que la entrada:

El tipo de datos de retorno es el tipo de datos del argumento de fecha , excepto los literales de cadena.

Por lo tanto, TIMEadentro, TIMEafuera.

Aaron Bertrand
fuente
1
+1 @Aaron Alternativamente, puede convertir StartTime y TimeToAdd a datetime y luego agregar. La conversión de TimeToAdd será muy complicada cuando los minutos sean> 59. DATEADD es la mejor solución.
Brian
Si agrega que DATEADDdevuelve el mismo tipo que el argumento de fecha, entonces aceptaré. El "Prevenir el desbordamiento si es necesario?" No se necesita línea. El problema de transferencia será manejado por la fuente de los datos y el destino de los datos.
Trisped
3
@Trisped seguro, si agrega a la pregunta que no creía que DATEADD era apropiado porque pensaba que solo podía devolver DATETIME y que eso podría causar problemas. De lo contrario, no parece relevante para su pregunta o para futuros lectores ...
Aaron Bertrand
¿Cómo la relevancia no está implícita en el "Tenga en cuenta que estoy usando el tipo de datos de tiempo"? Además, ¿por qué cambiaste mi pregunta para usar inconstantemente fila en lugar de registro?
Trisped
1
@Trisped la edición usa una mejor terminología y por favor vea las preguntas frecuentes sobre la edición : no dejemos de ir y venir o bloquearé la pregunta. Aaron tiene razón en que necesitamos aclarar todo para los demás, usted tiene su respuesta. Considere editar su pregunta según las líneas que sugiere si cree que sería útil: Aaron se ha ofrecido amablemente a agregar la información que desea a su respuesta si lo hace.
Jack dice que intente topanswers.xyz
0

Simplemente use la función dateadd para agregar sus minutos en entero contra '0:00'. Luego regresa al tiempo.

Seleccionar reparto (dateadd (minuto, 84, '0: 00') como hora)

Aquí, 84 es el minuto entero que quiero expresar en el tipo "tiempo".

Agregué eso a '0:00' y luego para eliminar el componente de fecha, lo convierto al tipo de hora. No se necesita codificación personalizada.

(Sin nombre de columna)

01: 24: 00.0000000

Jun Sato
fuente