Có ai biết cách chuyển đổi ngày tháng trong Excel sang dấu thời gian Unix chính xác không?
Có ai biết cách chuyển đổi ngày tháng trong Excel sang dấu thời gian Unix chính xác không?
Câu trả lời:
Những thứ không có tác dụng với tôi ... khi tôi chuyển đổi dấu thời gian trở lại thì nó đã hết 4 năm.
Điều này hoạt động hoàn hảo: =(A2-DATE(1970,1,1))*86400
Tín dụng được chuyển đến: Filip Czaja http://fczaja.blogspot.ca
Bài đăng gốc: http://fczaja.blogspot.ca/2011/06/convert-excel-date-into-timestamp.html
=((A1+28800)/86400)+25569
=(NOW()-DATE(1970,1,1))*86400 + 5*3600
(1970;1;1)
Windows và Mac Excel (2011):
Unix Timestamp = (Excel Timestamp - 25569) * 86400
Excel Timestamp = (Unix Timestamp / 86400) + 25569
MAC OS X (2007):
Unix Timestamp = (Excel Timestamp - 24107) * 86400
Excel Timestamp = (Unix Timestamp / 86400) + 24107
Để tham khảo:
86400 = Seconds in a day
25569 = Days between 1970/01/01 and 1900/01/01 (min date in Windows Excel)
24107 = Days between 1970/01/01 and 1904/01/02 (min date in Mac Excel 2007)
Nếu chúng ta giả sử ngày trong Excel ở ô A1 được định dạng là Ngày và dấu thời gian Unix phải ở ô A2 được định dạng là số thì công thức trong A2 phải là:
= (A1 * 86400) - 2209075200
Ở đâu:
86400 là số giây trong ngày 2209075200 là số giây trong khoảng thời gian từ 1900-01-01 đến 1970-01-01 là ngày cơ sở cho các dấu thời gian Excel và Unix.
Điều trên đúng với Windows. Trên Mac, ngày cơ bản trong Excel là 1904-01-01 và số giây phải được sửa thành: 2082844800
Dưới đây là ánh xạ để tham khảo, giả sử UTC cho các hệ thống bảng tính như Microsoft Excel:
Unix Excel Mac Excel Human Date Human Time
Excel Epoch -2209075200 -1462 0 1900/01/00* 00:00:00 (local)
Excel ≤ 2011 Mac† -2082758400 0 1462 1904/12/31 00:00:00 (local)
Unix Epoch 0 24107 25569 1970/01/01 00:00:00 UTC
Example Below 1234567890 38395.6 39857.6 2009/02/13 23:31:30 UTC
Signed Int Max 2147483648 51886 50424 2038/01/19 03:14:08 UTC
One Second 1 0.0000115740… — 00:00:01
One Hour 3600 0.0416666666… ― 01:00:00
One Day 86400 1 1 ― 24:00:00
* “Jan Zero, 1900” là 1899/12/31; xem phần Lỗi bên dưới. † Excel 2011 dành cho Mac (và cũ hơn) sử dụng hệ thống ngày 1904 .
Vì tôi thường sử dụng awk
để xử lý CSV và nội dung được phân cách bằng dấu cách, tôi đã phát triển một cách để chuyển đổi kỷ nguyên UNIX sang định dạng ngày tháng phù hợp với múi giờ / DST trong Excel:
echo 1234567890 |awk '{
# tries GNU date, tries BSD date on failure
cmd = sprintf("date -d@%d +%%z 2>/dev/null || date -jf %%s %d +%%z", $1, $1)
cmd |getline tz # read in time-specific offset
hours = substr(tz, 2, 2) + substr(tz, 4) / 60 # hours + minutes (hi, India)
if (tz ~ /^-/) hours *= -1 # offset direction (east/west)
excel = $1/86400 + hours/24 + 25569 # as days, plus offset
printf "%.9f\n", excel
}'
Tôi đã sử dụng echo
cho ví dụ này, nhưng bạn có thể đặt một tệp trong đó cột đầu tiên (đối với ô đầu tiên ở định dạng .csv, gọi nó là awk -F,
) là một kỷ nguyên UNIX. Thay thế $1
để đại diện cho số cột / ô mong muốn của bạn hoặc sử dụng một biến thay thế.
Điều này thực hiện một cuộc gọi hệ thống đến date
. Nếu bạn chắc chắn sẽ có phiên bản GNU, bạn có thể xóa phiên bản 2>/dev/null || date … +%%z
thứ hai , $1
. Với mức độ phổ biến của GNU, tôi không khuyên bạn nên giả sử phiên bản của BSD.
Giá trị này getline
đọc độ lệch múi giờ được xuất ra bởi date +%z
thành tz
, sau đó được dịch sang hours
. Định dạng sẽ giống như -0700
( PDT ) hoặc +0530
( IST ), vì vậy chuỗi con đầu tiên được trích xuất là 07
hoặc 05
, chuỗi thứ hai là 00
hoặc 30
(sau đó chia cho 60 để được biểu thị bằng giờ) và cách sử dụng thứ ba để tz
xem liệu phần bù của chúng ta có âm và thay đổi hay không hours
Nếu cần thiết.
Công thức được đưa ra trong tất cả các câu trả lời khác trên trang này được sử dụng để đặt excel
, với việc bổ sung điều chỉnh múi giờ nhận biết ánh sáng ban ngày như hours/24
.
Nếu bạn đang sử dụng phiên bản Excel cho Mac cũ hơn, bạn sẽ cần sử dụng 24107
thay thế cho 25569
(xem ánh xạ ở trên).
Để chuyển đổi bất kỳ thời gian không phải kỷ nguyên tùy ý nào sang thời gian thân thiện với Excel với ngày GNU:
echo "last thursday" |awk '{
cmd = sprintf("date -d \"%s\" +\"%%s %%z\"", $0)
cmd |getline
hours = substr($2, 2, 2) + substr($2, 4) / 60
if ($2 ~ /^-/) hours *= -1
excel = $1/86400 + hours/24 + 25569
printf "%.9f\n", excel
}'
Đây về cơ bản là cùng một mã, nhưng date -d
không còn @
phải đại diện cho kỷ nguyên unix (với khả năng của trình phân tích cú pháp chuỗi như thế nào, tôi thực sự ngạc nhiên về điều @
này là bắt buộc; định dạng ngày nào khác có 9-10 chữ số?) Và nó bây giờ được hỏi cho hai đầu ra: độ lệch kỷ nguyên và múi giờ. Do đó, bạn có thể sử dụng ví dụ @1234567890
như một đầu vào.
Lotus 1-2-3 (phần mềm bảng tính gốc) đã cố ý coi năm 1900 là một năm nhuận mặc dù thực tế không phải vậy (điều này làm giảm cơ sở mã tại thời điểm mỗi byte được tính). Microsoft Excel đã giữ lại lỗi này để tương thích, bỏ qua ngày 60 (giả tưởng 1900/02/29), giữ lại ánh xạ Lotus 1-2-3 của ngày 59 đến 1900/02/28. Thay vào đó, LibreOffice đã chỉ định ngày 60 đến ngày 19 tháng 2 năm 28 và đẩy tất cả các ngày trước đó trở lại một.
Bất kỳ ngày nào trước 1900/03/01 cũng có thể là một ngày nghỉ:
Day Excel LibreOffice
-1 -1 1899/12/29
0 1900/01/00* 1899/12/30
1 1900/01/01 1899/12/31
2 1900/01/02 1900/01/01
…
59 1900/02/28 1900/02/27
60 1900/02/29(!) 1900/02/28
61 1900/03/01 1900/03/01
Excel không thừa nhận ngày âm và có một định nghĩa đặc biệt về Số 0 của tháng 1 (1899/12/31) cho ngày 0. Về mặt nội bộ, Excel thực sự xử lý các ngày âm (xét cho cùng chúng chỉ là số), nhưng nó hiển thị chúng dưới dạng số vì nó không biết cách hiển thị chúng dưới dạng ngày tháng (cũng như không thể chuyển đổi các ngày cũ hơn thành số âm). Ngày 29 tháng 2 năm 1900, một ngày chưa từng xảy ra, được Excel công nhận chứ không phải LibreOffice.
Vì các chỉnh sửa của tôi ở trên đã bị từ chối (có ai trong số bạn thực sự đã thử không?), Đây là những gì bạn thực sự cần để làm cho điều này hoạt động:
Windows (Và Mac Office 2011+):
(Excel Timestamp - 25569) * 86400
(Unix Timestamp / 86400) + 25569
MAC OS X (trước Office 2011):
(Excel Timestamp - 24107) * 86400
(Unix Timestamp / 86400) + 24107
Bạn dường như đã tắt một ngày, chính xác là 86400 giây. Sử dụng số 2209161600 Không phải số 2209075200 Nếu bạn Google hai số, bạn sẽ tìm thấy hỗ trợ cho những điều trên. Tôi đã thử công thức của bạn nhưng luôn xuất hiện một ngày khác với máy chủ của tôi. Nó không rõ ràng từ dấu thời gian unix trừ khi bạn nghĩ trong unix thay vì thời gian của con người ;-) nhưng nếu bạn kiểm tra kỹ thì bạn sẽ thấy điều này có thể đúng.
Tôi có một cơ sở dữ liệu Excel cũ với các ngày "con người có thể đọc được", chẳng hạn như 2010.03.28 20:12:30 Các ngày cũ ở UTC + 1 (CET) và cần phải chuyển đổi nó sang thời gian kỷ nguyên.
Tôi đã sử dụng công thức = (A4-DATE (1970; 1; 1)) * 86400-3600 để chuyển đổi ngày tháng thành thời gian kỷ nguyên từ giá trị cột A sang cột B. Kiểm tra độ lệch múi giờ của bạn và thực hiện một phép toán với nó. 1 giờ là 3600 giây.
Điều duy nhất tại sao tôi viết ở đây một nhà cảm xạ, bạn có thể thấy rằng chủ đề này đã hơn 5 năm tuổi là tôi sử dụng các phiên bản Excel mới và cũng có các bài viết màu đỏ trong chủ đề này, nhưng chúng không chính xác. The DATE (1970; 1; 1). Ở đây, năm 1970 và tháng Giêng cần được tách biệt với; và không với,
Nếu bạn cũng đang gặp phải vấn đề này, hy vọng nó sẽ giúp bạn. Chúc một ngày tốt lành :)
Không có câu trả lời hiện tại nào phù hợp với tôi vì dữ liệu của tôi ở định dạng này từ phía unix:
2016-02-02 19:21:42 giờ UTC
Tôi cần chuyển đổi dữ liệu này thành Epoch để cho phép tham chiếu dữ liệu khác có dấu thời gian của epoch.
Tạo một cột mới cho phần ngày tháng và phân tích cú pháp với công thức này
=DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4))
Như Grendler khác đã nêu ở đây, hãy tạo một cột khác
=(B2-DATE(1970,1,1))*86400
Tạo một cột khác chỉ với thời gian được cộng lại với nhau để có tổng số giây:
=(VALUE(MID(A2,12,2))*60*60+VALUE(MID(A2,15,2))*60+VALUE(MID(A2,18,2)))
Tạo cột cuối cùng chỉ thêm hai cột cuối cùng với nhau:
=C2+D2
Đây là câu trả lời cuối cùng của tôi cho điều này.
Cũng rõ ràng là hàm new Date(year, month, day)
tạo của javascript cũng không tính đến giây nhuận.
// Parses an Excel Date ("serial") into a
// corresponding javascript Date in UTC+0 timezone.
//
// Doesn't account for leap seconds.
// Therefore is not 100% correct.
// But will do, I guess, since we're
// not doing rocket science here.
//
// https://www.pcworld.com/article/3063622/software/mastering-excel-date-time-serial-numbers-networkdays-datevalue-and-more.html
// "If you need to calculate dates in your spreadsheets,
// Excel uses its own unique system, which it calls Serial Numbers".
//
lib.parseExcelDate = function (excelSerialDate) {
// "Excel serial date" is just
// the count of days since `01/01/1900`
// (seems that it may be even fractional).
//
// The count of days elapsed
// since `01/01/1900` (Excel epoch)
// till `01/01/1970` (Unix epoch).
// Accounts for leap years
// (19 of them, yielding 19 extra days).
const daysBeforeUnixEpoch = 70 * 365 + 19;
// An hour, approximately, because a minute
// may be longer than 60 seconds, see "leap seconds".
const hour = 60 * 60 * 1000;
// "In the 1900 system, the serial number 1 represents January 1, 1900, 12:00:00 a.m.
// while the number 0 represents the fictitious date January 0, 1900".
// These extra 12 hours are a hack to make things
// a little bit less weird when rendering parsed dates.
// E.g. if a date `Jan 1st, 2017` gets parsed as
// `Jan 1st, 2017, 00:00 UTC` then when displayed in the US
// it would show up as `Dec 31st, 2016, 19:00 UTC-05` (Austin, Texas).
// That would be weird for a website user.
// Therefore this extra 12-hour padding is added
// to compensate for the most weird cases like this
// (doesn't solve all of them, but most of them).
// And if you ask what about -12/+12 border then
// the answer is people there are already accustomed
// to the weird time behaviour when their neighbours
// may have completely different date than they do.
//
// `Math.round()` rounds all time fractions
// smaller than a millisecond (e.g. nanoseconds)
// but it's unlikely that an Excel serial date
// is gonna contain even seconds.
//
return new Date(Math.round((excelSerialDate - daysBeforeUnixEpoch) * 24 * hour) + 12 * hour);
};
Để bù cho thời gian tiết kiệm ánh sáng ban ngày (bắt đầu từ chủ nhật cuối cùng của tháng 3 cho đến chủ nhật cuối cùng của tháng 10), tôi phải sử dụng công thức sau:
=IF(
AND(
A2>=EOMONTH(DATE(YEAR(A2);3;1);0)-MOD(WEEKDAY(EOMONTH(DATE(YEAR(A2);3;1);0);11);7);
A2<=EOMONTH(DATE(YEAR(A2);10;1);0)-MOD(WEEKDAY(EOMONTH(DATE(YEAR(A2);10;1);0);11);7)
);
(A2-DATE(1970;1;1)-TIME(1;0;0))*24*60*60*1000;
(A2-DATE(1970;1;1))*24*60*60*1000
)
Giải thích nhanh:
Nếu ngày ["A2"] nằm giữa chủ nhật cuối cùng của tháng 3 và chủ nhật cuối cùng của tháng 10 [dòng mã thứ ba và thứ tư], thì tôi sẽ trừ đi một giờ [-TIME (1; 0; 0)] cho ngày.
"11/09/2009 3:23:24 PM"
?