Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does DateTime.Now have its own implementation of GetHashCode that gives unique hashes?

The MSDN article here states, that the default implementation of GetHashCode() does not guarantee unique results and should be not used as an identifier. So my question is whether DateTime.Now has its own implementation that would give out unique hashes. Thx for help

like image 517
Jaker Avatar asked Nov 28 '22 19:11

Jaker


2 Answers

First, it would be a mistake to rely on the particular implementation of GetHashCode for DateTime. That is something that is hidden from you. Relying on hidden details is a bad code smell; they could change on you at any moment and break your code.

Second, it turns out that DateTime internally stores a 64-bit integer DateTime.Ticks that measures the number of 100-nanosecond units since the epoch (midnight on January 1, 0001). Therefore, DateTime instances require at least 64-bits of information. But hash codes are 32-bit integers and therefore hash codes can not be unique (you can not map 64-bit space to 32-bit space without collisions).

To be explicit, you can see the source code for DateTime.GetHashCode:

public override int GetHashCode() {
    long internalTicks = this.InternalTicks;
    return (((int) internalTicks) ^ ((int) (internalTicks >> 0x20)));
}

As you can see, it does some "folding" to squeeze InternalTicks into a 32-bit integer.

In general, do not rely on hash codes being unique. The input space is generally larger than the space being hashed to (the space of all 32-bit integers).

If you absolutely must have a unique key to represent a DateTime object, use DateTime.ToBinary. This will provide you with a 64-bit integer that is unique and can be used to reconstitute the DateTime (use DateTime.FromBinary).

like image 70
jason Avatar answered Dec 28 '22 07:12

jason


No, it doesn't.

DateTime internally stores its value as a long containing 100-nanosecond untis since 01/01/0001.

Since GetHashCode returns a 32-bit integer, it's impossible for it to be completely unqiue.

Here is DateTime's implementation:

public override int GetHashCode() {
    Int64 ticks = InternalTicks;
    return unchecked((int)ticks) ^ (int)(ticks >> 32); 
}
like image 22
SLaks Avatar answered Dec 28 '22 06:12

SLaks