Étant donné une année et une semaine calendaire, comment puis-je obtenir le mardi de cette semaine comme date?
Si vous avez year
et cw
semaine de calendrier) en tant que variables (par exemple, à partir d'une instruction SELECT), vous pouvez obtenir la DATE comme suit:
DATE_SUB(
DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK),
INTERVAL WEEKDAY(
DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK)
) -1 DAY),
La phrase DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK)
est dupliquée; ne voulait pas stocker une variable. La déclaration SQL a bien fonctionné pour moi avec MySQL.
UPDATE: Juste pour clarification: WEEKDAY(DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK))
donnera le premier jour de la semaine. En soustraire un nombre (-1 pour mardi; -2 pour mercredi, etc. sélectionnera un jour spécifique de la semaine pour vous). Voir _ (ici .
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 32
th 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.
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
);
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 .
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 |
+------------+------------+------------+
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).
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.
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.