Кто-нибудь знает, как преобразовать дату 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
* «Ян Ноль, 1900» - 31 декабря 1899 г .; см. раздел об ошибках ниже. † В 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) + 25569MAC OS X (до Office 2011):
(Excel Timestamp - 24107) * 86400(Unix Timestamp / 86400) + 24107Похоже, у вас нет времени на один день, ровно на 86400 секунд. Используйте номер 2209161600, а не номер 2209075200. Если вы погуглите два числа, вы найдете поддержку для вышеуказанного. Я пробовал вашу формулу, но всегда приходил на 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:
2016-02-02 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"?