@@ -9,6 +9,7 @@ from cpython.object cimport (
99 PyObject_RichCompareBool,
1010)
1111from numpy cimport (
12+ int32_t,
1213 int64_t,
1314 ndarray,
1415)
@@ -1217,39 +1218,56 @@ cdef str _period_strftime(int64_t value, int freq, bytes fmt):
12171218 char * formatted
12181219 bytes pat, brepl
12191220 list found_pat = [False ] * len (extra_fmts)
1220- int year, quarter
1221+ int quarter
1222+ int32_t us, ps
12211223 str result, repl
12221224
12231225 get_date_info(value, freq, & dts)
1226+
1227+ # Find our additional directives in the pattern and replace them with
1228+ # placeholders that are not processed by c_strftime
12241229 for i in range (len (extra_fmts)):
12251230 pat = extra_fmts[i][0 ]
12261231 brepl = extra_fmts[i][1 ]
12271232 if pat in fmt:
12281233 fmt = fmt.replace(pat, brepl)
12291234 found_pat[i] = True
12301235
1236+ # Execute c_strftime to process the usual datetime directives
12311237 formatted = c_strftime(& dts, < char * > fmt)
12321238
12331239 result = util.char_to_string(formatted)
12341240 free(formatted)
12351241
1242+ # Now we will fill the placeholders corresponding to our additional directives
1243+
1244+ # First prepare the contents
1245+ # Save these to local vars as dts can be modified by get_yq below
1246+ us = dts.us
1247+ ps = dts.ps
1248+ if any (found_pat[0 :3 ]):
1249+ # Note: this modifies `dts` in-place so that year becomes fiscal year
1250+ # However it looses the us and ps
1251+ quarter = get_yq(value, freq, & dts)
1252+ else :
1253+ quarter = 0
1254+
1255+ # Now do the filling per se
12361256 for i in range (len (extra_fmts)):
12371257 if found_pat[i]:
12381258
1239- quarter = get_yq(value, freq, & dts)
1240-
1241- if i == 0 :
1242- repl = str (quarter)
1243- elif i == 1 : # %f, 2-digit year
1259+ if i == 0 : # %q, 1-digit quarter.
1260+ repl = f" {quarter}"
1261+ elif i == 1 : # %f, 2-digit 'Fiscal' year
12441262 repl = f" {(dts.year % 100):02d}"
1245- elif i == 2 :
1263+ elif i == 2 : # %F, 'Fiscal' year with a century
12461264 repl = str (dts.year)
1247- elif i == 3 :
1248- repl = f" {(value % 1_000):03d}"
1249- elif i == 4 :
1250- repl = f" {(value % 1_000_000 ):06d}"
1251- elif i == 5 :
1252- repl = f" {(value % 1_000_000_000 ):09d}"
1265+ elif i == 3 : # %l, milliseconds
1266+ repl = f" {(us // 1_000):03d}"
1267+ elif i == 4 : # %u, microseconds
1268+ repl = f" {(us ):06d}"
1269+ elif i == 5 : # %n, nanoseconds
1270+ repl = f" {((us * 1000) + (ps // 1000) ):09d}"
12531271
12541272 result = result.replace(str_extra_fmts[i], repl)
12551273
@@ -2302,7 +2320,8 @@ cdef class _Period(PeriodMixin):
23022320 containing one or several directives. The method recognizes the same
23032321 directives as the :func:`time.strftime` function of the standard Python
23042322 distribution , as well as the specific additional directives ``%f``,
2305- ``%F``, ``%q``. (formatting & docs originally from scikits.timeries ).
2323+ ``%F``, ``%q``, ``%l``, ``%u``, ``%n``.
2324+ (formatting & docs originally from scikits.timeries ).
23062325
23072326 +-----------+--------------------------------+-------+
23082327 | Directive | Meaning | Notes |
@@ -2349,11 +2368,20 @@ cdef class _Period(PeriodMixin):
23492368 | | AM or PM. | |
23502369 +-----------+--------------------------------+-------+
23512370 | ``%q`` | Quarter as a decimal number | |
2352- | | [01,04] | |
2371+ | | [1,4] | |
23532372 +-----------+--------------------------------+-------+
23542373 | ``%S`` | Second as a decimal number | \(4) |
23552374 | | [00,61]. | |
23562375 +-----------+--------------------------------+-------+
2376+ | ``%l`` | Millisecond as a decimal number| |
2377+ | | [000,999]. | |
2378+ +-----------+--------------------------------+-------+
2379+ | ``%u`` | Microsecond as a decimal number| |
2380+ | | [000000,999999]. | |
2381+ +-----------+--------------------------------+-------+
2382+ | ``%n`` | Nanosecond as a decimal number | |
2383+ | | [000000000,999999999]. | |
2384+ +-----------+--------------------------------+-------+
23572385 | ``%U`` | Week number of the year | \(5) |
23582386 | | (Sunday as the first day of | |
23592387 | | the week ) as a decimal number | |
0 commit comments