ไม่มีใครรู้วิธีแปลงวันที่ของ Excel เป็นเวลาประทับ Unix ที่ถูกต้อง?
ไม่มีใครรู้วิธีแปลงวันที่ของ Excel เป็นเวลาประทับ Unix ที่ถูกต้อง?
คำตอบ:
สิ่งเหล่านี้ไม่ได้ผลสำหรับฉัน ... เมื่อฉันแปลงการประทับเวลากลับเป็นเวลา 4 ปี
สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบ: =(A2-DATE(1970,1,1))*86400
เครดิตไปที่: Filip Czaja http://fczaja.blogspot.ca
โพสต์ต้นฉบับ: 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 และ 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
สำหรับการอ้างอิง:
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)
หากเราถือว่าวันที่ใน Excel อยู่ในเซลล์ A1 ที่จัดรูปแบบเป็นวันที่และการประทับเวลา Unix ควรอยู่ในเซลล์ A2 ที่จัดรูปแบบเป็นตัวเลขสูตรใน A2 ควรเป็น:
= (A1 * 86400) - 2209075200
ที่ไหน:
86400 คือจำนวนวินาทีในวันที่ 2209075200 คือจำนวนวินาทีระหว่าง 1900-01-01 และ 1970-01-01 ซึ่งเป็นวันที่ฐานสำหรับการประทับเวลาของ Excel และ Unix
ข้างต้นเป็นจริงสำหรับ Windows บน Mac วันที่ฐานใน Excel คือ 1904-01-01 และควรแก้ไขตัวเลขวินาทีเป็น 2082844800
นี่คือการทำแผนที่สำหรับการอ้างอิงโดยสมมติว่าUTCสำหรับระบบสเปรดชีตเช่น 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” คือ 1899/12/31; ดูส่วนข้อบกพร่องด้านล่าง † Excel 2011 สำหรับ Mac (และเก่า) ใช้ระบบวัน 1904
ขณะที่ผมมักจะใช้awk
ในการประมวลผลCSVและเนื้อหาคั่นด้วยช่องว่างผมพัฒนาวิธีการแปลงยูนิกซ์ยุคไปยังเขต / DST -appropriateรูปแบบวันที่ 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
}'
ฉันใช้echo
สำหรับตัวอย่างนี้ แต่คุณสามารถไพพ์ไฟล์โดยที่คอลัมน์แรก (สำหรับเซลล์แรกในรูปแบบ. csv เรียกมันว่าawk -F,
) เป็นยุค UNIX แก้ไข$1
เพื่อแสดงจำนวนคอลัมน์ / เซลล์ที่คุณต้องการหรือใช้ตัวแปรแทน
date
นี้จะทำให้การเรียกระบบการ หากคุณมีเวอร์ชัน GNU ที่เชื่อถือได้คุณสามารถลบ2>/dev/null || date … +%%z
และข้อที่สอง, $1
ออกได้ เนื่องจาก GNU ทั่วไปเป็นอย่างไรฉันไม่แนะนำให้สมมติว่าเป็นเวอร์ชันของ BSD
getline
อ่านโซนเวลาชดเชยออกมาโดยdate +%z
เข้าไปซึ่งเป็นที่แปลแล้วเป็นtz
hours
รูปแบบจะเป็นเหมือน-0700
( PDT ) หรือ+0530
( IST ) ดังนั้นสตริงย่อยแรกที่แยกออกมาคือ07
หรือ05
อันที่สองคือ00
หรือ30
(จากนั้นหารด้วย 60 เพื่อแสดงเป็นชั่วโมง) และการใช้ครั้งที่สามเพื่อtz
ดูว่าออฟเซ็ตของเราเป็นลบหรือไม่และเปลี่ยนแปลงhours
หากมีความจำเป็น.
สูตรที่ได้รับในทุกคำตอบอื่น ๆ ในหน้านี้จะใช้ในการตั้งค่าด้วยนอกเหนือจากการปรับโซนเวลากลางวันประหยัดทราบเป็นexcel
hours/24
หากคุณใช้ Excel for Mac เวอร์ชันเก่าคุณจะต้องใช้24107
แทน25569
(ดูการทำแผนที่ด้านบน)
ในการแปลงเวลาที่ไม่ใช่ยุคโดยพลการเป็นเวลาที่เหมาะกับ Excel ด้วยวันที่ 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
}'
นี่เป็นรหัสเดียวกันโดยทั่วไป แต่date -d
ไม่มีการ@
แสดงถึงยุคยูนิกซ์อีกต่อไป (เนื่องจากตัวแยกวิเคราะห์สตริงมีความสามารถเพียงใดฉันรู้สึกประหลาดใจจริง ๆ ที่@
จำเป็นต้องมีรูปแบบวันที่อื่นใดที่มีตัวเลข 9-10 หลัก) และตอนนี้ก็ถาม สำหรับสองเอาต์พุต: ยุคและเขตเวลาชดเชย คุณสามารถใช้เช่น@1234567890
เป็นอินพุตได้
Lotus 1-2-3 (ซอฟต์แวร์สเปรดชีตดั้งเดิม) โดยเจตนาถือว่า 1900 เป็นปีอธิกสุรทินแม้ว่าจะไม่เป็นเช่นนั้นก็ตาม (ซึ่งจะลด codebase ลงในแต่ละครั้งเมื่อนับทุกไบต์) Microsoft Excel ยังคงรักษาจุดบกพร่องนี้ไว้เพื่อความเข้ากันได้โดยข้ามวันที่ 60 (สมมติว่า 1900/02/29) โดยคงการทำแผนที่ของ Lotus 1-2-3 ในวันที่ 59 ถึง 1900/02/28 LibreOffice แทนกำหนดวันที่ 60 เป็น 1900/02/28 และดันวันก่อนหน้าทั้งหมดกลับเป็นวันเดียว
วันใดก็ได้ก่อน 1900/03/01 อาจมากถึงวันหยุด:
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 ไม่ยอมรับวันที่ติดลบและมีคำจำกัดความพิเศษของ Zeroth ของเดือนมกราคม (1899/12/31) สำหรับศูนย์วัน ภายใน Excel จะจัดการวันที่ติดลบอย่างแท้จริง (เป็นเพียงตัวเลขเท่านั้น) แต่จะแสดงเป็นตัวเลขเนื่องจากไม่ทราบวิธีแสดงเป็นวันที่ (และไม่สามารถแปลงวันที่เก่ากว่าเป็นจำนวนลบได้) 29 ก.พ. 2443 วันที่ไม่เคยเกิดขึ้นได้รับการยอมรับจาก Excel แต่ไม่ใช่ LibreOffice
เนื่องจากการแก้ไขด้านบนของฉันถูกปฏิเสธ (มีใครลองทำจริงหรือไม่) นี่คือสิ่งที่คุณต้องการเพื่อให้ได้ผล:
Windows (และ Mac Office 2011+):
(Excel Timestamp - 25569) * 86400
(Unix Timestamp / 86400) + 25569
MAC OS X (ก่อน Office 2011):
(Excel Timestamp - 24107) * 86400
(Unix Timestamp / 86400) + 24107
เห็นได้ชัดว่าคุณหยุดงานภายในวันเดียวคือ 86400 วินาที ใช้หมายเลข 2209161600 ไม่ใช่หมายเลข 2209075200 หากคุณ Google ใช้หมายเลขสองหมายเลขนี้คุณจะพบการสนับสนุนด้านบน ฉันลองใช้สูตรของคุณแล้ว แต่มักจะแตกต่างจากเซิร์ฟเวอร์ของฉัน 1 วัน ไม่ชัดเจนจากการประทับเวลาของ unix เว้นแต่คุณจะคิดเป็น unix แทนเวลาของมนุษย์ ;-) แต่ถ้าคุณตรวจสอบอีกครั้งคุณจะเห็นว่าสิ่งนี้อาจถูกต้อง
ฉันมีฐานข้อมูล Excel เก่าที่มีวันที่ "มนุษย์อ่านได้" เช่น2010.03.28 20:12:30 วันที่ Theese อยู่ใน UTC + 1 (CET) และจำเป็นต้องแปลงเป็นเวลาตามยุคสมัย
ฉันใช้สูตร= (A4-DATE (1970; 1; 1)) * 86400-3600เพื่อแปลงวันที่เป็นช่วงเวลาจากคอลัมน์ A เป็นค่าคอลัมน์ B ตรวจสอบการชดเชยเขตเวลาของคุณและคำนวณด้วยคณิตศาสตร์ 1 ชั่วโมงคือ 3600 วินาที
สิ่งเดียวที่ฉันเขียน anwser ที่นี่คุณจะเห็นว่าหัวข้อนี้มีอายุมากกว่า 5 ปีคือฉันใช้ Excel เวอร์ชันใหม่และโพสต์สีแดงในหัวข้อนี้ด้วย แต่ไม่ถูกต้อง วันที่ (1970; 1; 1) ในปี 1970 และเดือนมกราคมจะต้องแยกจากกัน และไม่ใช่ด้วย
หากคุณกำลังประสบปัญหานี้หวังว่าจะช่วยคุณได้ ขอให้เป็นวันที่ดี :)
ไม่มีคำตอบใดที่ใช้ได้กับฉันเนื่องจากข้อมูลของฉันอยู่ในรูปแบบนี้จากด้าน unix:
2016-02-02 19:21:42 UTC
ฉันต้องการแปลงสิ่งนี้เป็น Epoch เพื่อให้สามารถอ้างอิงข้อมูลอื่น ๆ ที่มีการประทับเวลายุค
สร้างคอลัมน์ใหม่สำหรับส่วนวันที่และแยกวิเคราะห์ด้วยสูตรนี้
=DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4))
ตามที่ Grendler อื่น ๆ ได้ระบุไว้ที่นี่แล้วให้สร้างคอลัมน์อื่น
=(B2-DATE(1970,1,1))*86400
สร้างคอลัมน์อื่นโดยใช้เวลารวมกันเพื่อให้ได้วินาทีทั้งหมด:
=(VALUE(MID(A2,12,2))*60*60+VALUE(MID(A2,15,2))*60+VALUE(MID(A2,18,2)))
สร้างคอลัมน์สุดท้ายที่เพิ่มสองคอลัมน์สุดท้ายเข้าด้วยกัน:
=C2+D2
นี่คือคำตอบที่ดีที่สุดของฉันสำหรับเรื่องนี้
นอกจากนี้ยังเห็นได้ชัดว่าตัวnew Date(year, month, day)
สร้างของจาวาสคริปต์ไม่ได้อธิบายถึงวินาทีอธิกสุรทินด้วย
// 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);
};
เพื่อชดเชยเวลาออมแสง (เริ่มตั้งแต่วันอาทิตย์สุดท้ายของเดือนมีนาคมจนถึงวันอาทิตย์สุดท้ายของเดือนตุลาคม) ฉันต้องใช้สูตรต่อไปนี้:
=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
)
คำอธิบายโดยย่อ:
ถ้าวันที่ ["A2"] อยู่ระหว่างวันอาทิตย์สุดท้ายของเดือนมีนาคมถึงวันอาทิตย์สุดท้ายของเดือนตุลาคม [บรรทัดรหัสที่สามและสี่] ฉันจะลบหนึ่งชั่วโมง [-TIME (1; 0; 0)] ถึงวันที่
"11/09/2009 3:23:24 PM"
?