2011-08-16 9 views

Respuesta

17

Dado que tiene year y cw (semana calendario) como variables (por ejemplo, a partir de una instrucción SELECT) se puede obtener la fecha de la siguiente manera:

DATE_SUB(
    DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK), 
    INTERVAL WEEKDAY(
    DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK) 
) -1 DAY), 

la frase es reproducir de DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK) ted; no quería almacenar una variable El SQL-Statement funcionó muy bien para mí en MySQL.

ACTUALIZACIÓN: Solo por aclaración: WEEKDAY(DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK)) rendirá el primer día de la semana. Al sustraer un número de él (-1 para el martes, -2 para el miércoles, etc., seleccionará un día específico de la semana para usted). Ver here.

+0

Ten en cuenta que existen diferentes normas 'sql?' de los números de semana! El sistema de los EE. UU. (Semana con Jan1 = semana1) puede ser diferente del sistema ISO (semana con el primer jueves del año = semana1). Así que asegúrese de probar esto contra su definición prevista de una semana. – Eljakim

+0

@Eljakim que es correcto y en realidad es una de las razones por las cuales la aritmética de la "semana del año" de alguna manera tiene poco respaldo de MySQL. Lo mejor es no usarlos en absoluto. De hecho, la migración LEJOS DE 'semana del año' es la razón por la que escribí esa consulta una vez. – nre

+0

No use 'MAKEDATE' para esto, construirá fechas incorrectas, especialmente cuando usa fechas comerciales y un número de semana calendario. Por ejemplo, 'MAKEDATE (2017, 1)' le dará 'Sun, 01 Jan 2017', * mientras que esta es realmente la 52ª semana de 2016 * y la primera semana de 2017 comienza el 2 de enero. En su lugar, use este 'STR_TO_DATE ('2017 1 Monday', '% x% v% W')' para obtener el 'Monday' de la semana correcta 'Mon, 02 Jan 2017' –

0

Aquí es un ejemplo que podría ayudar:

SET DATEFIRST 1 
declare @wk int set @wk = 33 
declare @yr int set @yr = 2011 

select dateadd (week, @wk, dateadd (year, @yr-1900, 0)) - 2 - 
    datepart(dw, dateadd (week, @wk, dateadd (year, @yr-1900, 0)) - 4) as date 

y el resultado es:

2011-08-16 00:00:00.000 

que es hoy (martes).

0

Creo que sería más fácil escribir la lógica de la función usando php.

Si usa un script php, puede poner todas las fechas en un formato similar a "día-mes-año" y usar un bucle para pasar todos los días (desde 1980 hasta 2038 o desde la columna de fechas de mysql).

http://www.php.net/manual/en/function.date-format.php

A continuación, utilice el formato de fecha en las fechas en que bucle para convertirlos en los días de la semana.

Aquí hay una lista de cosas que se pueden utilizar en los formatos de fecha. http://www.php.net/manual/en/function.date.php D N l w te ayudan con el día de la semana.

9

Las definiciones de la semana calendario que encontré todas dijeron "un período de siete días consecutivos comenzando el domingo".

El siguiente es específica de MySQL ... su experiencia puede variar ...

DATE_ADD (MAKEDATE (año, 1), SEMANA cw INTERVALO) añade las semanas desde la primera del año, lo que no es correcto. ..

mysql> select DATE_ADD(MAKEDATE(2011, 1), INTERVAL 1 WEEK); 
+----------------------------------------------+ 
| DATE_ADD(MAKEDATE(2011, 1), INTERVAL 1 WEEK) | 
+----------------------------------------------+ 
| 2011-01-08         | 
+----------------------------------------------+ 

Según esta definición, que sólo tiene sentido tener el rango semana Calendario de 1-53, y tener esta representa el domingo de esa semana. Como tal, sumaríamos 2 días al n. ° domingo del año para recibir el martes.

Lo siguiente obtiene la fecha del primer domingo del año ...

mysql> select date_add('2012-01-01', interval (8 - dayofweek('2011-01-01')) % 7 DAY); 
+------------------------------------------------------------------------+ 
| date_add('2012-01-01', interval (8 - dayofweek('2011-01-01')) % 7 DAY) | 
+------------------------------------------------------------------------+ 
| 2012-01-02                | 
+------------------------------------------------------------------------+ 

por lo que este será obtener la fecha del 10º Domingo (intervalo de la nota 9 semana desde ya estamos en 1) ...

mysql> select date_add(date_add('2010-01-01', interval (8 - dayofweek('2010-01-01')) % 7 DAY) , interval 9 week); 
+-----------------------------------------------------------------------------------------------------+ 
| date_add(date_add('2010-01-01', interval (8 - dayofweek('2010-01-01')) % 7 DAY) , interval 9 week) | 
+-----------------------------------------------------------------------------------------------------+ 
| 2010-03-07                       | 
+-----------------------------------------------------------------------------------------------------+ 

Añadir 2 días más para llegar a Martes ...

mysql> select date_add(date_add(date_add('2010-01-01', interval (8 - dayofweek('2010-01-01')) % 7 DAY) , interval 9 week), interval 2 day); 
+--------------------------------------------------------------------------------------------------------------------------------+ 
| date_add(date_add(date_add('2010-01-01', interval (8 - dayofweek('2010-01-01')) % 7 DAY) , interval 9 week), interval 2 day) | 
+--------------------------------------------------------------------------------------------------------------------------------+ 
| 2010-03-09                              | 
+--------------------------------------------------------------------------------------------------------------------------------+ 

o más generalmente:

select 
date_add( 
    date_add( 
     date_add('<year>-01-01', interval (8 - dayofweek('<year>-01-01')) % 7 DAY) 
     , interval <week-1> week) 
    , interval <dayOfWeek> day 
); 
50

¡En MySQL, la función STR_TO_DATE() puede hacer el truco en una sola línea! Ejemplo queremos obtener la fecha del martes de la 32 ª semana del año 2013.

SELECT STR_TO_DATE('201332 Tuesday', '%X%V %W'); 

seria:

'2013-08-13' 

Creo que esta es la mejor y la más corta solución a tu problema.

+2

Esto fue genial @indago, exactamente lo que estaba buscando. Y mucho más elegante que las otras soluciones. – Voodoo

+1

¡Muy elegante! Al construir la cadena YYYYCW para 'STR_TO_DATE()' puedes usar esto '... STR_TO_DATE (CONCAT (AÑO (campo), LPAD (WEEKOFYEAR (campo, 2, '0')) ..' –

+0

@AlBundy puedes use esto para extraer de la fecha actual o de un campo particular como lo ha mostrado anteriormente, simplemente reemplace 'CURDATE()' con su 'date_field' como este ' SELECT STR_TO_DATE (CONCAT (AÑO (CURDATE()), LPAD (WEEKOFYEAR (CURDATE()), 2, '0'), '', DAYNAME (CURDATE())), '% X% V% W'); ' – indago

0

Given solutions no considera, que la primera semana de un año puede comenzar a finales de diciembre. Así que hay que comprobar, si la 1ª de enero de pertenece a calendarweek de viejo o nuevo año:

SET @week=1; 
SET @year=2014; 
SET @x_weeks_after_new_year=DATE_ADD(MAKEDATE(@year, 1), INTERVAL (SELECT IF(WEEKOFYEAR(MAKEDATE(@year, 1))>50 , 0 , -1))[email protected] WEEK); 
SELECT 
    CONCAT(@year, '-', @week) WeekOfYear, 
    @weekStart:=DATE_SUB(@x_weeks_after_new_year, INTERVAL WEEKDAY(@x_weeks_after_new_year) DAY) Monday, 
    DATE_ADD(@weekStart, INTERVAL 6 DAY) Sunday 

Esto dará como resultado:

+------------+------------+------------+ 
| WeekOfYear | Monday | Sunday | 
+------------+------------+------------+ 
| 2014-1 | 2013-12-30 | 2014-01-05 | 
+------------+------------+------------+ 
0

Al analizar la respuesta Indago y luego hacer un montón de pruebas, estaba recibiendo la semana siguiente como los resultados.

Hice un ajuste menor y las fechas coinciden.

STR_TO_DATE ('# {year_week} Lunes', '% x% v% W') - inicio de la semana

STR_TO_DATE ('# {year_week} Domingo', '% x% v% W') - fin de semana

Usted puede comparar los resultados que aquí http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php?year=2015

-1

la solución upvoted trabajó para mí en 2014 y 2015, pero no funcionó para mí en 2016 (posiblemente debido a que el inicio del año es el lunes y no el domingo.

Utilicé la siguiente función para corregir esto:

STR_TO_DATE ( CONCAT (mod (day_nr + 1, 7), '/', week_nr, '/', año), '% w /% u /% Y')

En mi datos: day_nr = 0 -> lunes,

day_nr = 6 -> Domingo

así que tuve que arreglar eso con una función mod

Cuestiones relacionadas