Exceldate到Unix时间戳

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

没有这些为我工作…当我转换时间戳回来是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

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中的date格式为A1单元格格式为Date,Unix时间戳格式应为A2单元格格式,则A2中的公式应为:

=(A1 * 86400) – 2209075200

哪里:

86400是当天秒数2209075200是1900-01-01和1970-01-01之间的秒数,它们是Excel和Unix时间戳的基准date。

以上是Windows的真实情况。 在Mac上,Excel中的基准date为1904-01-01,秒数应更正为:2082844800

假设电子表格系统(如Microsoft Excel)的UTC为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月零”是1899年12月31日; 请参阅下面的Bug部分。 Excel 2011 for Mac(及更早版本)使用1904年date系统 。

由于我经常使用awk来处理CSV和空格分隔的内容,所以我开发了一种将UNIX时代转换为时区/ DST相应的 Exceldate格式的方法:

 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 ,但是你可以pipe一个文件,第一列(对于第一个格式为.csv的单元格,称之为awk -F, )是一个UNIX纪元。 改变$1代表你想要的列/单元格编号或使用一个variables。

这使得系统调用date 。 如果您可靠地拥有GNU版本,则可以删除2>/dev/null || date … +%%z 2>/dev/null || date … +%%z ,第二个, $1 。 鉴于GNU的普遍性,我不推荐假设BSD的版本。

getlinedate +%z输出的时区偏移量读入tz ,然后转换为hours 。 格式将如-0700 ( PDT )或+0530 ( IST ),所以提取的第一个子串是0705 ,第二个是0030 (然后除以60以小时表示),第三个使用tz看到我们的抵消是否是负面的,如果需要改变hours

在此页面上的所有其他答案中给出的公式用于设置excel ,并增加了夏令时的时区调整(以hours/24

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

使用GNU date将任意非纪元时间转换为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时代(给定stringparsing器是多么有能力,我真的很惊讶@是必须的;其他date格式有9-10位数字? ),现在要求输出两个 :纪元和时区偏移量。 因此,您可以使用@1234567890作为input。

窃听器

Lotus 1-2-3 (原始电子表格软件)故意将1900作为一个闰年,尽pipe事实并非如此(这减less了每个字节计数时的代码库)。 Microsoft Excel 保留了兼容性的缺陷,跳过了第60天(虚构的1900/02/29),保留了Lotus 1-2-3的第59天到1900/02/28的映射。 LibreOffice改为在第60天到1900/02/28之间,并把以前的日子推回到第一天。

1900/03/01之前的任何一天最多可以rest一天:

 Day Excel LibreOffice -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不承认否定date,并且对零日的1月份的第零点有特别的定义。 在内部,Excel的确处理负date(他们只是数字毕竟),但它不知道如何显示它们作为date(也不能将旧date转换为负数)。 1900年2月29日,一个从未发生过的日子,被Excel识别而不是LibreOffice。

你显然有一天,正好86400秒。 使用数字2209161600不是数字2209075200如果你Google两个数字,你会发现上述的支持。 我尝试了你的公式,但总是出现1天不同于我的服务器。 从unix时间戳中不明显,除非你认为在unix而不是人类的时间;但是,如果你仔细检查,那么你会发现这可能是正确的。

因为我对上面的编辑被拒绝了(你们有没有真正尝试?),下面是你真正需要做的工作:

Windows(和Mac Office 2011+):

  • Unix时间戳= (Excel Timestamp - 25569) * 86400
  • Excel时间戳= (Unix Timestamp / 86400) + 25569

MAC OS X(pre office 2011):

  • Unix时间戳= (Excel Timestamp - 24107) * 86400
  • Excel时间戳= (Unix Timestamp / 86400) + 24107

目前的答案没有为我工作,因为我的数据是从这个unix方面的格式:

2016-02-02 19:21:42 UTC

我需要将其转换为Epoch,以便引用其他具有纪元时间戳的数据。

  1. 为date部分创build一个新列,并使用此公式进行分析

     =DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4)) 
  2. 正如其他Grendler已经在这里陈述,创build另一列

     =(B2-DATE(1970,1,1))*86400 
  3. 创build另一个列,只需要把时间加在一起得到总秒数:

     =(VALUE(MID(A2,12,2))*60*60+VALUE(MID(A2,15,2))*60+VALUE(MID(A2,18,2))) 
  4. 创build一个只添加最后两列的最后一列:

     =C2+D2 

这是我的最终答案。

也显然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 am // 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. // Eg 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 (eg 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); };