C/C++ Date Solution/Conversion


I need to come up with a way to unpack a date into a readable format. unfortunately I don't completely understand the original process/code that was used.

Per information that was forwarded to me the date was packed using custom C/Python code as follows;

  date = year << 20;
  date |= month << 16;
  date |= day << 11;
  date |= hour << 6;
  date |= minute;

For example, a recent packed date is 2107224749 which equates to Tuesday Sept. 22 2009 10:45am

I understand....or at least I am pretty sure....the << is shifting the bits but I am not sure what the "|" accomplishes.

Also, in order to unpack the code the notes read as follows;

year = (date & 0xfff00000) >> 20;
month = (date & 0x000f0000) >> 16;
day = (date & 0x0000f800) >> 11;
hour = (date & 0x000007c0) >> 6;
minute = (date & 0x0000003f);

Ultimately, what I need to do is perform the unpack and convert to readable format using either JavaScript or ASP but I need to better understand the process above in order to develop a solution.

Any help, hints, tips, pointers, ideas, etc. would be greatly appreciated.

asked on Stack Overflow Sep 23, 2009 by (unknown user) • edited Sep 23, 2009 by unwind

6 Answers


The pipe (|) is bitwise or, it is used to combine the bits into a single value.

The extraction looks straight-forward, except I would recommend shifting first, and masking then. This keeps the constant used for the mask as small as possible, which is easier to manage (and can possibly be a tad more efficient, although for this case that hardly matters).

Looking at the masks used written in binary reveals how many bits are used for each field:

  • 0xfff00000 has 12 bits set, so 12 bits are used for the year
  • 0x000f0000 has 4 bits set, for the month
  • 0x0000f800 has 5 bits set, for the day
  • 0x000007c0 has 5 bits set, for the hour
  • 0x0000003f has 6 bits set, for the minute
answered on Stack Overflow Sep 23, 2009 by unwind • edited Sep 23, 2009 by unwind

The idea is exactly what you said. Performing "<<" just shifts the bits to the left. What the | (bitwise or) is accomplishing is basically adding more bits to the number, but without overwriting what was already there.

A demonstration of this principle might help.

Let's say we have a byte (8 bits), and we have two numbers that are each 4 bits, which we want to "put together" to make a byte. Assume the numbers are, in binary, 1010, and 1011. So we want to end up with the byte: 10101011.

Now, how do we do this? Assume we have a byte b, which is initialized to 0.

If we take the first number we want to add, 1010, and shift it by 4 bits, we get the number 10100000 (the shift adds bytes to the right of the number).

If we do: b = (1010 << 4), b will have the value 10100000.

But now, we want to add the 4 more bits (0011), without touching the previous bits. To do this, we can use |. This is because the | operator "ignores" anything in our number which is zero. So when we do:

10100000 (b's current value)
00001011 (the number we want to add)
We get:
10101011 (the first four numbers are copied from the first number, 
          the other four numbers copied from the second number).

Note: This answer came out a little long, I'm wikiing this, so, if anyone here has a better idea how to explain it, I'd appreciate your help.

answered on Stack Overflow Sep 23, 2009 by Edan Maor

Yes the << shifts bits and the | is the bitwise OR operator.

answered on Stack Overflow Sep 23, 2009 by RobertL • edited Jan 5, 2013 by iforce2d

In the decode section & is bit wise and the 0xfff00000 is a hexadecimal bit mask. Basically each character in the bit mask represents 4 bits of the number. 0 being 0000 in binary and f being 1111 so if you look at the operation in binary you are anding 1111 1111 1111 0000 0000 ... with whatever is in date so basically you are getting the upper three nibbles(half bytes) and shifting them down so that 00A00000 gives you 10(A in hex) for the year.

Also note that |= is like += it is bit wise or then assignment rolled in to one.

answered on Stack Overflow Sep 23, 2009 by stonemetal

Just to add some practical tips:

minute = value & ((1 << 6)-1);
hour = (value >> 6) & ((1<<5)-1);  // 5 == 11-6 == bits reserved for hour

1 << 5 creates a bit at position 5 (i.e. 32=00100000b),
(1<<5)-1 cretaes a bit mask where the 5 lowest bits are set (i.e. 31 == 00011111b)

x & ((1<<5)-1) does a bitwise 'and' preserving only the bits set in the lowest five bits, extracting the original hour value.

answered on Stack Overflow Sep 23, 2009 by peterchen

User contributions licensed under CC BY-SA 3.0