有谁知道如何将Excel日期转换为正确的Unix时间戳?
答案 0 :(得分:99)
这些不适用于我......当我将时间戳转换回来时,已有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
答案 1 :(得分:68)
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)
答案 2 :(得分:11)
如果我们假设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
答案 3 :(得分: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 for Mac(及更早版本)使用1904 date system。
由于我经常使用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 for Mac,则需要使用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(原始的电子表格软件)故意treated 1900 as a leap year,尽管它不是(这在每个字节计数时减少了代码库)。 Microsoft Excel retained这个兼容性错误,跳过第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不承认否定日期,并且对第0天的1月份(1899/12/31)有一个特殊的定义。在内部,Excel确实处理负日期(它们毕竟只是数字),但它将它们显示为数字,因为它不知道如何将它们显示为日期(也不能将旧日期转换为负数)。 1900年2月29日,一个从未发生过的日子,被Excel认可,但不是LibreOffice。
答案 4 :(得分:3)
因为我对上述内容的编辑被拒绝了(你们其中任何人真的尝试过吗?),这就是你真正需要做的工作:
Windows(和Mac Office 2011 +):
(Excel Timestamp - 25569) * 86400
(Unix Timestamp / 86400) + 25569
MAC OS X(Office 2011之前):
(Excel Timestamp - 24107) * 86400
(Unix Timestamp / 86400) + 24107
答案 5 :(得分:2)
你显然已经休息了一天,恰好是86400秒。 使用数字2209161600 不是数字2209075200 如果你谷歌这两个数字,你会发现上述支持。 我尝试了你的公式,但总是与我的服务器不同1天。从unix时间戳开始并不明显,除非你在unix而不是人类时间考虑;-)但是如果你仔细检查那么你会发现这可能是正确的。
答案 6 :(得分: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月需要分开;而不是,
如果您也遇到此问题,希望对您有所帮助。 祝你有美好的一天:)
答案 7 :(得分:0)
目前的答案都没有对我有用,因为我的数据来自unix方面的格式:
2016-02-02 19:21:42 UTC
我需要将其转换为Epoch以允许引用具有纪元时间戳的其他数据。
为日期部分创建一个新列,并使用此公式进行解析
=DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4))
正如其他Grendler已在此处所述,创建另一列
=(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
答案 8 :(得分:0)
这是我对此的最终答案。
显然,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);
};
答案 9 :(得分:0)
要弥补夏令时(从3月的最后一个星期日开始,直到10月的最后一个星期日),我必须使用以下公式:
zeros(128,2e7,'single');
快速说明:
如果日期[“ A2”]在三月的最后一个星期日和十月的最后一个星期日[第三和第四代码行]之间,那么我将减去一个小时[-TIME(1; 0; 0)]
答案 10 :(得分:0)
如果您可以创建自定义函数(用户定义函数:UDF): 创建一个 VBA 模块并复制这些代码:
Function unix_time(Optional my_year, Optional my_month, Optional my_day, Optional my_hour, Optional my_minute, Optional my_second)
Dim now_date, now_time, ref_date, ref_time
my_year = IIf(IsMissing(my_year) = False, my_year, year(Now))
my_month = IIf(IsMissing(my_month) = False, my_month, month(Now))
my_day = IIf(IsMissing(my_day) = False, my_day, day(Now))
my_hour = IIf(IsMissing(my_hour) = False, my_hour, hour(Now))
my_minute = IIf(IsMissing(my_minute) = False, my_minute, minute(Now))
my_second = IIf(IsMissing(my_second) = False, my_second, second(Now))
now_date = DateSerial(my_year, my_month, my_day)
now_time = TimeSerial(my_hour, my_minute, my_second)
ref_date = DateSerial(1970, 1, 1)
ref_time = TimeSerial(0, 0, 0)'You can change this line based on your time zone. for example : Tehran -> TimeSerial(3,30,0)
now_date = now_date + now_time
ref_date = ref_date + ref_time
unix_time = (now_date - ref_date) * 86400
End Function
然后输入您想要的任何单元格:=unix_time()