2009-07-21 16 views
6

Estoy convirtiendo una pequeña aplicación de MSAccess en una aplicación ASP.NET basada en web, usando C# 3.5. Me preguntaba cuál es la mejor manera de trabajar con las fechas en C#, al convertir parte de este código de VBA en C#.En C#, ¿cómo se convierte el tipo de datos TimeSpan a DateTime?

Aquí se muestra un ejemplo del código VBA:

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

Aquí es lo que mi actual código C# parece que con los errores indicados en el código comentado:

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

Respuesta

2

Parece que su VB está regresando realmente un lapso de tiempo, presumiblemente en días. Aquí está la traducción directa más cercano:

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

Si en lugar de que sólo quería un recuento de días, vuelve Días propiedad del TimeSpan:

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

Y por una buena medida, esto es cómo iba a limpiar su versión final:

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

Más excelente. ¡Muchas gracias! – program247365

2

Obtener el TimeSpan, a continuación, reste eso del DateTime para obtener la fecha que desee. Para su interior IF, que se vería así:

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

EDIT: También puede volver DateTime.MaxValue y tener el control de funciones de llamada para el valor máximo, en lugar de devolver nulo.

+0

Su código siempre devolverá dateEffDateOne como resultado, no una diferencia entre las fechas. Supongo que no es lo que quiere @ program247365. – VladV

+0

No creo que eso sea lo que pidió el OP. Necesita DateTime, pero si necesita almacenar períodos de tiempo, entonces debería estar usando TimeSpan. –

6

no se puede convertir nula a System.DateTime porque es un tipo de valor no anulable" error

El tipo DateTime es un valor de tipo, lo que significa que no puede contener un valor nulo. Para obtener alrededor de esto puede hacer una de estas dos cosas: o bien devuelva DateTime.MinValue, y pruebe para cuando quiera usar el valor, o cambie la función para devolver DateTime? (observe el signo de interrogación), que es un nulo DateTime. La fecha anulable puede ser utilizado de esta manera:

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

no se puede convertir implícitamente a system.timepsan System.DateTime

Cuando resta un DateTimeDateTime de otro, el resultado es una TimeSpan, que representa la cantidad de tiempo entre ellos. El TimeSpan no representa un punto específico en el tiempo, sino el lapso en sí mismo. Para obtener la fecha, puede usar el método Add o la sobrecarga del método Subtract de un objeto DateTime que acepta TimeSpan. Exactamente cómo debe verse eso no puedo decirlo, ya que no sé qué representan las diferentes fechas en su código.

En el último caso, puede simplemente usar el valor devuelto por el método AddDays, pero con un valor negativo (con el fin de restar un día, en lugar de añadir uno):

return dateEffDateOne.AddDays(-1); 
+0

> dateCurrentDate.Subtract (dateCurrentDate.Subtract (dateEffDateOne)) dateCurrentDate- (dateCurrentDate-dateEffDateOne) == dateEffDateOne supongo, no es lo que quiere program247365 @. – VladV

+0

@VladV: Creo que tienes razón. Como no tengo idea de cómo se relacionan las diferentes fechas en el ejemplo del código original entre sí, no puedo averiguar qué resultado se espera, así que quité esa línea de mi respuesta. –

1

DateTime es una value type. Por lo tanto, no puede asignar null a DateTime. Pero puede usar un valor especial como DateTime.MinValue para indicar lo que estaba tratando de indicar mediante nulo.

DateTime representa una fecha (y hora), como "22 de julio de 2009". Esto significa que no debe usar este tipo para representar el intervalo de tiempo, como "9 días". TimeSpan es el tipo previsto para esto.

dateCurrentDate.Subtract (dateEffDateOne) (o, equivalentemente, dateCurrentDate-dateEffDateOne) es una diferencia entre dos fechas, es decir, intervalo de tiempo. Por lo tanto, le sugiero que cambie el tipo de devolución de su función a TimeSpan.

TimeSpan también es un tipo de valor, por lo que podría usar, por ejemplo, TimeSpan.Zero en lugar de nulo.

0

Después de algunas respuestas excelentes (he arriba-voté ustedes), por fin he forjó lo que creo que es mi respuesta. Resulta que devolver un int, como el número de días, es lo que funcionó para mí en esta situación.

Gracias a todos por brindar sus increíbles respuestas. Me ayudó a seguir el camino correcto.

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

Probablemente se refiera a dateEffDateOne.Equals (DateTime.MinValue) en lugar de TimeSpan.Zero. En la práctica, son lo mismo (almacenado como 0L), pero no debe confiar en esa coincidencia. – dahlbyk

+0

Gotcha. Gracias por el comentario. – program247365

Cuestiones relacionadas