Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重学js —— Date 对象一 #115

Open
lizhongzhen11 opened this issue Jun 2, 2020 · 0 comments
Open

重学js —— Date 对象一 #115

lizhongzhen11 opened this issue Jun 2, 2020 · 0 comments
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN

Comments

@lizhongzhen11
Copy link
Owner

Date 对象一

Time值和Time范围

ECMAScript中的时间测量类似于 POSIX 中的时间测量,尤其是根据通用的公历定义,即UTC 1970年1月1日开始的一个午夜纪元,并且每天的准确计算为86,400秒(每秒为1000毫秒)。

ECMAScript中的 time valueNumber 类型,可以是表示时间到毫秒精度的有限整数,也可以是不表示特定时间的 NaN。时间值是 24×60×60×1000 = 86,400,000 的倍数(即,对于某个整数 d 等于 86,400,000×d)表示自UTC日开始历时 d 天。(在负 d 的时间之前)。每一个其他的有限时间值 t 都是相对于最大的前一时间值 s 定义的,前一时间值 s 是这样的倍数,表示在 s 的同一个UTC天内发生的、但随后又是 t-s 毫秒的瞬间。

时间值不考虑UTC闰秒——没有代表正闰秒内的时间值,有时间值表示以负闰秒为单位从UTC时间线上删除的瞬间。但是,时间值的定义仍然与UTC分段对齐,仅在闰秒边界处具有不连续性,闰秒以外的零差。

一个数字可以精确表示从 -9,007,199,254,740,9929,007,199,254,740,992重学js —— Number 对象)的所有整数。时间值支持 -8,640,000,000,000,0008,640,000,000,000,000 毫秒的较小范围。这就产生了相对于 UTC 1970年1月1日 午夜开始的 -100,000,000天100,000,000天 的支持时间值范围。

格林尼治标准时间1970年1月1日开始的确切午夜时刻由时间值 +0 表示。

注意:公历的400年周期包含97个闰年。每年平均产生365.2425天,即31,556,952,000毫秒。因此,相对于1970年,Number 可以精确地代表毫秒精度的最大范围是 -285,426285,426 年。规范中 Date章节 指定的时间值所支持的较小范围相对于1970年约为 -273,790至273,790年

天数和一天中的时间

时间值 t 对应的天数:

Day(t) = floor(t / msPerDay)

每天的毫秒数:

msPerDay = 86400000

其余时间称为一天中的时间:

TimeWithinDay(t) = t modulo msPerDay

年数

ECMAScript使用冗长的公历将日期编号映射为年份编号,并确定该年份中的月份和日期。该历中,闰年恰好是(可被4整除)和((不可被100整除)或(可被400整除))的年份。因此,第y年的天数定义为:

DaysInYear(y)
    = 365 if (y modulo 4)  0
    = 366 if (y modulo 4) = 0 and (y modulo 100)  0
    = 365 if (y modulo 100) = 0 and (y modulo 400)  0
    = 366 if (y modulo 400) = 0

所有的非闰年有 365 天,闰年2月有29天。y年第一天的天数为:

DayFromYear(y) = 365 × (y - 1970) + floor((y - 1969) / 4) - floor((y - 1901) / 100) + floor((y - 1601) / 400)

年初的时间值为:

TimeFromYear(y) = msPerDay × DayFromYear(y)

时间值通过以下方式确定年份:

YearFromTime(t) = the largest integer y (closest to positive infinity) such that TimeFromYear(y)  t

闰年中闰年函数为1否则为0:

InLeapYear(t)
    = 0 if DaysInYear(YearFromTime(t)) = 365
    = 1 if DaysInYear(YearFromTime(t)) = 366

Month Number

月份是 0 ~ 11 范围内的整数。MonthFromTime(t)将时间值 t 映射到月数的方式定义为:

MonthFromTime(t)
    = 0 if 0  DayWithinYear(t) < 31
    = 1 if 31  DayWithinYear(t) < 59 + InLeapYear(t)
    = 2 if 59 + InLeapYear(t)  DayWithinYear(t) < 90 + InLeapYear(t)
    = 3 if 90 + InLeapYear(t)  DayWithinYear(t) < 120 + InLeapYear(t)
    = 4 if 120 + InLeapYear(t)  DayWithinYear(t) < 151 + InLeapYear(t)
    = 5 if 151 + InLeapYear(t)  DayWithinYear(t) < 181 + InLeapYear(t)
    = 6 if 181 + InLeapYear(t)  DayWithinYear(t) < 212 + InLeapYear(t)
    = 7 if 212 + InLeapYear(t)  DayWithinYear(t) < 243 + InLeapYear(t)
    = 8 if 243 + InLeapYear(t)  DayWithinYear(t) < 273 + InLeapYear(t)
    = 9 if 273 + InLeapYear(t)  DayWithinYear(t) < 304 + InLeapYear(t)
    = 10 if 304 + InLeapYear(t)  DayWithinYear(t) < 334 + InLeapYear(t)
    = 11 if 334 + InLeapYear(t)  DayWithinYear(t) < 365 + InLeapYear(t)

DayWithinYear(t) = Day(t) - DayFromYear(YearFromTime(t))

Date Number

1 ~ 31 的整数。DateFromTime(t) 将时间值 t 映射为日期数:

DateFromTime(t)
    = DayWithinYear(t) + 1 if MonthFromTime(t) = 0
    = DayWithinYear(t) - 30 if MonthFromTime(t) = 1
    = DayWithinYear(t) - 58 - InLeapYear(t) if MonthFromTime(t) = 2
    = DayWithinYear(t) - 89 - InLeapYear(t) if MonthFromTime(t) = 3
    = DayWithinYear(t) - 119 - InLeapYear(t) if MonthFromTime(t) = 4
    = DayWithinYear(t) - 150 - InLeapYear(t) if MonthFromTime(t) = 5
    = DayWithinYear(t) - 180 - InLeapYear(t) if MonthFromTime(t) = 6
    = DayWithinYear(t) - 211 - InLeapYear(t) if MonthFromTime(t) = 7
    = DayWithinYear(t) - 242 - InLeapYear(t) if MonthFromTime(t) = 8
    = DayWithinYear(t) - 272 - InLeapYear(t) if MonthFromTime(t) = 9
    = DayWithinYear(t) - 303 - InLeapYear(t) if MonthFromTime(t) = 10
    = DayWithinYear(t) - 333 - InLeapYear(t) if MonthFromTime(t) = 11

Week Day

WeekDay(t) = (Day(t) + 4) modulo 7

Hours, Minutes, Second, and Milliseconds

HourFromTime(t) = floor(t / msPerHour) modulo HoursPerDay
MinFromTime(t) = floor(t / msPerMinute) modulo MinutesPerHour
SecFromTime(t) = floor(t / msPerSecond) modulo SecondsPerMinute
msFromTime(t) = t modulo msPerSecond

HoursPerDay = 24
MinutesPerHour = 60
SecondsPerMinute = 60
msPerSecond = 1000
msPerMinute = 60000 = msPerSecond × SecondsPerMinute
msPerHour = 3600000 = msPerMinute × MinutesPerHour

MakeTime ( hour, min, sec, ms )

  1. 如果 hour 不是有限的或者 min 不是有限的或 sec 不是有限的或 ms不是有限的,返回 NaN
  2. 定义 h! ToInteger(hour)
  3. 定义 m! ToInteger(min)
  4. 定义 s! ToInteger(sec)
  5. 定义 milli! ToInteger(ms)
  6. 定义 th * msPerHour + m * msPerMinute + s * msPerSecond + milli,根据 IEEE 754-2019 规则执行算法(就像使用ECMAScript运算符 *+ 一样)。
  7. 返回 t

MakeDay ( year, month, date )

  1. 如果 year 不是有限的或者 month 不是有限的或 date 不是有限,返回 NaN
  2. 定义 y! ToInteger(year)
  3. 定义 m! ToInteger(month)
  4. 定义 dt! ToInteger(date)
  5. 定义 ymy + floor(m / 12)
  6. 定义 mnm modulo 12
  7. 找到一个值 t 使得 YearFromTime(t)ymMonthFromTime(t)mnDateFromTime(t) 是 1;但如果没有这样的值(参数可能超出范围),返回 NaN
  8. 返回 Day(t) + dt - 1

MakeDate ( day, time )

  1. 如果 day 不是有限的或 time 不是有限的,返回 NaN
  2. 返回 day × msPerDay + time

TimeClip ( time )

  1. 如果 time 不是有限的,返回 NaN
  2. 如果 abs(time) > 8.64 × 1015,返回 NaN
  3. 返回 ! ToInteger(time)

日期时间字符串格式

ECMAScript基于ISO 8601日历日期扩展格式的简化,为日期时间定义了字符串交换格式。格式如下:YYYY-MM-DDTHH:mm:ss.sssZ

  • YYYY 是公历阳历中的年份,从0000到9999之间为四个十进制数字,或作为 扩展年份 “ +”或“-”,后跟六个十进制数字。
  • - (连字符)在字符串中字面出现两次
  • MM 是一年中的月份,从01(一月)到12(十二月)的两位十进制数字。
  • DD 是月份的日期,是从01到31的两位十进制数字。
  • T 出现在字符串中,用于指示时间元素的开始。
  • HH 是从午夜以来经过的完整小时数,从00到24为两位十进制数字。
  • : (冒号)在字符串中字面出现两次
  • mm 是从小时开始到现在的完整分钟数,从00到59的两位十进制数字。
  • ss 是从分钟开始算起的完整秒数,从00到59的两位十进制数字。
  • . (点)在字符串中字面上出现
  • sss 是从秒开始的完整毫秒数,为三个十进制数字。
  • Z 是指定为“ Z”的UTC偏移量表示形式(对于没有偏移量的UTC)或“ +”或“-”的偏移量,后跟时间表达式HH:mm(分别指示UTC之前或之后的本地时间)

此格式包括仅日期形式:

YYYY
YYYY-MM
YYYY-MM-DD

它还包括“日期时间”格式,该格式由上述日期格式之一组成,紧随其后的是以下时间格式之一,并附加了可选的UTC偏移量表示形式:

THH:mm
THH:mm:ss
THH:mm:ss.sss
@lizhongzhen11 lizhongzhen11 added js基础 Good for newcomers 重学js 重学js系列 规范+MDN labels Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN
Projects
None yet
Development

No branches or pull requests

1 participant