Dates and Times日期和时间
Lotus 1-2-3, Excel, and other spreadsheet software do not have a true concept of date or time. Lotus 1-2-3、Excel和其他电子表格软件没有真正的日期或时间概念。Instead, dates and times are stored as offsets from an epoch. 相反,日期和时间存储为与历元的偏移量。The magic behind date interpretations is hidden in functions or number formats.日期解释背后的魔力隐藏在函数或数字格式中。
SheetJS attempts to create a friendly JS date experience while also exposing options to use the traditional date codesSheetJS试图创建一个友好的JS日期体验,同时还公开了使用传统日期代码的选项
How Spreadsheets Understand Time电子表格如何理解时间
Excel stores dates as numbers. Excel将日期存储为数字。When displaying dates, the format code should include special date and time tokens like 显示日期时,格式代码应包括特殊的日期和时间标记,如yyyyy
for long year. yyyyy
表示长年份。EDATE
and other date functions operate on and return date numbers.和其他日期函数操作并返回日期编号。
For date formats like 对于yyyy-mm-dd
, the integer part represents the number of days from a starting epoch. yyyy-mm-dd
等日期格式,整数部分表示从开始纪元算起的天数。For example, the date 例如,19-Feb-17
is stored as the number 42785
with a number format of d-mmm-yy
.19-Feb-17
存储为数字42785
,数字格式为d-mmm-yy
。
The fractional part of the date code serves as the time marker. 日期代码的小数部分用作时间标记。Excel assumes each day has exactly 86400 seconds. Excel假设每天有86400秒。For example, the date code 例如,日期代码0.25
has a time component corresponding to 6:00 AM.0.25
具有对应于上午6:00的时间分量。
For absolute time formats like 对于绝对时间格式,如[hh]:mm
, the integer part represents a whole number of 24-hour (or 1440 minute) intervals. [hh]:mm
,整数部分表示24小时(或1440分钟)间隔的整数。The value 格式为1.5
in the format [hh]:mm
is interpreted as 36 hours 0 minutes.[hh]:mm
的值1.5
被解释为36小时0分钟。
Date and Time Number Formats日期和时间数字格式
Assuming a cell has a formatted date, re-formatting as "General" will reveal the underlying value. 假设一个单元格有一个格式化的日期,将其重新格式化为“General”将显示底层值。Alternatively, the 或者,可以使用TEXT
function can be used to return the date code.TEXT
函数返回日期代码。
The following table covers some common formats:下表涵盖了一些常见格式:
Common Date-Time Formats通用日期时间格式 (click to hide)
yy | |
yyyy | |
m | |
mm | |
mmm | |
mmmm | |
mmmmm | |
d | |
dd | |
ddd | |
dddd | |
h | |
hh | |
m | |
mm | |
s | |
ss | |
A/P | |
AM/PM |
m
and 和mm
are context-dependent. 依赖于上下文。It is interpreted as "minutes" when the previous or next date token represents a time (hours or seconds):当上一个或下一个日期标记表示时间(小时或秒)时,它被解释为“分钟”:
yyyy-mm-dd hh:mm:ss
^^ ^^
month minutes
1904 and 1900 Date Systems1904和1900日期系统
The interpretation of date codes requires a shared understanding of date code 日期代码的解释需要对日期代码0
, otherwise known as the "epoch". 0
(也称为“epoch”)有共同的理解。Excel supports two epochs:Excel支持两个时代:
-
The default epoch is "January 0 1900".默认纪元为“1900年1月0日”。The0
value is 00:00 on December 31 of the year 1899, but it is formatted as January 0 1900.0
值为1899年12月31日的00:00,但其格式为1900年1月0日。 -
Enabling "1904 Date System" sets the default epoch to "January 1 1904".启用“1904日期系统”将默认历元设置为“1904年1月1日”。The0
value is 00:00 on January 1 of the year 1904.0
值为1904年1月1日的00:00。
The workbook's epoch can be determined by examining the workbook's 可以通过检查工作簿的wb.Workbook.WBProps.date1904
property:wb.Workbook.WBProps.date1904
属性来确定工作簿的时代:
if ( ! ! ( ( ( wb . Workbook || { } ) . WBProps || { } ) . date1904 ) ) {
/* uses 1904 date system */
} else {
/* uses 1900 date system */
}
Why does the 1904 date system exist?为什么存在1904年的日期系统?
1900 was not a leap year. 1900年不是闰年。For the Gregorian calendar, the general rules are:对于公历,一般规则为:
every multiple of 400 is a leap year每乘以400就是闰年every multiple of 100 that is not a multiple of 400 is not a leap year每100的倍数不是400的倍数就不是闰年every multiple of 4 that is not a multiple of 100 is a leap year每4的倍数不是100的倍数就是闰年all other years are not leap years.其他年份都不是闰年。
Lotus 1-2-3 erroneously treated 1900 as a leap year. 莲花1-2-3错误地将1900年视为闰年。This can be verified with the 这可以通过@date
function:@date
函数进行验证:
@date(0,2,28) -> 59 // Lotus accepts 2/28/1900
@date(0,2,29) -> 60 // <--2/29/1900 was not a real date
@date(0.2,30) -> ERR // Lotus rejects 2/30/1900
Excel extends the tradition in the default date system. Excel扩展了默认日期系统中的传统。The 1904 date system starts the count in 1904, skipping the bad date.1904年的日期系统从1904年开始计数,跳过错误的日期。
Relative Epochs相对时代
The epoch is based on the system timezone. 历元基于系统时区。The epoch in New York is midnight in Eastern time, while the epoch in Seattle is midnight in Pacific time.纽约的纪元是东部时间的午夜,而西雅图的纪元是太平洋时间的午夜。
This design has the advantage of uniform time display: "12 PM" is 12 PM irrespective of the timezone of the viewer. 这种设计具有统一时间显示的优点:“12 PM”是12 PM,与观看者的时区无关。However, this design precludes any international coordination (there is no way to create a value that represents an absolute time) and makes JavaScript processing somewhat ambiguous (since JavaScript Date objects are timezone-aware)然而,这种设计排除了任何国际协调(无法创建表示绝对时间的值),并使JavaScript处理有些模糊(因为JavaScript日期对象具有时区意识)
This is a deficiency of the spreadsheet software. 这是电子表格软件的一个缺陷。Excel has no native concept of universal time.Excel没有通用时间的固有概念。
The library attempts to normalize the dates. 图书馆试图使日期正常化。All times are specified in the local time zone. 所有时间均在本地时区中指定。SheetJS cannot magically fix the technical problems with Excel and other spreadsheet software, but this represents .SheetJS无法神奇地解决Excel和其他电子表格软件的技术问题,但这代表了。
How Files Store Dates and Times文件如何存储日期和时间
XLS, XLSB, and most binary formats store the raw date codes. XLS、XLSB和大多数二进制格式存储原始日期代码。Special number formats are used to indicate that the values are intended to be dates/times.特殊数字格式用于指示值是日期/时间。
CSV and other plaintext formats typically store actual formatted date values. CSV和其他纯文本格式通常存储实际的格式化日期值。They are interpreted as dates and times in the user timezone.它们被解释为用户时区中的日期和时间。
XLSX actually supports both! XLSX实际上支持这两者!Typically dates are stored as 通常,日期存储为n
numeric cells, but the format supports a special type d
where the data is an ISO 8601 date string. n
个数字单元格,但该格式支持特殊类型d
,其中数据是ISO 8601日期字符串。This is not used in the default Excel XLSX export and third-party support is poor.默认Excel XLSX导出中未使用此选项,第三方支持较差。
ODS does support absolute time values but drops the actual timezone indicator when parsing. ODS确实支持绝对时间值,但在解析时会删除实际的时区指示器。In that sense, LibreOffice follows the same behavior as Excel.从这个意义上说,LibreOffice遵循与Excel相同的行为。
How SheetJS handles Dates and TimesSheetJS如何处理日期和时间
The default behavior for all parsers is to generate number cells. 所有解析器的默认行为都是生成数字单元格。Passing the 将cellDates
to true will force the parsers to store dates:cellDates
传递为true
将强制解析器存储日期:
// cell A1 will be { t: 'n', v: 44721 }
var wb_sans_date = XLSX . read ( "6/9/2022" , { type : "binary" } ) ;
// cell A1 will be { t: 'd', v: <Date object representing June 9 2022> }
var wb_with_date = XLSX . read ( "6/9/2022" , { type : "binary" , cellDates : true } ) ;
When writing, date cells are automatically translated back to numeric cells with an appropriate number format.写入时,日期单元格自动转换回具有适当数字格式的数字单元格。
The actual values stored in cells are intended to be correct from the perspective of an Excel user in the current timezone.从Excel用户在当前时区的角度来看,存储在单元格中的实际值是正确的。
The value formatter understands date formats and converts when relevant.值格式化程序理解日期格式,并在相关时进行转换。
Utility Functions实用程序函数
Utility functions that deal with JS data accept a 处理JS数据的实用程序函数接受cellDates
argument which dictates how dates should be handled.cellDates
参数,该参数指示应如何处理日期。
Functions that create a worksheet will adjust date cells and use a number format like 创建工作表的函数将调整日期单元格,并使用m/d/yy
to mark dates:m/d/yy
等数字格式来标记日期:
// Cell A1 will be a numeric cell whose value is the date code
var ws = XLSX . utils . aoa_to_sheet ( [ [ new Date ( ) ] ] ) ;
// Cell A1 will be a date cell
var ws = XLSX . utils . aoa_to_sheet ( [ [ new Date ( ) ] ] , { cellDates : true } ) ;
Functions that create an array of JS objects with raw values will keep the native representation:使用原始值创建JS对象数组的函数将保留本机表示:
// Cell A1 is numeric -> output is a number
var ws = XLSX . utils . aoa_to_sheet ( [ [ new Date ( ) ] ] ) ;
var A1 = XLSX . utils . sheet_to_json ( ws , { header : 1 } ) [ 0 ] [ 0 ] ;
// Cell A1 is a date -> output is a date
var ws = XLSX . utils . aoa_to_sheet ( [ [ new Date ( ) ] ] , { cellDates : true } ) ;
var A1 = XLSX . utils . sheet_to_json ( ws , { header : 1 } ) [ 0 ] [ 0 ] ;
Number Formats字格式
By default, the number formats are not emitted. 默认情况下,不会发出数字格式。For Excel-based file formats, passing the option 对于基于Excel的文件格式,传递选项cellNF: true
adds the z
field.cellNF:true
会添加z
字段。
The helper function 辅助函数XLSX.SSF.is_date
parses formats and returns true
if the format represents a date or time:XLSX.SSF.is_date
解析格式,如果格式表示日期或时间,则返回true
:
XLSX . SSF . is_date ( "yyyy-mm-dd" ) ; // true
XLSX . SSF . is_date ( "0.00" ) ; // false