Подтвердить что ты не робот

Как конвертировать число недель в дату?

Учитывая год и календарную неделю, как я могу получить вторник этой недели в качестве даты?

4b9b3361

Ответ 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], чтобы получить соответствующую дату

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

Ответ 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