Chênh lệch ngày trong Excel là bốn năm: lần đầu tiên hãy xem hệ thống ngày của sổ làm việc
iso_dates kiểm soát phương thức tuần tự hóa ngày trong tệp và không tự động biến ngày giờ trong bộ nhớ thành chuỗi. Số sê-ri ngày yêu cầu kỷ nguyên của sổ làm việc; ở đây chúng tôi so sánh hai hệ thống ngày tháng và kiểm tra các giá trị XML và giá trị đọc lại đã lưu.
Excel xuất các ngày được bù bốn năm và trong hầu hết các trường hợp, sự cố là ở hệ thống ngày của sổ làm việc chứ không phải ở bản thân dữ liệu. Được viết cho các nhà phát triển và người chịu trách nhiệm dữ liệu chịu trách nhiệm xuất báo cáo, tập lệnh ETL hoặc trao đổi tệp Excel đa nền tảng. Khi bạn gặp phải các tình huống như thay đổi ngày tổng thể, các số không thể hiển thị dưới dạng ngày, dữ liệu bất thường vào khoảng năm 1900, v.v., trước tiên bạn có thể khắc phục sự cố theo thứ tự của bài viết này.
Sau khi đọc bài viết này, bạn sẽ hiểu sự khác biệt giữa hai hệ thống ngày tháng 1900 và 1904, biết cách đọc workbook.epoch để xác nhận hệ thống được sử dụng bởi sổ làm việc hiện tại và nắm vững phương pháp chấp nhận kiểm tra XML và đọc lại các giá trị sau khi lưu. Mã và bảng trong bài viết này được minh họa bằng các mẫu tổng hợp, thích hợp làm danh sách kiểm tra trước khi làm việc với tài liệu thực.
Tôi nên làm gì nếu ngày trên Excel khác bốn năm? Một câu kết luận
Trước tiên hãy đọc workbook.epoch của sổ làm việc và xác nhận hệ thống ngày trước khi chuyển đổi; các vấn đề về ngày và múi giờ ranh giới được xử lý riêng.
| hoàn cảnh của bạn | Các phương pháp được đề xuất | lý do |
|---|---|---|
| Ngày xuất được bù tổng cộng khoảng 1462 ngày | Đọc workbook.epoch trước để xác nhận hệ thống ngày của sổ làm việc | Sự khác biệt giữa hệ thống 1900 và 1904 là 1462 ngày và các giả định không chính xác ở phía đọc sẽ khiến tất cả các số sê-ri bị hiểu sai |
| Ô là một số nhưng không thể hiển thị dưới dạng ngày | Kiểm tra và hoàn thiện mặt nạ định dạng ngày number_format | Khi gõ đúng kiểu số, thiếu định dạng sẽ gây ra hiện tượng hiển thị bất thường. |
| Ngày trước tháng 3 năm 1900 hoặc 29-02-1900 xuất hiện trong dữ liệu | Đánh dấu là không hợp lệ hoặc chuyển sang xem xét thủ công, giữ lại số serial gốc | Ngày này không tồn tại trong lịch Gregory và không bị buộc phải chuyển đổi |
datetime với múi giờ cần được viết | Loại bỏ tzinfo sau khi chuyển đổi hợp nhất sang UTC | Excel không hỗ trợ lưu múi giờ, tất cả thời gian đều là giờ địa phương mà bạn không hề hay biết |
| Các tập tin cần được trao đổi trên các nền tảng | Khai báo rõ ràng hệ thống ngày tháng | Cài đặt mặc định của máy thu là khác nhau, có thể tạo ra độ lệch im lặng |
Sự khác biệt giữa hệ thống ngày năm 1900 và 1904
Ngày trong tệp XLSX về cơ bản là số sê-ri dấu phẩy động và ý nghĩa của nó phụ thuộc hoàn toàn vào hệ thống ngày mà sổ làm việc được ràng buộc. Đặc tả XLSX cho phép hai kỷ nguyên cơ sở:
- Hệ thống ngày 1900: được Windows sử dụng theo mặc định, số sê-ri 1 đại diện cho 1900-01-01
- Hệ thống ngày 1904: Được sử dụng theo mặc định trên các máy Mac đời đầu, số sê-ri 0 đại diện cho 1904-01-01
Có một khoảng chênh lệch cố định là 1462 ngày giữa hai ngày, đây là nguồn chính của "chênh lệch ngày bốn năm". Ngoài ra, hệ thống năm 1900 có một vấn đề lịch sử: nó coi năm 1900 là năm nhuận không chính xác, khiến ngày 29-02-1900 không tồn tại được hợp pháp hóa trong Excel.
So sánh cốt lõi
| dự án | hệ thống ngày năm 1900 | Hệ thống ngày năm 1904 |
|---|---|---|
| Điểm bắt đầu của số sê-ri | Số Serial 1 tương ứng với 1900-01-01 | Số Serial 0 tương ứng với 1904-01-01 |
| Các nguồn mặc định phổ biến | Windows | Máy Mac đời đầu |
| bù đắp từ hệ thống khác | chênh lệch 1462 ngày | chênh lệch 1462 ngày |
| vấn đề đặc biệt | Nhầm 1900 là năm nhuận, tồn tại 29-02-1900 | Bài viết này không đề cập đến những vấn đề như vậy |
Tại sao dữ liệu trước năm 1900 cần được chăm sóc đặc biệt
Nếu bạn đang xử lý dữ liệu lịch sử trước tháng 3 năm 1900, mô-đun datetime của Python không thể biểu thị trực tiếp ngày 29 tháng 2. Theo tài liệu openpyxl chính thức, để tương thích với hành vi của Excel, thư viện sẽ mô phỏng ngoại lệ này khi đọc ngày trong tháng 1 và tháng 2 theo hệ thống 1900, nhưng bản thân 1900-02-29 không thể được chuyển đổi thành đối tượng Python datetime hợp lệ.
Đối với hầu hết dữ liệu kinh doanh hiện đại, điều quan trọng là xác định sổ làm việc hiện tại đang sử dụng hệ thống nào và khai báo rõ ràng khi trao đổi tệp trên các nền tảng để tránh sự trôi dạt im lặng ở đầu nhận do cài đặt mặc định khác nhau.
Ví dụ tổng hợp: các phương thức xử lý và nhập dữ liệu biên
Để minh họa vấn đề, chúng tôi xây dựng một kịch bản tổng hợp: một báo cáo được xuất bởi hệ thống tài chính sử dụng hệ thống ngày năm 1904, nhưng tập lệnh ETL xuôi dòng phân tích cú pháp nó theo hệ thống năm 1900 theo mặc định.
Xử lý lỗi hoặc đầu vào ranh giới:
- Nếu số sê-ri đầu vào là 60 và sổ làm việc dành cho hệ thống 1900 thì nó tương ứng với số hư cấu 1900-02-29 trong Excel.
datetimegốc của Python némValueError. - Tại thời điểm này, bạn không nên ép buộc chuyển đổi mà hãy nắm bắt ngoại lệ và ghi lại dưới dạng giá trị ban đầu hoặc dấu đặc biệt, vì ngày không tồn tại trong lịch Gregory.
- Nếu một đối tượng
datetimecó thông tin múi giờ được truyền vào để ghi, openpyxl sẽ không tự động chuyển đổi múi giờ mà yêu cầu loại bỏ tzinfo trước, nếu không có thể xảy ra lỗi ghi hoặc lỗi. - Bản thân Excel không hỗ trợ lưu trữ múi giờ và tất cả thời gian đều là giờ địa phương mà bạn không nhận thức được.
Phát hiện hệ thống ngày và mã chuyển đổi an toàn
Ví dụ sau đây cho thấy cách xử lý an toàn các khác biệt về hệ thống ngày tháng trong bộ nhớ. Mã này chỉ để trình diễn logic và không thực hiện việc đọc và ghi tệp thực tế. Nó cần được chạy trong môi trường phụ thuộc bị khóa của riêng bạn. Nên sử dụng Openpyxl >= 3.1.0. Các ví dụ không bao gồm các yêu cầu mạng hoặc thao tác ghi đè tệp, tất cả các xác nhận đều dựa trên dữ liệu tổng hợp.
from datetime import datetime
from io import BytesIO
from zipfile import ZipFile
from openpyxl import Workbook, load_workbook
from openpyxl.utils.datetime import from_excel, CALENDAR_MAC_1904, CALENDAR_WINDOWS_1900
assert from_excel(1, CALENDAR_MAC_1904) == datetime(1904, 1, 2)
assert from_excel(1, CALENDAR_WINDOWS_1900) == datetime(1900, 1, 1)
wb = Workbook()
wb.epoch = CALENDAR_MAC_1904
wb.iso_dates = True
value = datetime(2026, 9, 26, 12, 30)
wb.active["A1"] = value
assert wb.active["A1"].value == value
out = BytesIO()
wb.save(out)
with ZipFile(BytesIO(out.getvalue())) as z:
xml = z.read("xl/worksheets/sheet1.xml")
assert b't="d"' in xml and b"2026-09-26T12:30:00" in xml
restored = load_workbook(BytesIO(out.getvalue()))
assert restored.active["A1"].value == value
assert restored.epoch == CALENDAR_MAC_1904
Tiêu chí chấp nhận và ranh giới đánh giá thủ công
| Quan sát hiện tượng | điều kiện đầu vào hoặc biên | quyết định sản lượng hoặc xử lý dự kiến | Liệu tự động hóa có thể áp dụng được hay không |
|---|---|---|---|
| Tất cả các ngày được bù trừ thống nhất 1462 ngày | wb.epoch không nhất quán với các giả định phân tích | Đọc wb.epoch và chuyển đổi lại số thứ tự | Đúng |
| 1900-02-29 xuất hiện trong dữ liệu | Hệ thống 1900 có số sê-ri 60 | Được đánh dấu là ngày không hợp lệ, giữ lại số sê-ri gốc 60 | Không, bạn cần xác nhận thủ công ý nghĩa kinh doanh |
| Một phần thời gian bị thiếu hoặc bị đặt sai chỗ | Nhập datetime với tzinfo | Chuyển đổi sang UTC một cách thống nhất và sau đó loại bỏ tzinfo để viết | một phần, bạn cần xác định thủ công múi giờ mục tiêu |
| Ô hiển thị số nhưng được định dạng là ngày | Loại số đúng nhưng thiếu number_format | Kiểm tra và hoàn thiện mặt nạ định dạng ngày | Đúng |
| Ngày lịch sử (sớm hơn 1900-01-01) hiển thị bất thường | Ngày sớm hơn 1900-01-01 | Thay vào đó, hãy sử dụng bộ lưu trữ văn bản hoặc cơ sở dữ liệu lịch sử chuyên dụng | Không, XLSX không phù hợp với trường hợp này |
Cần lưu ý rằng phần trình diễn mã chỉ xác minh tính chính xác của logic chuyển đổi và không bằng hiệu ứng đầu cuối. Các tệp thực có thể chứa nhiều định dạng ngày, định dạng có điều kiện hoặc ngày được tạo bởi các công thức, yêu cầu các lớp phân tích cú pháp bổ sung. Khi gặp những ngày trước tháng 3 năm 1900, dữ liệu cộng tác giữa các múi giờ hoặc lịch không chuẩn (chẳng hạn như âm lịch, năm tài chính), bạn nên nhập quy trình xem xét thủ công và các tập lệnh tự động không được thực hiện các chỉnh sửa trái phép.
🎯 Phương pháp nào phù hợp với bạn?
Nếu bạn cần đọc ngày từ tệp xuất
Trước tiên hãy đọc workbook.epoch, xác nhận hệ thống ngày và sau đó quyết định xem có chuyển đổi lại số sê-ri hay không.
Nếu dữ liệu của bạn liên quan đến ngày trước tháng 3 năm 1900
Đánh dấu các hồ sơ liên quan đến 1900-02-29 là không hợp lệ, giữ lại số sê-ri gốc và giao cho xác nhận thủ công về ý nghĩa kinh doanh.
Nếu bạn cần viết thời gian kèm theo múi giờ vào Excel
Đầu tiên hãy chuyển đổi sang UTC một cách thống nhất, sau đó loại bỏ tzinfo; múi giờ mục tiêu cần được xác định theo cách thủ công.
Nếu bạn muốn trao đổi file với hệ thống khác
Khai báo rõ ràng hệ thống ngày tháng và xác thực các giá trị ngày đọc lại ở đầu nhận.
❓ Câu hỏi thường gặp (FAQ)
1. Tại sao ngày xuất khẩu lại bị lệch khoảng bốn năm?
Nguyên nhân phổ biến là hệ thống ngày tháng của sổ làm việc không nhất quán với các giả định ở phía đọc. Sự khác biệt giữa hai hệ thống năm 1900 và 1904 là 1462 ngày.
2. iso_dates có tự động biến datetime thành chuỗi không?
Sẽ không. iso_dates chỉ kiểm soát phương thức tuần tự hóa ngày trong tệp và không tự động chuyển đổi datetime trong bộ nhớ thành chuỗi.
3. Tại sao 1900-02-29 không thể chuyển đổi sang datetime Python?
1900 Hệ thống coi năm 1900 là năm nhuận không chính xác, khiến 1900-02-29 tồn tại trong Excel nhưng ngày không tồn tại trong lịch Gregory. datetime của Python ném ValueError, trong trường hợp đó, giá trị số ban đầu hoặc cờ đặc biệt phải được ghi lại.
4. Viết ngày giờ theo múi giờ vào Excel như thế nào?
Excel không hỗ trợ lưu trữ múi giờ. Trước tiên, nó phải được chuyển đổi thống nhất sang UTC, sau đó loại bỏ tzinfo trước khi viết; openpyxl sẽ không tự động hoàn thành chuyển đổi múi giờ.
📝 Tóm tắt
Các vấn đề về bù ngày thường phát sinh từ hệ thống ngày của sổ làm việc. Xác nhận workbook.epoch trước khi chuyển đổi có thể tránh được hầu hết các lỗi im lặng. Các vấn đề về ranh giới ngày và múi giờ phải được con người xem xét.
Thử ngay: Tải tài liệu lên để bắt đầu dịch, giữ nguyên bố cục ban đầu
Tài liệu tham khảo và các bước tiếp theo
- tài liệu về ngày và giờ chính thức của openpyxl: https://openpyxl.readthedocs.io/en/stable/datetime.html
- Ghi chú của Microsoft về hệ thống ngày tháng 1900/1904: https://docs.microsoft.com/en-us/office/troubleshoot/excel/1900-and-1904-date-system
- Lời giải thích của Microsoft về lỗi năm nhuận 1900: https://docs.microsoft.com/en-us/office/troubleshoot/excel/wrongly-assumes-1900-is-leap-year
Bước tiếp theo: Chọn mẫu Excel đã được giải mẫn cảm mà bạn có quyền sử dụng, chạy mã phát hiện kỷ nguyên ở trên và xác nhận xem hệ thống ngày của mẫu đó có nhất quán với logic xử lý của bạn hay không. Nếu phát hiện thấy sự không nhất quán, hãy điều chỉnh các tham số chuyển đổi trước khi tạo bản dịch.
Sử dụng danh sách kiểm tra này để dịch tài liệu
Đầu tiên hãy quyết định nội dung nào là văn bản, nội dung nào là công thức và mã hóa doanh nghiệp, sau đó dịch bảng. Kiểm tra sau dịch không chỉ xác nhận xem tiếng Trung đã được chuyển đổi sang ngôn ngữ đích hay chưa mà còn xác nhận rằng các công thức, mã định danh và mối quan hệ tham chiếu không bị thay đổi.
OmniDoc (cổng thông tin sản phẩm) cung cấp cổng dịch thuật tài liệu đa định dạng và trang web chính thức giới thiệu các chức năng so sánh OCR, bảng thuật ngữ và song ngữ. Đối với các nhóm muốn làm việc trực tiếp từ các tệp, đây là con đường đáng để đánh giá bằng các mẫu thực tế. Vui lòng sử dụng các tệp đã được giải mẫn cảm mà bạn có quyền tải lên và sử dụng các mục kiểm tra trong bài viết này để xem lại kết quả. Bài viết này không khẳng định OmniDoc sử dụng các thư viện nguồn mở hoặc thuật toán nội bộ trong bài viết, cũng như không sử dụng các ví dụ để thay thế việc kiểm tra hiệu suất sản phẩm.


