MCPcopy Create free account
hub / github.com/RT-Thread/env-windows / _ord2ymd

Function _ord2ymd

tools/python-3.11.9-amd64/Lib/datetime.py:88–148  ·  view source on GitHub ↗

ordinal -> (year, month, day), considering 01-Jan-0001 as day 1.

(n)

Source from the content-addressed store, hash-verified

86assert _DI100Y == 25 * _DI4Y - 1
87
88def _ord2ymd(n):
89 "ordinal -> (year, month, day), considering 01-Jan-0001 as day 1."
90
91 # n is a 1-based index, starting at 1-Jan-1. The pattern of leap years
92 # repeats exactly every 400 years. The basic strategy is to find the
93 # closest 400-year boundary at or before n, then work with the offset
94 # from that boundary to n. Life is much clearer if we subtract 1 from
95 # n first -- then the values of n at 400-year boundaries are exactly
96 # those divisible by _DI400Y:
97 #
98 # D M Y n n-1
99 # -- --- ---- ---------- ----------------
100 # 31 Dec -400 -_DI400Y -_DI400Y -1
101 # 1 Jan -399 -_DI400Y +1 -_DI400Y 400-year boundary
102 # ...
103 # 30 Dec 000 -1 -2
104 # 31 Dec 000 0 -1
105 # 1 Jan 001 1 0 400-year boundary
106 # 2 Jan 001 2 1
107 # 3 Jan 001 3 2
108 # ...
109 # 31 Dec 400 _DI400Y _DI400Y -1
110 # 1 Jan 401 _DI400Y +1 _DI400Y 400-year boundary
111 n -= 1
112 n400, n = divmod(n, _DI400Y)
113 year = n400 * 400 + 1 # ..., -399, 1, 401, ...
114
115 # Now n is the (non-negative) offset, in days, from January 1 of year, to
116 # the desired date. Now compute how many 100-year cycles precede n.
117 # Note that it's possible for n100 to equal 4! In that case 4 full
118 # 100-year cycles precede the desired day, which implies the desired
119 # day is December 31 at the end of a 400-year cycle.
120 n100, n = divmod(n, _DI100Y)
121
122 # Now compute how many 4-year cycles precede it.
123 n4, n = divmod(n, _DI4Y)
124
125 # And now how many single years. Again n1 can be 4, and again meaning
126 # that the desired day is December 31 at the end of the 4-year cycle.
127 n1, n = divmod(n, 365)
128
129 year += n100 * 100 + n4 * 4 + n1
130 if n1 == 4 or n100 == 4:
131 assert n == 0
132 return year-1, 12, 31
133
134 # Now the year is correct, and n is the offset from January 1. We find
135 # the month via an estimate that's either exact or one too large.
136 leapyear = n1 == 3 and (n4 != 24 or n100 == 3)
137 assert leapyear == _is_leap(year)
138 month = (n + 50) >> 5
139 preceding = _DAYS_BEFORE_MONTH[month] + (month > 2 and leapyear)
140 if preceding > n: # estimate is too large
141 month -= 1
142 preceding -= _DAYS_IN_MONTH[month] + (month == 2 and leapyear)
143 n -= preceding
144 assert 0 <= n < _days_in_month(year, month)
145

Callers 2

_isoweek_to_gregorianFunction · 0.85
fromordinalMethod · 0.85

Calls 2

_is_leapFunction · 0.85
_days_in_monthFunction · 0.85

Tested by

no test coverage detected