Excel tarihini doğru bir Unix zaman damgasına nasıl dönüştüreceğini bilen var mı?
Excel tarihini doğru bir Unix zaman damgasına nasıl dönüştüreceğini bilen var mı?
Yanıtlar:
Bunların hiçbiri benim için işe yaramadı ... zaman damgasını geri çevirdiğimde 4 yıl geride kaldı.
Bu mükemmel çalıştı: =(A2-DATE(1970,1,1))*86400
Kredi: Filip Czaja http://fczaja.blogspot.ca
Orijinal Gönderi: 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 ve 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
Referans için:
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'deki tarihin Tarih olarak biçimlendirilmiş A1 hücresinde olduğunu ve Unix zaman damgasının sayı olarak biçimlendirilmiş bir A2 hücresinde olması gerektiğini varsayarsak, A2'deki formül şöyle olmalıdır:
= (A1 * 86400) - 2209075200
nerede:
86400 gün içindeki saniye sayısıdır 2209075200, Excel ve Unix zaman damgaları için temel tarihler olan 1900-01-01 ve 1970-01-01 arasındaki saniye sayısıdır.
Yukarıdakiler Windows için geçerlidir. Mac'te, Excel'deki temel tarih 1904-01-01'dir ve saniye sayısı şu şekilde düzeltilmelidir: 2082844800
Microsoft Excel gibi elektronik tablo sistemleri için UTC varsayılarak referans için bir eşleme :
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; bkz Bug aşağıdaki bölümü. † Mac için Excel 2011 (ve daha eski), 1904 tarih sistemini kullanır .
Sık sık kullandıkça awk
süreç için CSV ve boşlukla ayrılmış içerik, ben UNIX dönemi dönüştürmek için bir yol geliştirdi saat dilimi / DST -Uygun Excel tarih biçimini:
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
Bu örnek için kullandım , ancak ilk sütunun (.csv biçimindeki ilk hücre için olarak adlandırın awk -F,
) bir UNIX dönemi olduğu bir dosyayı aktarabilirsiniz . Alter $1
istediğiniz sütun / hücre sayısını temsil veya bunun yerine bir değişken kullanmak.
Bu, bir sistem çağrısı yapar date
. Eğer güvenilir bir GNU sürümüne sahip olacaksa, kaldırabilir 2>/dev/null || date … +%%z
ve ikinci , $1
. GNU'nun ne kadar yaygın olduğu göz önüne alındığında, BSD'nin sürümünü varsaymamayı tavsiye etmem.
getline
Tarafından çıkarılan ofset zaman dilimini okur date +%z
içine tz
daha sonra çevrilir, hours
. Biçim, -0700
( PDT ) veya +0530
( IST ) gibi olacaktır , bu nedenle çıkarılan ilk alt dize 07
veya 05
, ikincisi 00
veya 30
(daha sonra saat cinsinden ifade edilmek üzere 60'a bölünür) ve üçüncü kullanım, tz
ofsetimizin negatif olup olmadığını ve değişip değişmediğini görür. hours
gerekirse.
Bu sayfadaki diğer tüm cevaplarda verilen formül excel
, gün ışığından yararlanma farkında olan saat dilimi ayarlamasının eklenmesi ile ayarlanır hours/24
.
Mac için Excel'in daha eski bir sürümünü kullanıyorsanız 24107
, bunun yerine kullanmanız gerekir 25569
(yukarıdaki eşlemeye bakın).
Herhangi bir dönem dışı rastgele zamanı, GNU tarihiyle Excel uyumlu zamanlara dönüştürmek için:
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
}'
Bu temelde aynı koddur, ancak date -d
artık @
unix dönemini temsil edecek bir özelliği yoktur (dize ayrıştırıcısının ne kadar yetenekli olduğu göz önüne alındığında, aslında @
zorunlu olmasına şaşırdım ; başka hangi tarih formatının 9-10 hanesi var?) Ve şimdi soruluyor için iki çıkışları: dönem ve zaman dilimi farkı. Bu nedenle, örneğin @1234567890
bir girdi olarak kullanabilirsiniz .
Lotus 1-2-3 (orijinal elektronik tablo yazılımı), 1900'ü kasıtlı olarak , öyle olmasa da artık yıl olarak değerlendirdi (bu, her baytın sayıldığı bir zamanda kod tabanını azalttı). Microsoft Excel bu hatayı uyumluluk için korudu , 60. günü (hayali 1900/02/29) atlayarak Lotus 1-2-3'ün 59. gün ile 1900/02/28 arasındaki eşlemesini korudu. LibreOffice bunun yerine 60 - 1900/02/28 günlerini atadı ve önceki tüm günleri bir geriye itti.
1900/03/01 tarihinden önceki herhangi bir tarih bir tatil günü kadar olabilir:
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, negatif tarihleri kabul etmez ve sıfırıncı gün için Ocak Ayının Sıfırının (1899/12/31) özel bir tanımına sahiptir. Excel dahili olarak negatif tarihleri işler (sonuçta sadece sayılardır), ancak bunları tarih olarak nasıl görüntüleyeceğini bilmediğinden (eski tarihleri negatif sayılara dönüştüremediğinden) sayı olarak görüntüler. 29 Şubat 1900, hiç yaşanmamış bir gün, Excel tarafından tanınıyor ancak LibreOffice tarafından tanınmıyor.
Yukarıdakilere yaptığım düzenlemeler reddedildiğinden (herhangi biriniz gerçekten denediniz mi?), İşte bu işe yaraması için gerçekten ihtiyacınız olan şey:
Windows (ve Mac Office 2011+):
(Excel Timestamp - 25569) * 86400
(Unix Timestamp / 86400) + 25569
MAC OS X (Ön Ofis 2011):
(Excel Timestamp - 24107) * 86400
(Unix Timestamp / 86400) + 24107
Görünüşe göre bir gün, tam olarak 86400 saniye. 2209161600 numarasını kullanın 2209075200 numarasını değil İki numarayı Google'da ararsanız, yukarıdakiler için destek bulacaksınız. Formülünüzü denedim ama her zaman sunucumdan 1 gün farklı geliyordu. Unix zaman damgasından insan zamanı yerine unix'i düşünmedikçe açık değil ;-) ama iki kez kontrol ederseniz, bunun doğru olabileceğini göreceksiniz.
2010.03.28 20:12:30 gibi "insan tarafından okunabilir" tarihlere sahip eski bir Excel veritabanım vardı. Bu tarihler UTC + 1 (CET) idi ve bunu çağ zamanına dönüştürmem gerekiyordu.
Tarihleri çağ zamanına A sütunundan B sütun değerlerine dönüştürmek için = (A4-DATE (1970; 1; 1)) * 86400-3600 formülünü kullandım. Saat dilimi farkınızı kontrol edin ve bununla bir matematik yapın. 1 saat 3600 saniyedir.
Buraya cevaplayıcı yazmamın tek yanı, bu konunun 5 yıldan daha eski olduğunu görebiliyorsunuz, bu konuda yeni Excel sürümlerini ve ayrıca kırmızı yazıları kullanıyorum, ancak bunlar yanlış. TARİH (1970; 1; 1). Burada 1970 ve Ocak ayrılması gerekiyor; ve değil
Bu sorunu da yaşıyorsanız, umarız size yardımcı olur. İyi günler dilerim :)
Mevcut cevapların hiçbiri benim için işe yaramadı çünkü verilerim unix tarafından bu formattaydı:
2016-02-02 19:21:42 UTC
Dönem zaman damgalarına sahip diğer verilere başvurmaya izin vermek için bunu Epoch'a dönüştürmem gerekiyordu.
Tarih bölümü için yeni bir sütun oluşturun ve bu formülle ayrıştırın
=DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4))
Diğer Grendler'ın burada daha önce belirttiği gibi, başka bir sütun oluşturun
=(B2-DATE(1970,1,1))*86400
Toplam saniye elde etmek için yalnızca zamanın toplandığı başka bir sütun oluşturun:
=(VALUE(MID(A2,12,2))*60*60+VALUE(MID(A2,15,2))*60+VALUE(MID(A2,18,2)))
Son iki sütunu birbirine ekleyen son bir sütun oluşturun:
=C2+D2
İşte buna nihai cevabım.
Ayrıca görünüşe göre javascript'in new Date(year, month, day)
kurucusu da artık saniyeleri hesaba katmıyor.
// 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);
};
Yaz saatini telafi etmek için (Mart'ın son pazarından Ekim'in son pazarına kadar) aşağıdaki formülü kullanmam gerekiyordu:
=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
)
Hızlı açıklama:
["A2"] tarihi Mart'ın son pazarıyla Ekim'in son pazar günü arasındaysa [üçüncü ve dördüncü kod satırları], o zaman tarihe bir saat [-TIME (1; 0; 0)] çıkaracağım.
"11/09/2009 3:23:24 PM"
?