Excel日期到Unix时间戳


85

有谁知道如何将Excel日期转换为正确的Unix时间戳?


你所说的“ Excel日期”是什么意思?您是说将文本格式化为易于理解的日期时间字符串"11/09/2009 3:23:24 PM"吗?
Matt Ball

4
不要忘记,由于32位溢出,Unix时间戳在2038年1月19日将停止工作。在此之前,数百万应用程序将需要采用新的时间戳约定,或迁移到64位系统,这将使时间戳花费更多的时间。

13
更像32位时间。
user606723 2011年

Answers:


107

这些都不对我有用...当我将时间戳转换回去时,已经有4年了。

这完美地工作: =(A2-DATE(1970,1,1))*86400

图片来源:Filip Czaja 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
Ivan Chau

CDT当前时间(中央日光时间):=(NOW()-DATE(1970,1,1))*86400 + 5*3600
hBrent

除非您用分号替换逗号,否则现代版本的Excel将抱怨上面的公式:(1970;1;1)
Jose Luis Blanco

1
@tonygil如果您要定位的单元格实际上是Excel中的日期,它将起作用。如果是应该表示日期的文本,则所有选择均无效。
Casey

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
Mac上的Office 2011似乎可以与这些公式的“ Windows”版本配合使用。“ Mac”版本尚不完善。
radicand

1
我认为您已经颠倒了这些公式中的excel和unix时间戳。Unix时间戳以秒为单位,因此需要除以86400,而不是excel时间戳,这就是公式所说的。参见@radicand的答案。
迈克·休斯顿

感谢您的评论,在Mac Excel 2011上对此进行了测试,看起来它们与Windows版本相同。
Jeff Wu

有没有办法将毫秒制的unist timstamp转换为日期时间,并保留毫秒?
洛伦佐·贝利

男人说在计算器上。是的,leap秒,教授。
catamphetamine

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


至少在Windows上它不能完全正常工作。到19点钟关闭。
LLBBL 2011年

4
所以应该是这样:=(A1 * 86400)-2209143600
LLBBL 2011年

2
Mac Excel的默认日期基础是1904,而在Windows Excel中则是1900,但是您可以通过在“偏好设置/计算”下取消选中“使用1904日期系统”来更改Mac Excel中的日期基础,它的工作方式类似于Windows excel。
Cloudranger

6

这是一个供参考的映射,假定针对电子表格系统(例如Microsoft Excel)的UTC

                         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年1月0日”是1899/12/31;请参阅下面的错误部分。 Mac和更早版本的Excel 2011使用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 +%ztz,然后将其翻译成hours。格式类似于-0700PDT)或+0530IST),因此提取的第一个子字符串为0705,第二个子字符串为0030(然后除以60以小时表示),第三个使用来tz查看偏移量是否为负并改变hours如果需要的话。

此页面上所有其他答案中给出的公式用于设置excel,并且将意识到夏令时的时区调整设置为hours/24

如果您使用的是旧版Mac版Excel,则需要使用24107代替25569(请参见上面的映射)。

要将任意的非纪元时间转换为具有GNU日期的Excel友好时间,请执行以下操作:

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年视为a年,尽管事实并非如此(这减少了每次计数字节时的代码库)。Microsoft Excel出于兼容性考虑保留了此错误,跳过了第60天(虚拟1900/02/29),保留了第1-59天到第1900/02/28天的Lotus 1-2-3映射。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确实确实处理了负日期(毕竟它们只是数字),但由于它不知道如何将它们显示为日期(也不可以将较旧的日期转换为负数字),因此将它们显示为数字。1900年2月29日,这一天从未发生过,但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将第一年计算为a年,即使不是这样。
阿尼斯(Anisus)2011年

我可以确认魔术数字确实为2209161600,即1970-01-01-1900-01-01 + 1天*86400。如果您在excel中输入1900-01-01并另存为sylk格式,然后在文本编辑器,您会看到它将该日期保存为1,而不是应将其保存为零,这就是为什么您必须添加1天的原因
Cloudranger 2013年

1

我有一个带有“人类可读”日期的旧Excel数据库,例如2010.03.28 20:12:30 这些日期是UTC + 1(CET),需要将其转换为纪元时间。

我使用=(A4-DATE(1970; 1; 1))* 86400-3600公式将日期从A列转换为B列值的时间。检查您的时区偏移量并进行数学计算。1小时是3600秒。

我在这里写下答案的唯一原因是,您看到该主题已有5年以上的历史了,因为我使用了新的Excel版本,并且在该主题中也使用了红色的贴子,但它们不正确。DATE(1970; 1; 1)。这里的1970年和1月需要分开; 而不是

如果您也遇到此问题,希望对您有所帮助。祝你今天愉快 :)


0

当前的答案都不适合我,因为我的数据在Unix方面是这种格式的:

2016-02-02 19:21:42 UTC

我需要将其转换为Epoch,以允许引用具有epoch时间戳的其他数据。

  1. 为日期部分创建一个新列,并使用此公式进行解析

    =DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4)) 
    
  2. 正如其他Grendler在此已说明的那样,创建另一列

    =(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

这是我对此的最终答案。

显然,JavaScript的new Date(year, month, day)构造函数也无法说明for秒。

// 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

为了弥补夏时制(从3月的最后一个星期日开始,直到10月的最后一个星期日),我必须使用以下公式:

=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)]。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.