Дата Excel в метку времени Unix - PullRequest
80 голосов
/ 09 ноября 2009

Кто-нибудь знает, как преобразовать дату Excel в правильную метку времени Unix?

Ответы [ 9 ]

99 голосов
/ 21 июня 2012

Ни один из них не сработал для меня ... когда я конвертировал метку времени обратно, это на 4 года.

Это сработало отлично: =(A2-DATE(1970,1,1))*86400

Кредит идет: Филип Czaja http://fczaja.blogspot.ca

Исходное сообщение: http://fczaja.blogspot.ca/2011/06/convert-excel-date-into-timestamp.html

68 голосов
/ 27 мая 2011

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)
11 голосов
/ 09 ноября 2009

Если мы предположим, что дата в 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

6 голосов
/ 15 сентября 2015

Вот сопоставление для справки, при условии 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

* & ldquo; Jan Zero, 1900 & rdquo; 1899/12/31; см. раздел Ошибка ниже. В Excel 2011 для Mac (и старше) используется система дат 1904 .

Поскольку я часто использую awk для обработки CSV и содержимого, разделенного пробелами, я разработал способ преобразования эпох UNIX в часовой пояс / DST -адресуемый формат даты 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.

3 голосов
/ 13 февраля 2013

Поскольку мои правки к вышеуказанному были отклонены (кто-нибудь из вас действительно пробовал?), Вот что вам действительно нужно, чтобы эта работа:

Windows (и Mac Office 2011 +):

  • Unix Timestamp = (Excel Timestamp - 25569) * 86400
  • Временная метка Excel = (Unix Timestamp / 86400) + 25569

MAC OS X (до выпуска Office 2011):

  • метка времени Unix = (Excel Timestamp - 24107) * 86400
  • Отметка времени Excel = (Unix Timestamp / 86400) + 24107
2 голосов
/ 23 марта 2011

Вы, очевидно, отключились на один день, ровно 86400 секунд. Используйте номер 2209161600 Не номер 2209075200 Если вы введете в Google эти два числа, вы найдете поддержку для вышеуказанного. Я попробовал вашу формулу, но всегда появлялся на 1 день иначе, чем мой сервер. Это не очевидно из отметки времени Unix, если вы не думаете о Unix, а не о человеческом времени ;-), но если вы дважды проверите, то увидите, что это может быть правильно.

1 голос
/ 09 ноября 2018

У меня была старая база данных Excel с «удобочитаемыми» датами, например 2010.03.28 20: 12: 30 Эти даты были в UTC + 1 (CET) и должны были преобразовать их в время эпохи.

Я использовал формулу = (A4-DATE (1970; 1; 1)) * 86400-3600 для преобразования дат во время эпохи из столбца A в значения столбца B. Проверьте смещение часового пояса и сделайте с ним математику. 1 час - 3600 секунд.

Единственное, из-за чего я пишу здесь, вы можете видеть, что этой теме более 5 лет, что я использую новые версии Excel, а также красные сообщения в этой теме, но они неверны. ДАТА (1970; 1; 1). Здесь 1970 и январь должны быть разделены; а не с

Если вы также столкнулись с этой проблемой, надеюсь, она вам поможет. Хорошего дня:)

0 голосов
/ 07 сентября 2017

Вот мой окончательный ответ на этот вопрос.

Также, очевидно, конструктор javascript 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);
};
0 голосов
/ 03 февраля 2016

Ни один из текущих ответов не сработал для меня, потому что мои данные были в этом формате со стороны Unix:

2016-02-02 19:21:42 UTC

Мне нужно было преобразовать это в эпоху, чтобы позволить ссылаться на другие данные, которые имели метки времени эпохи.

  1. Создайте новый столбец для части даты и проанализируйте по этой формуле

    =DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4)) 
    
  2. Как уже говорил другой Грендлер, создайте еще один столбец

    =(B2-DATE(1970,1,1))*86400 
    
  3. Создайте еще один столбец, добавив только время, чтобы получить общее количество секунд:

    =(VALUE(MID(A2,12,2))*60*60+VALUE(MID(A2,15,2))*60+VALUE(MID(A2,18,2)))
    
  4. Создайте последний столбец, который просто добавляет последние два столбца вместе:

    =C2+D2
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...