Неправильный расчет номер недели в году?

1. CaSH_2004 374 22.05.12 11:23 Сейчас в теме
1С как то интересно определяет номер недели в году, просто берет количество недель, в то время как существует стандарт ISO 8601 и соответствующий ему межгосударственный стандарт ГОСТ ИСО 8601-2001 "ПРЕДСТАВЛЕНИЕ ДАТ И ВРЕМЕНИ".

По данному стандарту, первой неделей года является та неделя, на которую попадает первый четверг данного года. То есть в 2012 году первый четверг года попадает на 5 января. Значит 1 неделя 2012 года начинается со 2 января 2012 года. 1 января 2012 попадает на последнюю неделю 2011 года (для 2011 года - неделя под номером 52). Все это может приводить к доволе интересным результатам: год может содержать 52 или 53 недели. 29, 30, 31 декабря могут относиться к первой неделе следующего года (в случае попадания 1 января следующего года на четверг). Также может случиться наоборот, что 1, 2, и 3 января могут относиться к последней недели прошлого года (52 или 53 неделя в зависимости от года).

Итак, для чего 1С так считает - для самой себя или я что-то ни так понимаю?
Торговцы требуют корректного номера недели.
Например 14 по 20 мая НеделяГода() возвращает 21, а на календаре 20
Это что разные понятия?
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. CaSH_2004 374 22.05.12 11:29 Сейчас в теме
Согласно стандарту получается что нужно еще делать так (код на 7.7):

	НомерНеделиГода_ = НомерНеделиГода(НачДата);
	Если НомерДняНедели(НачГода(НачДата)) > 4 Тогда
		НомерНеделиГода_ = НомерНеделиГода_ -  1;
	КонецЕсли;
4. Kostalmed 24 28.11.12 16:03 Сейчас в теме
(2) CaSH_2004, Для 1С 8 код выглядит следующим образом.

НомерНеделиГода_ = НеделяГода(СсылкаНаОбъект.Дата);

Если ДеньНедели(НачалоГода(СсылкаНаОбъект.Дата)) > 4 Тогда
НомерНеделиГода_ = НомерНеделиГода_ - 1;
КонецЕсли;
3. ekorshunov 28.11.12 14:16 Сейчас в теме
Для некоторых дат: 01.01.2012, 01.01.2016, 01.01.2017 - исправленная функция вернет 0
5. ekorshunov 28.11.12 16:33 Сейчас в теме
Более корректным будет такой код, т.к. в указанном ГОСТ-е также сказано, что первой неделей считается та, в которой содержится 04 января.

Функция глНомерНеделиГода(_дата) Экспорт

	ЧетвертоеЯнваря = НачГода(_дата) + 3; 
	НачалоПервойНедели = НачНедели(ЧетвертоеЯнваря);  

	Если _дата < НачалоПервойНедели Тогда
		// дата принадлежит последней неделе прошлого года.
		Возврат глНомерНеделиГода(Дата(ДатаГод(_дата)-1, 12, 31));
	Иначе
		// получаем разницу дат в неделях.
		КоличествоНедель = Цел((НачНедели(_дата) - НачалоПервойНедели)/7);
		Возврат 1 + КоличествоНедель;
	КонецЕсли;

КонецФункции	// глНомерНеделиГода()
Показать
6. sulfur17 66 13.04.16 12:53 Сейчас в теме
(5) ekorshunov,
т.к. в указанном ГОСТ-е также сказано, что первой неделей считается та, в которой содержится 04 января.

Это где такое сказано?
Вот дословно:

текст ISO

first Thursday - это первый четверг, а не четвертое число.

Функция должна быть такая:
Функция НеделяГодаПоISO8601(Знач Дата, Год=Неопределено) Экспорт
	Если ДеньНедели(НачалоГода(Дата)) <= 4 тогда //если первая неделя года начинается до четверга, т.е. в ней есть четверг
		//значит год начинается с первой недели
		Год = Год(Дата);
		Возврат НеделяГода(Дата);
	Иначе
		//год начинается с последней недели прошлого года
		Год = Год(Дата) - 1;
		Возврат НеделяГодаПоISO8601(НачалоГода(Дата)-1);
	КонецЕсли;
КонецФункции
Показать
7. Fox-trot 164 13.04.16 15:51 Сейчас в теме
(6) sulfur17, а для чего второй параметр "Год"?
8. sulfur17 66 13.04.16 19:46 Сейчас в теме
(7) Fox-trot, у вас год может начаться с 53 недели и закончиться 53 неделей.
Вы можете забыть об этом и сгруппировать по номеру недели, и получите неправильные данные.
Параметр Год - это напоминание о таком подводном камне.
Когда будете вызывать мою функцию, то увидите этот параметр и вспомните.
9. sulfur17 66 19.04.16 15:56 Сейчас в теме
Исправляю свою ошибку в (6).
Вот правильный код:
Функция НеделяГодаПоISO8601(Знач Дата, Год=Неопределено) Экспорт
	Если ДеньНедели(НачалоГода(Дата)) <= 4 тогда //если первая неделя года начинается до четверга, т.е. в ней есть четверг
		//значит год начинается с первой недели
		Год = Год(Дата);
		Неделя = НеделяГода(Дата);
		Возврат Неделя;
	Иначе
		//год начинается с последней недели прошлого года
		Неделя = НеделяГода(Дата)-1;
		
		Если Неделя = 0 тогда //если это до первой недели года
			Неделя = НеделяГодаПоISO8601(НачалоГода(Дата)-1, Год); //значит это последняя неделя прошлого года
		Иначе
			Год = Год(Дата);
		КонецЕсли;
	КонецЕсли;
	
	Возврат Неделя;
КонецФункции
Показать
10. Fox-trot 164 20.04.16 18:49 Сейчас в теме
(9) sulfur17, тебе там за количество буков платят чтоли? завем два раза писАть Возврат Неделя;?
12. cameron_rifkin 03.02.17 17:06 Сейчас в теме
(6)Собственно эти параметры равнозначны. Если в неделе есть четверг, то в ней как минимум 4 дня, т.е. даже если четверг - 1 число, то воскресенье - 4, так что в той неделе, где есть четверг, всегда будет и 4 число
11. angryprog 22.04.16 07:51 Сейчас в теме
Сегодня столкнулся с данной проблемой, написал такую функцию для расчета:
Функция НеделяГода_ISO8601(Дата)
	
	Корректировочная = НеделяГода(Дата(Год(Дата),1,4)) - 1;
	Результат = НеделяГода(Дата) - Корректировочная;
	Результат = ?(Результат = 0, НеделяГода_ISO8601(ДобавитьМесяц(КонецГода(Дата), -12)), Результат);
	
	Возврат Результат;
	
КонецФункции
Показать
ttsshh; cameron_rifkin; +2 Ответить
13. sergiz 14.12.17 10:33 Сейчас в теме
Сегодня устранял неправильный расчет номер недели в году в запросе.

Для решения задачи использовал следствие из стандарта ISO 8601 - неделя, в которой 1 января это понедельник, вторник, среда или четверг.

Согласно рекомендациям международного стандарта ISO 8601 (пункт 2.2.10), первой неделей года считается неделя, содержащая первый четверг года, что эквивалентно следующим выражениям:
1) неделя, содержащая 4 января;
2) неделя, в которой 1 января это понедельник, вторник, среда или четверг;
3) неделя, которая содержит как минимум четыре дня нового года.
Источник https://ru.wikipedia.org/wiki/%D0%9D%D0%B5%D0%B4%D0%B5%D0%BB%D1%8F#Календарная_неделя_и_её_нумерация

Код:

ВЫБРАТЬ
	ВЫБОР
		КОГДА ДЕНЬНЕДЕЛИ(НАЧАЛОПЕРИОДА(&Дата, ГОД)) < 5
			ТОГДА НЕДЕЛЯ(&Дата)
		ИНАЧЕ ВЫБОР
				КОГДА НЕДЕЛЯ(&Дата) = 1
					ТОГДА 53
				ИНАЧЕ НЕДЕЛЯ(&Дата) - 1
			КОНЕЦ
	КОНЕЦ КАК НомерНеделиПоISO8601
Показать


И функция приобретает вид:

Функция НеделяГода_ISO8601(Дата)
	
	Если ДеньНедели(НачалоГода(Дата)) < 5 Тогда 
	    Результат = НеделяГода(Дата);
	ИначеЕсли НеделяГода(Дата) = 1 Тогда
	    Результат = 53;
	Иначе
	    Результат = НеделяГода(Дата) - 1;
	КонецЕсли;
	
    Возврат Результат;
    
КонецФункции
Показать


Возможно, это решение будет полезно не только мне. Делюсь с Вами.
16. Anesk 17 20.01.23 12:20 Сейчас в теме
(13)
ВЫБРАТЬ
ВЫБОР
КОГДА ДЕНЬНЕДЕЛИ(НАЧАЛОПЕРИОДА(&Дата, ГОД)) < 5
ТОГДА НЕДЕЛЯ(&Дата)
ИНАЧЕ ВЫБОР
КОГДА НЕДЕЛЯ(&Дата) = 1
ТОГДА 53
ИНАЧЕ НЕДЕЛЯ(&Дата) - 1
КОНЕЦ
КОНЕЦ КАК НомерНеделиПоISO8601


Все прекрасно, только номер предыдущего года не всегда 53. Может и 52 быть.
Доработал немного, для тех кто ищет как определить номер недели в запросе

 ВЫБРАТЬ
   ВЫБОР
      КОГДА ДЕНЬНЕДЕЛИ(НАЧАЛОПЕРИОДА(&Дата, ГОД)) < 5
      ТОГДА НЕДЕЛЯ(&Дата)
      ИНАЧЕ ВЫБОР
              КОГДА НЕДЕЛЯ(&Дата) = 1
              ТОГДА ВЫБОР
              			КОГДА ДЕНЬНЕДЕЛИ(ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&Дата, ГОД), СЕКУНДА, -1)) < 5
              			ТОГДА НЕДЕЛЯ(ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&Дата, ГОД), СЕКУНДА, -1))
              			ИНАЧЕ НЕДЕЛЯ(ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&Дата, ГОД), СЕКУНДА, -1))-1
              		КОНЕЦ 
              ИНАЧЕ НЕДЕЛЯ(&Дата) - 1
            КОНЕЦ
 КОНЕЦ КАК НомерНеделиПоISO8601
Показать
14. alest 25.01.18 17:03 Сейчас в теме
В представленных решениях неделя(понедельника 31-12-2018) = 53, а неделя(01-01-2019) = 1. Т.е. 53-я неделя 2018 года содержит 1 день?
Мне пользователи говорят, что 31-12-2018 это уже 1ая неделя 2019-го года...
15. docerman 74 28.09.18 13:39 Сейчас в теме
Вот так правильно:
Функция НеделяГода_ISO8601(Дата)
    
    Если ДеньНедели(НачалоГода(Дата)) < 5 Тогда 
        Результат = НеделяГода(Дата);
    ИначеЕсли НеделяГода(Дата) = 1 Тогда
        Результат = 52;
	Если ДеньНедели(НачалоГода(Дата)) = 5 Тогда
		Результат = 53;
	КонецЕсли;
    Иначе
        Результат = НеделяГода(Дата) - 1;
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот