Дата Excel до мітки часу Unix


85

Хтось знає, як перетворити дату Excel на правильну позначку часу Unix?


Що ви маєте на увазі під "датою екселя"? Ви маєте на увазі текст, відформатований як зручний для читання рядок дати та часу "11/09/2009 3:23:24 PM"?
Matt Ball

4
Не забувайте, що 19 січня 2038 року мітка часу Unix перестане працювати через 32-бітове переповнення. До цього моменту мільйонам програм потрібно буде або прийняти нову конвенцію про позначки часу, або перенести їх на 64-розрядні системи, які придбають часову позначку на «трохи» більше часу.

13
більше як на 32 біта більше часу.
user606723

Відповіді:


107

Жодне з них не працювало у мене ... коли я перетворив мітку часу назад, це 4 роки.

Це спрацювало чудово: =(A2-DATE(1970,1,1))*86400

Кредит: Філіп Чая http://fczaja.blogspot.ca

Оригінальне повідомлення: http://fczaja.blogspot.ca/2011/06/convert-excel-date-into-timestamp.html


6
Не забувайте свій часовий пояс (якщо ви не в UTC і не стежите за літнім часом). Епоха UNIX є агностичною для часового поясу, тоді як таблиці - ні. Ось посібник із прикладами.
Адам Кац,

GMT + 8:=((A1+28800)/86400)+25569
Іван Чау

поточний час для CDT (центральний денний час):=(NOW()-DATE(1970,1,1))*86400 + 5*3600
hBrent

Сучасні версії Excel будуть скаржитися на наведену вище формулу, якщо ви не заміните коми комою з комою:(1970;1;1)
Хосе Луїс Бланко

1
@tonygil Це спрацює, якщо клітинки, на які ви націлюєтесь, насправді є датами в Excel. Якщо це текст, який повинен відображати дату, всі ставки вимкнені.
Кейсі

75

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)

3
Office 2011 на Mac, схоже, чудово працює з версією цих формул для Windows. Версії "Mac" дуже далекі від цього.
radicand

1
Я думаю, ви змінили мітки часу excel та unix у цих формулах. Мітка часу Unix становить кілька секунд, тому її потрібно ділити на 86400, а не на мітку часу excel, про що говорять формули. Дивіться відповідь @ radicand.
Mike Houston

Дякуємо за коментарі, протестували це на Mac Excel 2011, і схоже, вони такі самі, як і версія Windows.
Jeff Wu

Чи є спосіб перетворити Unix timstamp в мілісекундах на дату і час, зберігаючи мілісекунди?
Лоренцо Беллі,

говорить чоловік на stackoverflow. так, як щодо високосних секунд, професоре.
катамфетамін

11

Якщо ми припустимо, що дата в 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


Це не працює точно на вікнах, принаймні. Він вимикається до 19 годин.
LLBBL

4
Отож має бути так: = (A1 * 86400) - 2209143600
LLBBL

2
База дат Mac Excel за замовчуванням - 1904, тоді як у Windows Excel - 1900, але ви можете змінити базу дат у Mac Excel, знявши прапорець біля опції "використовувати систему дат 1904" у розділі "Налаштування / розрахунок", тоді вона працює як Windows Excel.
Cloudranger

6

Ось відображення для довідки, припускаючи 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/0159    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

Оскільки мої зміни до вищезазначеного були відхилені (чи хтось із вас насправді намагався?), Ось що вам справді потрібно, щоб зробити цю роботу:

Windows (та Mac Office 2011+):

  • Мітка часу Unix = (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

Ви, мабуть, виїхали на один день, рівно 86400 секунд. Використовуйте номер 2209161600, а не номер 2209075200. Якщо ви шукаєте два числа в Google, ви знайдете підтримку для вищезазначеного. Я спробував твою формулу, але завжди підходив на 1 день, ніж на моєму сервері. З мітки часу unix це не очевидно, якщо ви не думаєте на unix замість людського часу ;-), але якщо ви двічі перевірите, то побачите, що це може бути правильно.


Це правильно, оскільки Excel розраховує перший рік як високосний рік, хоча це не так.
ANisus

Я можу підтвердити, що справді магічне число - 2209161600, це 1970-01-01 - 1900-01-01 + 1 день * 86400. Якщо ви введете 1900-01-01 в Excel і збережете як формат sylk, і подивіться на файл у у текстовому редакторі ви побачите, що ця дата зберігається як 1 замість нуля, як слід, саме тому вам потрібно додати 1 день
Cloudranger

1

У мене була стара база даних 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 і січень потрібно розділяти; а не з,

Якщо ви також стикаєтеся з цією проблемою, сподіваємося, що вона вам допоможе. Гарного дня :)


0

Жодна з поточних відповідей не працювала для мене, оскільки мої дані були в такому форматі з боку unix:

02.02.2016 19:21:42 UTC

Мені потрібно було перетворити це на Epoch, щоб дозволити посилання на інші дані, які мали позначки часу епохи.

  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
    

0

Ось моя остаточна відповідь на це.

Також, очевидно, 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);
};

0

Щоб компенсувати перехід на літній час (починаючи з останньої неділі березня до останньої неділі жовтня), мені довелося використати таку формулу:

=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)] до дати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.