Click here to Skip to main content
15,886,110 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I have a method that converts a datetime value into a uint number but I wonder if its possible to convert it back into a datetime and if so how would I do that?

here is the method that converts the datetime into a uint:

C#
public static uint ToUIntTime(this DateTime pValue)
{
    uint minute = (uint)(pValue.Minute << 25);
    uint hour = (uint)((pValue.Hour & 0x3F) << 19);
    uint day = (uint)((pValue.Day & 0x3F) << 13);
    uint month = (uint)((pValue.Month & 0x1F) << 8);
    byte year = (byte)(pValue.Year - 2000);

    uint ret = 0;

    ret = ret | minute;
    ret = ret | hour;
    ret = ret | day;
    ret = ret | month;
    ret = ret | year;

    return ret;
}


What I have tried:

I have looked at how the bitwise OR operator works but dont really understand anyways how to get the values back to its original form (minute, hour, day, month and year).
Posted
Updated 20-Aug-17 6:53am

1 solution

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[^]:
C#
DateTime dt = ...;
long bin = dt.ToBinary();

FromBinary[^]:
C#
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.
C#
public static DateTime ToDateTime(this uint value)
{
    int year = (byte)(255 & value) + 2000; // note what I said about this!
    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 1s in that integer will become 0s 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.
 
Share this answer
 
v3
Comments
maxbre 20-Aug-17 12:59pm    
Yes, I would prefer that aswell but unfortunately this way is what I have to work with because this is the output that is saved in a database that both my application and other applications are reading.
Thomas Daniels 20-Aug-17 13:12pm    
It should be possible to reverse the bit operations logic -- but I don't know what the point of '& 0x3F' is. I may be missing something, but it looks pointless, and removing it would help with the reverting logic. Also, your 'year' calculation sounds dangerous: what about years under 2000? When reverting, how will you be sure between 1999 and 2255? (because you're casting -1 to a byte, thus underflowing, getting 255 again)
Thomas Daniels 20-Aug-17 13:33pm    
I built some deserialization code; see my edited answer for the code and an explanation.
maxbre 20-Aug-17 13:48pm    
That's awesome! Thank you so much and also for the good explanation really appreciate it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900