2009-07-21 19 views
6

Ich konvertiere eine kleine MSAccess-Anwendung mit C# 3.5 in eine webbasierte ASP.NET-App. Ich habe mich gefragt, wie man am besten mit Daten in C# arbeiten kann, wenn man einen Teil dieses VBA-Codes in C# umwandelt. HierWie konvertiert man in C# den TimeSpan-Datentyp in DateTime?

ist ein Beispiel für den VBA-Code:

Coverage1=IIf(IsNull([EffDate1]),0,IIf([CurrDate]<=[EndDate1],[CurrDate]-[EffDate1],[EndDate1]-[EffDate1]+1)) 

Hier ist, was mein aktueller C# -Code sieht aus wie mit den Fehlern in dem kommentierten Code bezeichnet:

public DateTime CalculateCoverageOne(DateTime dateEffDateOne, DateTime dateCurrentDate, DateTime dateEndDateOne) 
    { 
     if (dateCurrentDate.Date <= dateEndDateOne.Date) 
     { 
      return null; //Get "cannot convert null to System.DateTime because it is a non-nullable value type" error 
     } 
     else 
     { 
      if (dateCurrentDate.Date <= dateEndDateOne) 
      { 
       return dateCurrentDate.Subtract(dateEffDateOne); //Gets error "cannot implicitly convert system.timepsan to system.datetime 
      } 
      else 
      { 
       return dateEndDateOne.Subtract(dateEffDateOne.AddDays(1)); //Gets error "cannot implicitly convert system.timepsan to system.datetime 
      } 
     } 
    } 

Antwort

2

Es sieht so aus, als ob Ihre VB tatsächlich eine Zeitspanne zurückgibt, vermutlich in Tagen. Hier ist die nächste direkte Übersetzung:

public TimeSpan CalculateCoverageOne(DateTime EffDate1, DateTime CurrDate, DateTime? EndDate1) 
{ 
    return (EndDate1 == null) ? TimeSpan.Zero : 
      (CurrDate < EndDate1) ? (CurrDate - EffDate1) : 
      (EndDate1.AddDays(1) - EffDate1); 
} 

Wenn Sie stattdessen nur eine Anzahl von Tagen wollte, einfach die ausgeTimeSpan-Tage-Eigenschaft:

public int CalculateCoverageOne(DateTime EffDate1, DateTime CurrDate, DateTime? EndDate1) 
{ 
    return ((EndDate1 == null) ? TimeSpan.Zero : 
      (CurrDate < EndDate1) ? (CurrDate - EffDate1) : 
      (EndDate1.AddDays(1) - EffDate1)).Days; 
} 

Und für eine gute Maßnahme, das ist, wie ich aufräumen würde Ihr Endfassung:

public int CalculateCoverageOne(DateTime dateCurrentDate, DateTime dateEffectiveDate, DateTime dateEffDateOne, DateTime dateEndDateOne) 
{ 
    TimeSpan ts; 
    if (dateEffDateOne == DateTime.MinValue) 
    { 
     ts = TimeSpan.Zero; 
    } 
    else if (dateEffectiveDate <= dateEndDateOne) 
    { 
     ts = dateCurrentDate - dateEffDateOne; 
    } 
    else 
    { 
     ts = (dateEndDateOne - dateEffDateOne) + new TimeSpan(1, 0, 0, 0); 
    } 
    return ts.Days; 
} 
+0

Am besten. Vielen Dank! – program247365

2

werden die Zeitspanne bekommen, dann subtrahiere das von der DateTime, um das gewünschte Datum zu erhalten. Für Ihre innere IF-Anweisung, würde es so aussehen:

TimeSpan estSpan = dateCurrentDate.Subtract(dateEffDateOne); 
return dateCurrentDate.Subtract(estSpan); 

EDIT: Sie können auch DateTime.MaxValue und haben die Berufung Funktionsprüfung für den Maximalwert, statt Rückkehr null zurückzukehren. Um

+0

Ihr Code wird immer dateEffDateOne als Ergebnis zurückgeben, kein Unterschied zwischen den Daten. Ich denke, es ist nicht das, was @ program247365 will. – VladV

+0

Ich glaube nicht, dass das OP gefragt hat. Er benötigt DateTime, aber wenn er Zeiträume speichern muss, sollte er TimeSpan verwenden. –

6

kann System.DateTime nicht null konvertieren, weil es sich um eine nicht-Nullable-Wertetyp“Fehler

Der DateTime Typ ist ein Werttyp, was bedeutet, dass es nicht einen Nullwert halten kann. Um dies zu tun, können Sie eines von zwei Dingen tun: Entweder geben Sie DateTime.MinValue zurück, und testen Sie, ob Sie den Wert verwenden möchten, oder ändern Sie die Funktion DateTime? (beachten Sie das Fragezeichen), das ist ein Nullwert DateTime so verwendet werden:

DateTime? nullable = DateTime.Now; 
if (nullable.HasValue) 
{ 
    // do something with nullable.Value 
} 

kann nicht implizit konvertieren system.timepsan System.DateTime

Wenn Sie eine DateTime von einem anderen DateTime subtrahieren, ist das Ergebnis ein TimeSpan ist, was die Höhe der Zeit zwischen ihnen. Die TimeSpan repräsentiert keinen bestimmten Zeitpunkt, sondern die Spanne selbst. Um das Datum zu erhalten, können Sie die Add Methode oder die Subtract Methodenüberladung eines DateTime Objekts verwenden, das eine TimeSpan akzeptiert. Genau wie das aussehen soll kann ich nicht sagen, da ich nicht weiß, was die verschiedenen Daten in deinem Code darstellen.

Im letzten Fall können Sie einfach den Rückgabewert der AddDays Methode verwenden, aber mit einem negativen Wert (um einen Tag zu subtrahieren, anstatt eine der Zugabe):

return dateEffDateOne.AddDays(-1); 
+0

> dateCurrentDate.Subtract (dateCurrentDate.Subtract (dateEffDateOne)) dateCurrentDate- (dateCurrentDate-dateEffDateOne) == dateEffDateOne Ich denke, es ist nicht das, was @ program247365 will. – VladV

+0

@VladV: Ich denke du hast Recht. Da ich keine Ahnung habe, wie sich die verschiedenen Daten im ursprünglichen Codebeispiel aufeinander beziehen, kann ich nicht wirklich herausfinden, welches Ergebnis erwartet wird, also habe ich diese Zeile aus meiner Antwort entfernt. –

1

Datetime ist ein value type. Daher können Sie DateTime keine Null zuweisen. Sie können jedoch einen speziellen Wert wie DateTime.MinValue verwenden, um anzugeben, was Sie mit null angeben wollten.

DateTime steht für ein Datum (und eine Uhrzeit), wie "22. Juli 2009". Dies bedeutet, dass Sie diesen Typ nicht zur Darstellung des Zeitintervalls wie "9 Tage" verwenden sollten. TimeSpan ist der dafür vorgesehene Typ.

dateCurrentDate.Subtract (dateEffDateOne) (oder, äquivalent, dateCurrentDate-dateEffDateOne) ist eine Differenz zwischen zwei Daten, das heißt, Zeitintervall. Daher empfehle ich Ihnen, den Rückgabetyp Ihrer Funktion in TimeSpan zu ändern.

TimeSpan ist auch ein Werttyp, Sie können also beispielsweise TimeSpan.Zero anstelle von null verwenden.

0

Nach einigen ausgezeichneten Antworten (ich habe bis gestimmt euch), ich habe endlich gehämmert, was ich denke, ist meine Antwort. Stellt sich heraus, dass das Zurückgeben eines int, wie die Anzahl der Tage ist, was für mich in dieser Situation funktionierte.

Danke allen, für die Bereitstellung Ihrer fantastischen Antworten. Es hat mir geholfen, auf die richtige Spur zu kommen.

public int CalculateCoverageOne(DateTime dateCurrentDate, DateTime dateEffectiveDate, DateTime dateEffDateOne, DateTime dateEndDateOne) 
    { 
     //Coverage1= 
     //IIf(IsNull([EffDate1]),0, 
      //IIf([CurrDate]<=[EndDate1], 
       //[CurrDate]-[EffDate1], 
        //[EndDate1]-[EffDate1]+1)) 

     if (dateEffDateOne.Equals(TimeSpan.Zero)) 
     { 
      return (TimeSpan.Zero).Days; 
     } 
     else 
     { 
      if (dateEffectiveDate <= dateEndDateOne) 
      { 
       return (dateCurrentDate - dateEffDateOne).Days; 
      } 
      else 
      { 
       return (dateEndDateOne - dateEffDateOne).Add(new TimeSpan(1, 0, 0, 0)).Days; 
      } 
     } 
    } 
+0

Sie meinen wahrscheinlich dateEffDateOne.Equals (DateTime.MinValue) und nicht TimeSpan.Zero. In der Praxis sind sie dasselbe (gespeichert als 0L), aber Sie sollten sich nicht auf diesen Zufall verlassen. – dahlbyk

+0

Gotcha. Danke für den Kommentar. – program247365

Verwandte Themen