@@ -1236,14 +1236,16 @@ cdef list extra_fmts = [(b"%q", b"^`AB`^"),
1236
1236
cdef list str_extra_fmts = [" ^`AB`^" , " ^`CD`^" , " ^`EF`^" ,
1237
1237
" ^`GH`^" , " ^`IJ`^" , " ^`KL`^" ]
1238
1238
1239
+ cdef inline int idx_first_nonfiscal_fmt = 3
1240
+
1239
1241
cdef str _period_strftime(int64_t value, int freq, bytes fmt):
1240
1242
cdef:
1241
1243
Py_ssize_t i
1242
1244
npy_datetimestruct dts
1243
1245
char * formatted
1244
1246
bytes pat, brepl
1245
1247
list found_pat = [False ] * len (extra_fmts)
1246
- int quarter
1248
+ int quarter, us, ps
1247
1249
str result, repl
1248
1250
1249
1251
get_date_info(value, freq, & dts)
@@ -1263,23 +1265,33 @@ cdef str _period_strftime(int64_t value, int freq, bytes fmt):
1263
1265
result = util.char_to_string(formatted)
1264
1266
free(formatted)
1265
1267
1268
+ # Now we will fill the placeholders corresponding to our additional directives
1269
+ # First prepare the contents
1270
+ if any (found_pat[idx_first_nonfiscal_fmt:]):
1271
+ # Save these to local vars as dts can be modified by get_yq below
1272
+ us = dts.us
1273
+ ps = dts.ps
1274
+ if any (found_pat[0 :idx_first_nonfiscal_fmt]):
1275
+ # Note: this modifies `dts` in-place so that year becomes fiscal year
1276
+ # However it looses the us and ps
1277
+ quarter = get_yq(value, freq, & dts)
1278
+
1279
+ # Now do the filling per se
1266
1280
for i in range (len (extra_fmts)):
1267
1281
if found_pat[i]:
1268
1282
1269
- quarter = get_yq(value, freq, & dts)
1270
-
1271
- if i == 0 :
1272
- repl = str (quarter)
1273
- elif i == 1 : # %f, 2-digit year
1283
+ if i == 0 : # %q, 1-digit quarter.
1284
+ repl = f" {quarter}"
1285
+ elif i == 1 : # %f, 2-digit 'Fiscal' year
1274
1286
repl = f" {(dts.year % 100):02d}"
1275
- elif i == 2 :
1287
+ elif i == 2 : # %F, 'Fiscal' year with a century
1276
1288
repl = str (dts.year)
1277
- elif i == 3 :
1278
- repl = f" {(value % 1_000):03d}"
1279
- elif i == 4 :
1280
- repl = f" {(value % 1_000_000 ):06d}"
1281
- elif i == 5 :
1282
- repl = f" {(value % 1_000_000_000 ):09d}"
1289
+ elif i == 3 : # %l, milliseconds
1290
+ repl = f" {(us // 1_000):03d}"
1291
+ elif i == 4 : # %u, microseconds
1292
+ repl = f" {(us ):06d}"
1293
+ elif i == 5 : # %n, nanoseconds
1294
+ repl = f" {((us * 1000) + (ps // 1000) ):09d}"
1283
1295
1284
1296
result = result.replace(str_extra_fmts[i], repl)
1285
1297
@@ -2332,7 +2344,8 @@ cdef class _Period(PeriodMixin):
2332
2344
containing one or several directives. The method recognizes the same
2333
2345
directives as the :func:`time.strftime` function of the standard Python
2334
2346
distribution , as well as the specific additional directives ``%f``,
2335
- ``%F``, ``%q``. (formatting & docs originally from scikits.timeries ).
2347
+ ``%F``, ``%q``, ``%l``, ``%u``, ``%n``.
2348
+ (formatting & docs originally from scikits.timeries ).
2336
2349
2337
2350
+-----------+--------------------------------+-------+
2338
2351
| Directive | Meaning | Notes |
@@ -2379,11 +2392,20 @@ cdef class _Period(PeriodMixin):
2379
2392
| | AM or PM. | |
2380
2393
+-----------+--------------------------------+-------+
2381
2394
| ``%q`` | Quarter as a decimal number | |
2382
- | | [01,04] | |
2395
+ | | [1,4] | |
2383
2396
+-----------+--------------------------------+-------+
2384
2397
| ``%S`` | Second as a decimal number | \(4) |
2385
2398
| | [00,61]. | |
2386
2399
+-----------+--------------------------------+-------+
2400
+ | ``%l`` | Millisecond as a decimal number| |
2401
+ | | [000,999]. | |
2402
+ +-----------+--------------------------------+-------+
2403
+ | ``%u`` | Microsecond as a decimal number| |
2404
+ | | [000000,999999]. | |
2405
+ +-----------+--------------------------------+-------+
2406
+ | ``%n`` | Nanosecond as a decimal number | |
2407
+ | | [000000000,999999999]. | |
2408
+ +-----------+--------------------------------+-------+
2387
2409
| ``%U`` | Week number of the year | \(5) |
2388
2410
| | (Sunday as the first day of | |
2389
2411
| | the week ) as a decimal number | |
0 commit comments