If the purpose is to store the DateTime as a number and recreate it later, I would not write custom code to create a
uint
, but I would use a
long
and use the built-in ToBinary (and FromBinary) method.
ToBinary[
^]:
DateTime dt = ...;
long bin = dt.ToBinary();
FromBinary[
^]:
long bin = ...;
DateTime dt = DateTime.FromBinary(bin);
[Edit]
As you said that you really need a uint because of a database, I built some code that reverses the logic of your serialization algorithm. How it works: your serialization algorithm makes sure that all parts of the date (minute, hour, ...) are at a specific location in the series of bits, so the deserializer extracts that series, shifts it to the right so the decimal value is correct, and puts that in a new DateTime object.
Two very important things to consider:
1) This will only work for the years 2000 till 2255 (both included), because of your 'byte year = ...' line. If this is undesired, you need to come up with a different serialization; my deserialization code can give you some ideas for the reverse.
2) The number of seconds in each date is lost because it's not stored. The deserialization code sets it to 0.
public static DateTime ToDateTime(this uint value)
{
int year = (byte)(255 & value) + 2000;
int month = (int)((7936 & value) >> 8);
int day = (int)((516096 & value) >> 13);
int hour = (int)((33030144 & value) >> 19);
int minute = (int)((2113929216 & value) >> 25);
return new DateTime(year, month, day, hour, minute, 0);
}
To give a more detailed explanation on what this does, I'll take 'month' as example, but it's the same for the other values.
In the serialized format, the month is stored from the 9th bit (included) till the 13th bit (included) (right-to-left), so 5 bits. This means that the information we want to learn about, can be represented as:
00000000000000000001111100000000
, or
7936
. Because we use the
&
operator, those
1
s in that integer will become
0
s if they are also zeroes in
value
. After this, we have our desired 'month' value in the middle of the bit sequence: we use the right shift
>> 8
to put the value at the 'front' (seen from the right) of the bit sequence, so the decimal value is the actual month.