web-dev-qa-db-fra.com

Comment convertir le nombre de semaines en date?

Étant donné une année et une semaine calendaire, comment puis-je obtenir le mardi de cette semaine comme date?

19
Cephalopod
18
nre

Dans MySQL, la fonction STR_TO_DATE() peut faire l'affaire en une seule ligne!


Exemple: nous voulons obtenir la date de la Tuesday du 32th semaine de l'année 2013

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

produirait:

'2013-08-13'

Je pense que c'est la solution la meilleure et la plus courte à votre problème.

55
indago

Les définitions de la semaine civile que j'ai trouvées m'ont toutes dit "une période de sept jours consécutifs commençant le dimanche".

Ce qui suit est spécifique à MySQL ... votre kilométrage peut varier ...

DATE_ADD (MAKEDATE (année, 1), INTERVAL cw SEMAINE) ajoute les semaines à partir du 1er de l'année ce qui n'est pas correct ...

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

Selon cette définition, il est uniquement utile d’avoir une semaine calendaire allant de 1 à 53 et de représenter le dimanche de cette semaine. En tant que tel, nous ajouterions 2 jours au nième dimanche de l'année pour obtenir le mardi.

Ce qui suit donne la date du premier dimanche de l'année ...

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                                                             |
+------------------------------------------------------------------------+

cela donnera donc la date du 10ème dimanche (notez l’intervalle de 9 semaines puisque nous sommes déjà à 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                                                                                          |
+-----------------------------------------------------------------------------------------------------+

ajoutez 2 jours de plus pour arriver à mardi ...

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                                                                                                                     |
+--------------------------------------------------------------------------------------------------------------------------------+

ou plus généralement:

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
);
9
Ethan Joffe

En regardant la réponse d'Indago puis en effectuant une série de tests, je recevais la semaine suivante comme résultat.

J'ai apporté un ajustement mineur et les dates ont alors été identiques:

SELECT STR_TO_DATE('2019 1 Monday', '%x %v %W') -- beginning of week

SELECT STR_TO_DATE('2019 1 Sunday', '%x %v %W') -- end of week

Vous pouvez comparer les résultats avec ici .

2
Warren Landis

Compte tenu des solutions ne considère pas, que la première semaine d'une année peut commencer à la fin de décembre. Nous devons donc vérifier si le 1er janvier appartient à calendarweek de l’ancien ou du nouvel an:

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))+@week 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

Cela se traduira par:

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

Voici un exemple qui pourrait aider:

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

et le résultat est:

2011-08-16 00:00:00.000

qui est aujourd'hui (mardi).

0
CrazyMPh

Je pense qu'il serait plus facile d'écrire la logique de la fonction en utilisant php.

Si vous utilisez un script php, vous pouvez mettre toutes les dates dans un format similaire à "jour-mois-année" et utiliser une boucle pour la parcourir tous les jours (de 1980 à 2038 ou à partir de votre colonne de dates mysql).

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

Utilisez ensuite le format de date sur les dates de cette boucle pour les convertir en jours de la semaine.

Voici une liste d'éléments pouvant être utilisés dans les formats de date. http://www.php.net/manual/en/function.date.php D N l w tous vous aider avec jour de la semaine.

0
obesechicken13

En théorie, vous pourriez utiliser DATEPART avec le paramètre dw pour trouver le premier mardi du mois, puis ajouter 7 * [CalenderWeek] pour obtenir la date appropriée.

http://msdn.Microsoft.com/en-us/library/ms174420.aspx

0
David