8 Stimmen

Warum schlägt dieser Unit-Test beim Testen der DateTime-Gleichheit fehl?

Bei Verwendung von NUnit 2.2 auf .NET 3.5 schlägt der folgende Test bei Verwendung von DateTime.Equals fehl. Warum?

[TestFixture]
public class AttributeValueModelTest
{
    public class HasDate
    {
        public DateTime? DateValue
        {
            get
            {
                DateTime value;
                return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
            }
        }

        public object ObjectValue { get; set; }
    }

    [Test]
    public void TwoDates()
    {
        DateTime actual = DateTime.Now;
        var date = new HasDate {ObjectValue = actual};
        Assert.IsTrue(date.DateValue.Value.Equals(actual));
    }
}

16voto

Amy B Punkte 104656

Die Daten sind nicht gleich. TryParse lässt einige Ticks aus. Vergleichen Sie die Tick-Werte.

Für einen Testlauf:

Console.WriteLine(date.DateValue.Value.Ticks);
Console.WriteLine(actual.Ticks);

Ausbeute:

633646934930000000
633646934936763185

3voto

James Curran Punkte 98228

Das Problem ist nicht wirklich TryParse, sondern ToString().

Ein DateTime-Objekt beginnt mit einer Präzision (wenn auch nicht Genauigkeit) bis auf Millionstel Sekunden. ToString() wandelt es in eine Zeichenkette um, die nur auf eine Sekunde genau ist.

TryParse gibt sein Bestes mit dem, was ihm zur Verfügung steht.

Wenn Sie einen Formatspezifizierer hinzufügen (etwa in der Art von "yyyy-MM-dd HH:mm:ss.ffffff" ), sollte es funktionieren.

1voto

Don Kirkby Punkte 46803

Um ein Format anzugeben, das die gesamte Genauigkeit enthält, können Sie die Methode String.Format() verwenden. Das Beispiel, das James gibt, würde wie folgt aussehen:

String.Format("{0:yyyy-MM-dd HH:mm:ss.ffffff}", ObjectValue);

Ich weiß nicht, wozu das gut sein soll, wenn man es als etwas ausgibt, das kein Datum ist.

Vielleicht wäre es einfacher, einen Sonderfall hinzuzufügen, wenn Sie bereits ein Datumsobjekt haben:

    public DateTime? DateValue
    {
        get
        {
            DateTime value = ObjectValue as DateTime;
            if (value != null) return value;
            return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
        }
    }

0voto

Stephane Grenier Punkte 14946

Ich weiß nicht, ob das in .NET auch so ist, aber in Java vergleicht das Gleichheitszeichen oft nur, wenn die Instanzen gleich sind, nicht wenn die Werte gleich sind. Sie würden stattdessen wollen compareTo verwenden.

0voto

shahkalpesh Punkte 32505
public DateTime? DateValue
        {
            get
            {
                DateTime value;
                bool isDate = DateTime.TryParse(ObjectValue.ToString(), out value); 
                return isDate ? new DateTime?(value) : new DateTime?();
            }
        }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X