As others have mentioned, you may find a bitfield easier to work with than shifting and or'ing to align the bits. A bitfield is declared as a normal structure, but allows segregating bits between the members of the structure. For your year, month, day, you could use something similar to:
typedef struct { /* bitfield for year, month, day */
unsigned year : 11,
mon : 4,
day : 4;
} datebits;
The datebits struct segregates the first 11 bits for the year, the next 4 for the month, and the final 4 for the day. You use it just like any other struct. Here is a short example:
#include <stdio.h>
typedef struct { /* bitfield for year, month, day */
unsigned year : 11,
mon : 4,
day : 4;
} datebits;
typedef union { /* union to avoid violating strict aliasing */
datebits d; /* when shifting datebits to print binary bits */
unsigned u; /* (this is only for putchar bit output) */
} duu;
int main (void) {
unsigned i = 19;
datebits d; /* declare bitfield */
duu du;
d.year = 1999; /* fill bitfield */
d.mon = 12;
d.day = 2;
du.d = d;
printf ("\n year : %u month : %u day : %u\n\n (bits in memory) d : ",
d.year, d.mon, d.day);
while (i--) /* verification of each bit in memory */
putchar ((du.u >> i) & 1 ? '1' : '0');
putchar ('\n');
return 0;
}
Output
$ ./bin/bitfield_datebits
year : 1999 month : 12 day : 2
(bits in memory) d : 0010110011111001111
(note: the union is just to facilitate the binary printing of the individual bits, it is not needed for normal use of datebits).
As you can see your day is 0010, your month 1100 and the year 11111001111 in proper order.