@@ -9,6 +9,7 @@ from cpython.object cimport (
9
9
PyObject_RichCompareBool,
10
10
)
11
11
from numpy cimport (
12
+ int32_t,
12
13
int64_t,
13
14
ndarray,
14
15
)
@@ -1217,39 +1218,56 @@ cdef str _period_strftime(int64_t value, int freq, bytes fmt):
1217
1218
char * formatted
1218
1219
bytes pat, brepl
1219
1220
list found_pat = [False ] * len (extra_fmts)
1220
- int year, quarter
1221
+ int quarter
1222
+ int32_t us, ps
1221
1223
str result, repl
1222
1224
1223
1225
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
1224
1229
for i in range (len (extra_fmts)):
1225
1230
pat = extra_fmts[i][0 ]
1226
1231
brepl = extra_fmts[i][1 ]
1227
1232
if pat in fmt:
1228
1233
fmt = fmt.replace(pat, brepl)
1229
1234
found_pat[i] = True
1230
1235
1236
+ # Execute c_strftime to process the usual datetime directives
1231
1237
formatted = c_strftime(& dts, < char * > fmt)
1232
1238
1233
1239
result = util.char_to_string(formatted)
1234
1240
free(formatted)
1235
1241
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
1236
1256
for i in range (len (extra_fmts)):
1237
1257
if found_pat[i]:
1238
1258
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
1244
1262
repl = f" {(dts.year % 100):02d}"
1245
- elif i == 2 :
1263
+ elif i == 2 : # %F, 'Fiscal' year with a century
1246
1264
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}"
1253
1271
1254
1272
result = result.replace(str_extra_fmts[i], repl)
1255
1273
@@ -2302,7 +2320,8 @@ cdef class _Period(PeriodMixin):
2302
2320
containing one or several directives. The method recognizes the same
2303
2321
directives as the :func:`time.strftime` function of the standard Python
2304
2322
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 ).
2306
2325
2307
2326
+-----------+--------------------------------+-------+
2308
2327
| Directive | Meaning | Notes |
@@ -2349,11 +2368,20 @@ cdef class _Period(PeriodMixin):
2349
2368
| | AM or PM. | |
2350
2369
+-----------+--------------------------------+-------+
2351
2370
| ``%q`` | Quarter as a decimal number | |
2352
- | | [01,04] | |
2371
+ | | [1,4] | |
2353
2372
+-----------+--------------------------------+-------+
2354
2373
| ``%S`` | Second as a decimal number | \(4) |
2355
2374
| | [00,61]. | |
2356
2375
+-----------+--------------------------------+-------+
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
+ +-----------+--------------------------------+-------+
2357
2385
| ``%U`` | Week number of the year | \(5) |
2358
2386
| | (Sunday as the first day of | |
2359
2387
| | the week ) as a decimal number | |
0 commit comments