2009-06-23 26 views
5

En mi tabla tengo un mes (tinyint) y un campo de día (tinyint). Me gustaría tener una función que tome este mes y día y produzca un horario para la próxima fecha (incluido el año) dado este mes y día.

Así que si tuviera Month = 9, Day = 7 produciría el 9/7/2009.
Si tuviera el Mes 1, Día 1 produciría 1/1/2010.SQL: Cómo producir la fecha siguiente dado mes y día

+0

¿cómo sabes qué año de usar? ¿Estás asumiendo que siempre estará basado en la fecha actual? Además, ¿qué base de datos estás usando? – northpole

+0

Se basa a partir de hoy. Entonces digamos que hoy es 23/6/2009. La fecha en la tabla es month = 6, day = 22. Entonces quiero que regrese 22/06/2010 porque esa es la próxima fecha. –

Respuesta

2

algo como esto iba a funcionar. Es una variación de su método, pero no usa el formato literal MM/DD/YYYY, y no explotará contra malas entradas (para bien o para mal).

declare @month tinyint 
declare @day tinyint 
set @month = 9 
set @day = 1 

declare @date datetime 

-- this could be inlined if desired 
set @date = convert(char(4),year(getdate()))+'0101' 
set @date = dateadd(month,@month-1,@date) 
set @date = dateadd(day,@day-1,@date) 

if @date <= getdate()-1 
    set @date = dateadd(year,1,@date) 

select @date 

Como alternativa, para crear una cadena en formato AAAAMMDD:

set @date = 
    right('0000'+convert(char(4),year(getdate())),4) 
+ right('00'+convert(char(2),@month),2) 
+ right('00'+convert(char(2),@day),2) 

Otro método, que evita literales todos juntos:

declare @month tinyint 
declare @day tinyint 
set @month = 6 
set @day = 24 

declare @date datetime 
declare @today datetime 

-- get todays date, stripping out the hours and minutes 
-- and save the value for later 
set @date = floor(convert(float,getdate())) 
set @today = @date 

-- add the appropriate number of months and days 
set @date = dateadd(month,@month-month(@date),@date) 
set @date = dateadd(day,@day-day(@date),@date) 

-- increment year by 1 if necessary 
if @date < @today set @date = dateadd(year,1,@date) 

select @date 
1

Aquí está mi ejemplo sql hasta ahora. Realmente no me gusta, aunque ...

DECLARE @month tinyint, 
    @day tinyint, 
    @date datetime 

SET @month = 1 
SET @day = 1 

-- SET DATE TO DATE WITH CURRENT YEAR 
SET @date = CONVERT(datetime, CONVERT(varchar,@month) + '/' + CONVERT(varchar,@day) + '/' + CONVERT(varchar,YEAR(GETDATE()))) 


-- IF DATE IS BEFORE TODAY, ADD ANOTHER YEAR 
IF (DATEDIFF(DAY, GETDATE(), @date) < 0) 
BEGIN 
    SET @date = DATEADD(YEAR, 1, @date) 
END 

SELECT @date 
+2

No utilice el formato MM/DD/YYYY para los literales de fecha. Use AAAAMMDD en su lugar. Evitará problemas de localización y se ordena adecuadamente. –

+0

De lo contrario, no veo ningún problema con su método. ¿No le gusta la conversión de un literal? –

+0

Parece algo que debería ser una solución fácil. –

1

he aquí una solución con PostgreSQL

your_date_calculated = Year * 10000 + Month * 100 + Day 

le da una fecha como 20090623.

select cast(cast(your_date_calculated as varchar) as date) + 1 
1

aquí está mi versión. El núcleo de la misma está a sólo dos líneas, usando la función DATEADD, y no se requiere ninguna conversión a/de cuerdas, flotadores o cualquier otra cosa:

DECLARE @Month TINYINT 
DECLARE @Day TINYINT 

SET @Month = 9 
SET @Day = 7 

DECLARE @Result DATETIME 

SET @Result = 
    DATEADD(month, ((YEAR(GETDATE()) - 1900) * 12) + @Month - 1, @Day - 1) 
IF (@Result < GETDATE()) 
    SET @Result = DATEADD(year, 1, @Result) 

SELECT @Result 
+0

Agradable. ¿Qué tal una versión en línea para evitar la sobrecarga de llamada de función? por ejemplo, SELECT DATEADD (año, , DATEADD (mes, ((AÑO (GETDATE()) - 1900) * 12) + MonthField - 1, DayField - 1)) como NewDate FROM .... –

Cuestiones relacionadas