Как конвертировать число недели в дату? - PullRequest
20 голосов
/ 16 августа 2011

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

Ответы [ 10 ]

55 голосов
/ 09 августа 2013

В MySQL функция STR_TO_DATE() может выполнить одну строчку!


Пример: мы хотим получить дату Tuesday 32 th неделя года 2013.

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

выдаст:

'2013-08-13'

Я думаю, что это лучшее и самое короткое решение вашей проблемы.

19 голосов
/ 16 августа 2011

Если у вас есть year и cw (неделя календаря) в качестве переменных (например, из оператора SELECT), вы можете получить ДАТУ следующим образом:

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 прекрасно работал для меня на MySQL.

ОБНОВЛЕНИЕ: Только для пояснения: WEEKDAY(DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK)) даст первый день недели.Вычитая из него число (-1 для вторника; -2 для среды и т. Д., Вы выберете конкретный день недели для вас).Смотри здесь .

9 голосов
/ 11 июля 2012

В определениях календарной недели, которые я нашел, говорилось, что «период из семи последовательных дней, начинающихся с воскресенья».

Ниже приведено описание, специфичное для MySQL ... Ваш пробег может отличаться ...

DATE_ADD (MAKEDATE (year, 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
);
2 голосов
/ 17 ноября 2015

Рассматривая ответ Индаго и затем проводя кучу тестов, я получал после недели в качестве результатов.

Я сделал небольшую корректировку, а затем совпадали даты:

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

Вы можете сравнить результаты с здесь .

1 голос
/ 19 июня 2019
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)
;
0 голосов
/ 28 марта 2016

Решение с голосованием работало для меня в 2014 и 2015 годах, но не работало для меня в 2016 году (возможно, потому что начало года - в понедельник, а не в воскресенье.

Я использовал следующую функцию, чтобы исправить это:

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

По моим данным: day_nr = 0 -> понедельник,

day_nr = 6 -> воскресенье

Так что мне пришлось исправить это с помощью функции мода

0 голосов
/ 19 августа 2013

Данные решения не учитывают, что первая неделя года может начаться в конце декабря. Поэтому мы должны проверить, принадлежит ли 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))+@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

Это приведет к:

+------------+------------+------------+
| WeekOfYear |   Monday   |   Sunday   |
+------------+------------+------------+
|   2014-1   | 2013-12-30 | 2014-01-05 |
+------------+------------+------------+
0 голосов
/ 16 августа 2011

Я думаю, что было бы легче написать логику функции, используя php.

Если вы используете скрипт php, вы можете поместить все даты в формат, подобный «день-месяц-год»и используйте цикл для просмотра каждого дня (с 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 мы все поможем вам с днем ​​недели.

0 голосов
/ 16 августа 2011

Вот пример, который может помочь:

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

, что сегодня (вторник).

0 голосов
/ 16 августа 2011

Теоретически вы можете использовать DATEPART с параметром dw, чтобы найти первый вторник месяца, а затем добавить 7 * [CalenderWeek], чтобы получить соответствующую дату

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...