2017-06-20 15 views
1

Betrachten Sie die folgende (vereinfachte) Code:Warum unterscheiden sich diese beiden DateTime-Instanzen?

DateTime now = DateTime.Now; 
DateTime now2 = new DateTime(now.Year, now.Month, now.Day, 
           now.Hour, now.Minute, now.Second, 
           now.Millisecond, now.Kind); 
bool condition = (now <= now2); 

Da ich die Felder von now-now2 kopiert haben, diese beiden Instanzen der DateTime Struktur sollte gleich sein. condition wird jedoch zu false ausgewertet. Warum?

Gibt es eine Möglichkeit, den Code so zu ändern, dass die Bedingung wahr ist?

+4

Wenn Sie sagen, „sollte“, meinen Sie, dass Sie in einem Haltepunkt setzen und bestätigt, dass die Instanzen sind in der Tat identisch? –

+0

Der Debugger ist hier dein Freund. –

Antwort

0

Alle Antworten auf Now2 verwenden korrekt berichtet, dass Problem in Zecken, die 10.000 Mal kleiner als Millisekunden, aber er gab mir keine Antwort, wie Zustand zu ändern also wird es als wahr bewertet. Ich brauche Konstruktor

DateTime(int year, int month, ...); 

statt zu verwenden: in Anwendung

DateTime(long ticks); 

wegen meiner Logik. Es stellt sich heraus, dass es mit dem ersten Konstruktor nicht möglich ist, den 10.000sten Teil von Millisekunden zu setzen, und mit dem zweiten Konstruktor ist es nicht möglich, den Tag des Monats einzustellen, ohne einige Arithmetik manuell zu berechnen. Meine Lösung ist in ersten Konstruktor zu verwenden und fügen Sie 1 Millisekunde vor dem Vergleich:

DateTime now = DateTime.Now; 
DateTime now2 = new DateTime(now.Year, now.Month, now.Day, 
           now.Hour, now.Minute, now.Second, 
           now.Millisecond, now.Kind); 
bool condition = (now <= now2.AddMilliseconds(1)); 
1

Sie haben die Zecken vergessen. Hier Bedingung erfüllt ist:

var now = DateTime.Now; 
var now2 = new DateTime(now.Ticks); 
var eq = now <= now2; 

EDIT: Antwort auf die Frage in den Kommentaren:

var tempNow = DateTime.Now; 
var now = new DateTime(tempNow.Year ...); 
var now2 = new DateTime(tempNow.Year, tempNow.Month, customDay, ...) 

in diesem Fall, dass Sie sie vergleichen können, wie Sie möchten.

+0

Ich muss den Tag des Monats anders als das ursprüngliche Datum einstellen. Logik funktioniert, es sei denn, dieser Tag des Monats ist heute. Wie kann ich den Tag des Monats einstellen und den Rest der DateTime behalten? – Uros

+0

@Uros Ihr Code funktioniert nicht, auch wenn der Tag * heute nicht * ist. Du verlierst in all diesen anderen Fällen bis zu einer Millisekunde Zeit, du hast es einfach nicht bemerkt. – Servy

+0

@Uros Ist es das, was Sie wollten? –

7

It's the Ticks. Es sind immer die Ticks. Manchmal.

DateTime now = DateTime.Now; 
DateTime now2 = new DateTime(now.Year, now.Month, now.Day, 
    now.Hour, now.Minute, now.Second, now.Millisecond); 
bool condition = (now <= now2); 

var diff = now2 - now; 

enter image description here

Die Auflösungszeit ist feiner als Millisekunden. Ticks is the real value:

Der Wert dieser Eigenschaft die Anzahl der 100-Nanosekunden-Intervalle repräsentiert, die zum 1. Januar 0001 seit 00.00.00 Mitternacht verstrichen ist (00.00.00 UTC am 1. Januar 0001, in der Gregorianische Kalender), der DateTime.MinValue darstellt.

Und es gibt einen Konstruktor für sie:

var reallyNow = new Datetime(now.Ticks); 

Sie bestanden nie einen beliebigen Wert für Ticks in diesem Konstruktor für now2 (weil es keinen Parameter für das hat), und so wird now2.Ticks haben vier Nullen bei das Ende. Allerdings DateTime.Now, die Sie direkt auf now kopiert, hatte einen Ticks Wert, der nicht gleichmäßig durch 10.000 teilbar war.

+4

Ich dachte, dass Link am Anfang Ihrer Antwort zu einer Art urkomischen Meme sein würde. Wie enttäuschend. –

1

Da die resolution of DateTime ist 100 Nanosekunden, nicht 1 Millisekunde. Sie haben die Werte nur bis zur Millisekunde kopiert.

Zeitwert in 100-Nanosekunden-Einheiten gemessen werden Ticks genannt, [...]

So müssen Sie einen Konstruktor verwenden, die mehr Präzision als 1 Millisekunde ermöglicht zum Beispiel the constructor accepting "ticks":

DateTime now = DateTime.Now; 
DateTime now2 = new DateTime(now.Ticks); 
bool condition = (now <= now2);   // yields true 
+0

Vielen Dank dafür. Kann ich den Tag des Monats für now2 ändern? – Uros

+1

@Uros: Sicher, benutze 'AddDays' und ein wenig Mathe. – Heinzi

0

DateTime hat eine niedrigere Auflösung als Millisekunden: Ticks. Wenn Sie now2 erstellen, sind die niedrigstwertigen Stellen in now2.Ticks gleich Null, deshalb ist now2 kleiner als jetzt.

Für mich: now.Ticks = 636335767998991455 now2.Ticks = 636335767998990000

Wenn Sie jetzt duplizieren wollen DateTime now2 = new DateTime(now.Ticks)

+0

Ich möchte alles außer Tag des Monats duplizieren. Der Tag des Monats wird von einer anderen Variablen gelesen. Kann ich es irgendwie einstellen? – Uros

Verwandte Themen