& - оператор, выполняющий побитовое И"|"побитовый ИЛИ. См. здесь и здесь . Также см. здесь для объяснения использования побитового И / ИЛИ для хранения нескольких числовых значений в одном числовом столбце. Эта часть:
@iDate&0xfff0000
будет «маскировать» или исключать / заменять нулями ту часть iDate, которая отличается от 256 ^ 2. Затем вы делите на 65536 - что просто меняет исходную математику умножения года на 65536.
Если концепция побитового И чужеродна, я приведу пример, который НЕ РАБОТАЕТ в десятичном виде. Битовое И преобразует все это в двоичное, а затем маскирует вещи (например, подсеть IP, если вы знакомы с этим).
В любом случае, рассмотрите десятичное число 20171012. Если такое понятие как десятичное Исуществует, это может выглядеть как 20171012&11110000
. Места "1" - это "хранители", а места "0" - "выбрасывание". Если вы сложите их вертикально, результатом будет сохранение значений с «1» под ними и замена значений с «0» под ними на «0».
number 20171012
dec-wise AND 11110000
result 20170000
теперь результат равенЭто не 2017 год, поэтому вам придется разделить на 10000, чтобы получить 2017 год. Для 20171012&1100
вы должны использовать подразумеваемые лидирующие нули:
number 20171012
dec-wise AND 00001100
result 1000
Я, вероятно, преобразовал бы в int, добавив год *10000 и месяц * 100 и день. Возвращаясь назад, я бы использовал комбинацию целочисленного деления и MOD. Но я думаю, что побитовое И, возможно, немного более элегантно (особенно для получения месяца).
На основе вашего комментария я расскажу, как я конвертировал даты в int и возвращал обратно:
declare @dDate date = '2017-10-12'
declare @iDate int
set @iDate = year(@dDate) * 10000 + month(@dDate) * 100 + day(@dDate)
select @iDate
select 'year', @iDate/10000 -- basic integer division provides the year
select 'month', (@iDate % 10000)/100 -- combine modulo and integer division to get the month
select 'day', @iDate % 100 -- basic modulo arithmetic provides the day
возвращает:
20171012
year 2017
month 10
day 12