Учитывая год и календарную неделю, как я могу получить вторник этой недели в качестве даты?
Как конвертировать число недель в дату?
Ответ 1
Если у вас есть year
и cw
(неделя календаря) в качестве переменных (например, из инструкции SELECT), вы можете получить DATE следующим образом:
DATE_SUB(
DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK),
INTERVAL WEEKDAY(
DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK)
) -1 DAY),
Фраза DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK)
дублируется; не хотел хранить переменную. SQL-Statement хорошо работал у меня в MySQL.
ОБНОВЛЕНИЕ: Только для уточнения: WEEKDAY(DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK))
даст первый день недели. Выделение числа из него (-1 для вторника, -2 для среды и т.д. Выберет конкретный день недели для вас).
См. здесь.
Ответ 2
В MySQL STR_TO_DATE()
может сделать трюк всего за одну строку!
Пример: мы хотим получить дату Tuesday
32
й недели 2013
.
SELECT STR_TO_DATE('2013 32 Tuesday', '%X %V %W');
будет выводить:
'2013-08-13'
Я думаю, что это лучшее и самое короткое решение вашей проблемы.
Ответ 3
Определения календарной недели я нашел, что все сказали "период в семь дней подряд, начиная с воскресенья".
Ниже приведено описание MySQL... ваш пробег может меняться...
DATE_ADD (MAKEDATE (год, 1), INTERVAL cw WEEK) добавляет недели с 1-го года, что неверно...
mysql> select DATE_ADD(MAKEDATE(2011, 1), INTERVAL 1 WEEK);
+----------------------------------------------+
| DATE_ADD(MAKEDATE(2011, 1), INTERVAL 1 WEEK) |
+----------------------------------------------+
| 2011-01-08 |
+----------------------------------------------+
По этому определению имеет смысл иметь диапазон календарных недель от 1-53, и это означает, что это воскресенье этой недели. Таким образом, мы добавим 2 дня к n-му воскресенью года, чтобы попасть во вторник.
Следующее получает дату первого воскресенья года...
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 |
+------------------------------------------------------------------------+
чтобы это получило дату 10-го воскресенья (нота-интервал 9 недель с тех пор, как мы уже достигли 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 |
+-----------------------------------------------------------------------------------------------------+
добавьте еще 2 дня, чтобы добраться до вторника...
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 |
+--------------------------------------------------------------------------------------------------------------------------------+
или более широко:
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
);
Ответ 4
Посмотрев на ответ Indago и выполнив несколько тестов, я получил результаты на следующей неделе.
Я сделал небольшую корректировку, и даты совпадают:
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
Вы можете сравнить результаты с здесь.
Ответ 5
Хорошо теоретически вы можете использовать DATEPART с параметром dw, чтобы найти первый вторник месяца, а затем добавить 7 * [CalenderWeek], чтобы получить соответствующую дату
Ответ 6
Вот пример, который может помочь:
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
и результат:
2011-08-16 00:00:00.000
который сегодня (вторник).
Ответ 7
Я думаю, что было бы проще написать логику функции с помощью php.
Если вы используете php script, вы можете поместить все даты в формате, подобном "day-month-year", и использовать цикл, чтобы проходить каждый день (с 1980-х до 2038 или из столбца дат mysql).
http://www.php.net/manual/en/function.date-format.php
Затем используйте формат даты в датах в этом цикле, чтобы преобразовать их в дни недели.
Вот список вещей, которые можно использовать в форматах даты. http://www.php.net/manual/en/function.date.php D N L вес все помогут вам в день недели.
Ответ 8
Данные решения не учитывают, что первая неделя года может начаться в конце декабря. Поэтому мы должны проверить, если 1 января относится к календарю недели или нового года:
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
Это приведет к:
+------------+------------+------------+
| WeekOfYear | Monday | Sunday |
+------------+------------+------------+
| 2014-1 | 2013-12-30 | 2014-01-05 |
+------------+------------+------------+
Ответ 9
DELIMITER $$
CREATE FUNCTION fn_yearweek_to_date(
var_yearweek INTEGER UNSIGNED,
var_weekday ENUM(
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday'
)
)
RETURNS DATE DETERMINISTIC
BEGIN
RETURN STR_TO_DATE(CONCAT(var_yearweek, var_weekday), '%x%v%W');
END;
DELIMITER ;
SELECT
fn_yearweek_to_date(YEARWEEK(NOW(), 1), 'Sunday'),
fn_yearweek_to_date(YEARWEEK(NOW(), 1), 7)
;
Ответ 10
Рекомендуемое решение работало для меня в 2014 и 2015 годах, но не работало для меня в 2016 году (возможно, потому, что начало Года в понедельник, а не в воскресенье.
Я использовал следующую функцию, чтобы исправить это:
STR_TO_DATE ( CONCAT (mod (day_nr + 1, 7), '/', week_nr, '/', year), '% w/% u/% Y')
В моих данных: day_nr = 0 → Понедельник,
day_nr = 6 → Sunday
Поэтому мне пришлось исправить это с помощью функции mod