2009-04-07 11 views

Respuesta

53

Donde 39938 es la cantidad de días desde 1/1/1900?

En ese caso, utilice esta función (C#):

public static DateTime FromExcelSerialDate(int SerialDate) 
{ 
    if (SerialDate > 59) SerialDate -= 1; //Excel/Lotus 2/29/1900 bug 
    return new DateTime(1899, 12, 31).AddDays(SerialDate); 
} 

VB:

Public Shared Function FromExcelSerialDate(ByVal SerialDate As Integer) As DateTime 
    If SerialDate > 59 Then SerialDate -= 1 ''// Excel/Lotus 2/29/1900 bug 
    Return New DateTime(1899, 12, 31).AddDays(SerialDate) 
End Function 

[Actualización]:
Hmm ... Una prueba rápida de eso muestra que en realidad están dos días libres. No estoy seguro de dónde está la diferencia.

Bien: problema resuelto ahora. Ver los comentarios para más detalles. Especialmente vea la recomendación de usar DateTime.FromOADate() en su lugar.

+1

sé 1 día es para Lotus teniendo un error el 29/02/1900 lo tenía como un día que no existe. No sé lo que es el otro día. –

+0

Fechas de VBA (Excel) comienzan en 12/30/1899 –

+0

Funciona si resta 2, pero falla para las fechas de serie de al menos por debajo de 60 (02/29/1900) y el segundo día de fuga allí. –

1
void ExcelSerialDateToDMY(int nSerialDate, int &nDay, 
          int &nMonth, int &nYear) 
{ 
    // Excel/Lotus 123 have a bug with 29-02-1900. 1900 is not a 
    // leap year, but Excel/Lotus 123 think it is... 
    if (nSerialDate == 60) 
    { 
     nDay = 29; 
     nMonth = 2; 
     nYear = 1900; 

     return; 
    } 
    else if (nSerialDate < 60) 
    { 
     // Because of the 29-02-1900 bug, any serial date 
     // under 60 is one off... Compensate. 
     nSerialDate++; 
    } 

    // Modified Julian to DMY calculation with an addition of 2415019 
    int l = nSerialDate + 68569 + 2415019; 
    int n = int((4 * l)/146097); 
      l = l - int((146097 * n + 3)/4); 
    int i = int((4000 * (l + 1))/1461001); 
     l = l - int((1461 * i)/4) + 31; 
    int j = int((80 * l)/2447); 
    nDay = l - int((2447 * j)/80); 
     l = int(j/11); 
     nMonth = j + 2 - (12 * l); 
    nYear = 100 * (n - 49) + i + l; 
} 

cortar y pegar de alguien vigilara de talentos ...

Ian Brown

133

me resulta más sencillo usar FromOADate method, por ejemplo:

DateTime dt = DateTime.FromOADate(39938); 

Utilizando este código dt es "05/05/2009".

+4

+1 Esto parece mucho más elegante que las otras respuestas ... –

+2

Esto también maneja las fechas con valores de tiempo (coma flotante en el formato de datos subyacente), lo que no ocurre con la solución aceptada. –

+0

@nullptr Sin embargo, tiene una precisión de solo 1 milisegundo. Puedes obtener una precisión mucho mayor si te importa. Ver [mi respuesta en otro lugar] (http://stackoverflow.com/a/13922172/1336654). –

1

Por 39938 hacer esto: 39938 * 864000000000 + 599264352000000000

864000000000 representa el número de garrapatas en un día 599264352000000000 representa el número de garrapatas desde el año 0001 hasta el año 1900

Cuestiones relacionadas