Làm cách nào để chuyển đổi số ngày nối tiếp Excel thành .NET DateTime?


67
13
Huỳnh Tường Vinh
10 năm trước

Làm cách nào để chuyển đổi từ ngày nối tiếp excel sang thời gian ngày .NET?

Ví dụ 39938 là ngày 05/05/2009.

Hữu ích 67 Yêu thích 13 Chia sẻ Viết bình luận 0
Không hữu ích

4 Trả lời


71
Đỗ Kim Toàn
10 năm trước

Trong đó 39938 là số ngày kể từ 1/1/1900?

Trong trường hợp đó, sử dụng chức năng thư viện khung DateTime.FromOADate().
Hàm này đóng gói tất cả các chi tiết cụ thể và kiểm tra giới hạn.

Đối với giá trị lịch sử của nó, đây là một triển khai có thể:

(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

[Cập nhật]:
Hmm ... Một thử nghiệm nhanh cho thấy thực sự là hai ngày nghỉ. Không chắc chắn sự khác biệt ở đâu.

Được rồi: vấn đề đã được khắc phục. Xem các ý kiến ​​để biết chi tiết.

Hữu ích 71 Trả lời hay nhất Chia sẻ Viết bình luận 5
Không hữu ích

-1 để sao chép những gì đã được giải quyết trong .NET Framework (DateTime.FromOADate).

Hữu ích 24 · Không hữu ích · Trả lời 0

Mặc dù tôi đồng ý rằng phương pháp FROMOADate tốt hơn, tôi vẫn thấy câu trả lời này có nhiều thông tin.

Hữu ích 5 · Không hữu ích · Trả lời 0

Để biết thêm thông tin về FromOADate, hãy xem msdn.microsoft.com/en-us/l

Hữu ích 4 · Không hữu ích · Trả lời 0

Tôi nghĩ rằng bạn nhận được 2 ngày quá nhiều với chuyển đổi này, tức là ngày kỷ nguyên sẽ phải được chuyển về DateTime (1899, 12, 30). Điều này là do lỗi năm nhuận của Excel tôi giả sử.

Hữu ích 3 · Không hữu ích · Trả lời 0

Rất tiếc, mọi người khác đã nhanh hơn ;-) Và vâng, lỗi ban đầu xuất phát từ Lotus như Joel đã giải thích: joelonsoftware.com/items/2006/06/16.html

Hữu ích 2 · Không hữu ích · Trả lời 0

154
Trịnh Khắc Duy
9 năm trước

Tôi thấy đơn giản hơn khi sử dụng phương thức FromOADate , ví dụ:

DateTime dt = DateTime.FromOADate(39938);

Sử dụng mã này dt là "05/05/2009".

Hữu ích 154 Chia sẻ Viết bình luận 4
Không hữu ích

+1 Điều này có vẻ thanh lịch hơn nhiều so với các câu trả lời khác ...

Hữu ích 4 · Không hữu ích · Trả lời 0

Điều này cũng xử lý ngày với các giá trị thời gian (dấu phẩy động ở định dạng dữ liệu cơ bản), mà giải pháp được chấp nhận không có.

Hữu ích 2 · Không hữu ích · Trả lời 0

@nullptr Tuy nhiên, nó có độ chính xác chỉ 1 mili giây. Bạn có thể có được độ chính xác cao hơn nhiều nếu bạn quan tâm. Xem câu trả lời của tôi ở nơi khác .

Hữu ích 0 · Không hữu ích · Trả lời 0

Đối với peepz PowerShell của tôi:[DateTime]::FromOADate($serialDate)

Hữu ích 0 · Không hữu ích · Trả lời 0

1
Hoàng Hồng Nhuận
9 năm trước
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;
}

Cắt và dán tài năng của ai đó ...

Ian Brown

Hữu ích 1 Chia sẻ Viết bình luận 0
Không hữu ích

1
Huỳnh Khắc Kỷ
3 năm trước

Đối với 39938, hãy làm điều này: 39938 * 864000000000 + 599264352000000000

864000000000 đại diện cho số lượng bọ ve trong một ngày 599264352000000000 đại diện cho số lượng bọ ve từ năm 0001 đến năm 1900

Hữu ích 1 Chia sẻ Viết bình luận 0
Không hữu ích

Trả lời của bạn

Xem trước nội dung