2009-07-21 11 views
6

Sto convertendo una piccola applicazione MSAccess in un'app ASP.NET basata sul Web, utilizzando C# 3.5. Mi stavo chiedendo quale sia il modo migliore per lavorare con le date in C#, quando si converte parte di questo codice VBA in C#.In C#, come si converte il tipo di dati TimeSpan in DateTime?

Ecco un esempio del codice VBA:

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

Ecco quello che il mio attuale codice C# sembra che con gli errori indicati nel codice commentato:

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 
      } 
     } 
    } 

risposta

2

Sembra che il tuo VB stia effettivamente restituendo un intervallo di tempo, presumibilmente in giorni. Ecco la traduzione diretta più vicina:

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

Se invece si voleva solo un conteggio di giorni, solo il ritorno del TimeSpan proprietà Giorni:

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

E per buona misura, questo è come vorrei ripulire il versione finale:

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

Più eccellente. Grazie mille! – program247365

2

Prendi il TimeSpan, poi sottrai quello dal DateTime per ottenere la data desiderata. Per la vostra interna IF, sarebbe simile a questa:

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

EDIT: Si consiglia inoltre di tornare DateTime.MaxValue ed avere il controllo funzionale di chiamata per il valore massimo, invece di restituire null.

+0

Il tuo codice restituirà sempre dataEffDateOne come risultato, non una differenza tra le date. Immagino che non sia quello che vuole @ program247365. – VladV

+0

Non credo che sia quello che l'OP ha chiesto. Ha bisogno di DateTime, ma se ha bisogno di memorizzare periodi di tempo, allora dovrebbe usare TimeSpan. –

6

impossibile convertire null per System.DateTime perché è un tipo di valore non null" Errore

Il tipo DateTime è un tipo valore, il che significa che non può contenere un valore nullo. Per attorno a questo puoi fare una di queste due cose, o restituire DateTime.MinValue, e testarlo quando vuoi usare il valore, o cambiare la funzione per restituire DateTime? (nota il punto interrogativo), che è un valore nullo DateTime. essere utilizzato in questo modo:

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

non può convertire implicitamente system.timepsan a System.DateTime

Quando si sottrae un DateTime da un altro DateTime, il risultato è un TimeSpan, rappresenta la quantità di tempo che intercorre tra loro. Lo TimeSpan non rappresenta un punto specifico nel tempo, ma lo span stesso. Per ottenere la data, è possibile utilizzare il metodo o l'overload del metodo Subtract di un oggetto DateTime che accetta uno TimeSpan. Non riesco a dire esattamente come dovrebbe apparire, dal momento che non so quali siano le diverse date nel codice.

In quest'ultimo caso, si può semplicemente utilizzare il valore restituito dal metodo AddDays, ma con un valore negativo (al fine di sottrarre un giorno, invece di aggiungere uno):

return dateEffDateOne.AddDays(-1); 
+0

> dateCurrentDate.Subtract (dateCurrentDate.Subtract (dateEffDateOne)) dateCurrentDate- (dateCurrentDate-dateEffDateOne) == dateEffDateOne credo, non è ciò che vuole @ program247365. – VladV

+0

@VladV: Penso che tu abbia ragione. Dato che non ho idea di come le varie date nell'esempio di codice originale si relazionano l'una con l'altra, non riesco a capire quale sia il risultato previsto, quindi ho rimosso quella linea dalla mia risposta. –

1

DateTime è un value type. Pertanto, non è possibile assegnare null a DateTime. Ma puoi usare un valore speciale come DateTime.MinValue per indicare qualsiasi cosa stavi cercando di indicare con null.

DateTime rappresenta una data (e un'ora), ad esempio "22 luglio 2009". Questo significa che non devi usare questo tipo per rappresentare un intervallo di tempo, ad esempio "9 giorni". TimeSpan è il tipo previsto per questo.

dateCurrentDate.Subtract (dateEffDateOne) (o, equivalentemente, dateCurrentDate-dateEffDateOne) è una differenza tra due date, cioè l'intervallo di tempo. Quindi, ti suggerisco di cambiare il tipo di ritorno della tua funzione in TimeSpan.

TimeSpan è anche un tipo di valore, quindi è possibile utilizzare, ad esempio, TimeSpan.Zero anziché null.

0

Dopo alcune risposte eccellenti (ho votato up-voi ragazzi), ho finalmente battuto fuori quello che penso è la mia risposta. Risulta che restituire un int, come il numero di giorni, è ciò che ha funzionato per me in questa situazione.

Grazie a tutti, per aver fornito le vostre fantastiche risposte. Mi ha aiutato a prendere la strada giusta.

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

Probabilmente si intende dateEffDateOne.Equals (DateTime.MinValue) piuttosto che TimeSpan.Zero. In pratica sono la stessa cosa (memorizzati come 0L), ma non dovresti fare affidamento su quella coincidenza. – dahlbyk

+0

Gotcha. Grazie per il commento. – program247365

Problemi correlati