Хтось знає, як перетворити дату Excel на правильну позначку часу Unix?
Хтось знає, як перетворити дату Excel на правильну позначку часу Unix?
Відповіді:
Жодне з них не працювало у мене ... коли я перетворив мітку часу назад, це 4 роки.
Це спрацювало чудово: =(A2-DATE(1970,1,1))*86400
Кредит: Філіп Чая 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, відформатована як Date, а мітка часу 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 і просторово-роздільниками змісту, я розробив спосіб перетворення UNIX епохи в часовому поясі / 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 для 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
більше не @
повинен представляти unix епоху (враховуючи, наскільки здатний синтаксичний аналізатор рядків, я насправді здивований, що @
це обов’язково; який ще формат дати має 9-10 цифр?), І тепер його запитують для двох виходів: зміщення епохи та часового поясу. Тому ви можете використовувати, наприклад, @1234567890
як вхідні дані.
Lotus 1-2-3 (оригінальне програмне забезпечення для електронних таблиць) навмисно трактувало 1900 рік як високосний рік, незважаючи на те, що він не був (це зменшило кодову базу в той час, коли кожен байт враховувався). 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 не визнає негативні дати і має спеціальне визначення Нульового січня (1899/12/31) для нульового дня. Внутрішньо Excel дійсно обробляє від’ємні дати (зрештою це просто числа), але відображає їх як числа, оскільки не знає, як відображати їх як дати (а також не може перетворити старі дати в від’ємні числа). 29 лютого 1900 року, дня, якого ніколи не було, 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 Ці дати були в UTC + 1 (CET), і їх потрібно було перевести в епоху.
Я використав формулу = (A4-DATE (1970; 1; 1)) * 86400-3600, щоб перетворити дати на час епохи зі стовпця A у значення B. Перевірте зміщення часового поясу та порахуйте його. 1 година - 3600 секунд.
Єдине, чому я пишу тут anwser, ви бачите, що цій темі вже більше 5 років - це те, що я використовую нові версії Excel, а також червоні повідомлення в цій темі, але вони неправильні. ДАТА (1970; 1; 1). Тут 1970 і січень потрібно розділяти; а не з,
Якщо ви також стикаєтеся з цією проблемою, сподіваємося, що вона вам допоможе. Гарного дня :)
Жодна з поточних відповідей не працювала для мене, оскільки мої дані були в такому форматі з боку unix:
02.02.2016 19:21:42 UTC
Мені потрібно було перетворити це на Epoch, щоб дозволити посилання на інші дані, які мали позначки часу епохи.
Створіть новий стовпець для частини дати та проаналізуйте цю формулу
=DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4))
Як вже зазначав інший Грендлер, створіть ще одну колонку
=(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)
конструктор javascript також не враховує стрибкових секунд.
// 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"
?