@@ -1506,6 +1506,27 @@ format_utcoffset(char *buf, size_t buflen, const char *sep,
15061506 return 0 ;
15071507}
15081508
1509+ static PyObject *
1510+ make_somezreplacement (PyObject * object , char * sep , PyObject * tzinfoarg )
1511+ {
1512+ char buf [100 ];
1513+ PyObject * tzinfo = get_tzinfo_member (object );
1514+
1515+ if (tzinfo == Py_None || tzinfo == NULL ) {
1516+ return PyBytes_FromStringAndSize (NULL , 0 );
1517+ }
1518+
1519+ assert (tzinfoarg != NULL );
1520+ if (format_utcoffset (buf ,
1521+ sizeof (buf ),
1522+ sep ,
1523+ tzinfo ,
1524+ tzinfoarg ) < 0 )
1525+ return NULL ;
1526+
1527+ return PyBytes_FromStringAndSize (buf , strlen (buf ));
1528+ }
1529+
15091530static PyObject *
15101531make_Zreplacement (PyObject * object , PyObject * tzinfoarg )
15111532{
@@ -1566,7 +1587,7 @@ make_freplacement(PyObject *object)
15661587
15671588/* I sure don't want to reproduce the strftime code from the time module,
15681589 * so this imports the module and calls it. All the hair is due to
1569- * giving special meanings to the %z, %Z and %f format codes via a
1590+ * giving special meanings to the %z, %:z, % Z and %f format codes via a
15701591 * preprocessing step on the format string.
15711592 * tzinfoarg is the argument to pass to the object's tzinfo method, if
15721593 * needed.
@@ -1578,6 +1599,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
15781599 PyObject * result = NULL ; /* guilty until proved innocent */
15791600
15801601 PyObject * zreplacement = NULL ; /* py string, replacement for %z */
1602+ PyObject * colonzreplacement = NULL ; /* py string, replacement for %:z */
15811603 PyObject * Zreplacement = NULL ; /* py string, replacement for %Z */
15821604 PyObject * freplacement = NULL ; /* py string, replacement for %f */
15831605
@@ -1632,32 +1654,29 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
16321654 }
16331655 /* A % has been seen and ch is the character after it. */
16341656 else if (ch == 'z' ) {
1657+ /* %z -> +HHMM */
16351658 if (zreplacement == NULL ) {
1636- /* format utcoffset */
1637- char buf [100 ];
1638- PyObject * tzinfo = get_tzinfo_member (object );
1639- zreplacement = PyBytes_FromStringAndSize ("" , 0 );
1640- if (zreplacement == NULL ) goto Done ;
1641- if (tzinfo != Py_None && tzinfo != NULL ) {
1642- assert (tzinfoarg != NULL );
1643- if (format_utcoffset (buf ,
1644- sizeof (buf ),
1645- "" ,
1646- tzinfo ,
1647- tzinfoarg ) < 0 )
1648- goto Done ;
1649- Py_DECREF (zreplacement );
1650- zreplacement =
1651- PyBytes_FromStringAndSize (buf ,
1652- strlen (buf ));
1653- if (zreplacement == NULL )
1654- goto Done ;
1655- }
1659+ zreplacement = make_somezreplacement (object , "" , tzinfoarg );
1660+ if (zreplacement == NULL )
1661+ goto Done ;
16561662 }
16571663 assert (zreplacement != NULL );
1664+ assert (PyBytes_Check (zreplacement ));
16581665 ptoappend = PyBytes_AS_STRING (zreplacement );
16591666 ntoappend = PyBytes_GET_SIZE (zreplacement );
16601667 }
1668+ else if (ch == ':' && * pin == 'z' && pin ++ ) {
1669+ /* %:z -> +HH:MM */
1670+ if (colonzreplacement == NULL ) {
1671+ colonzreplacement = make_somezreplacement (object , ":" , tzinfoarg );
1672+ if (colonzreplacement == NULL )
1673+ goto Done ;
1674+ }
1675+ assert (colonzreplacement != NULL );
1676+ assert (PyBytes_Check (colonzreplacement ));
1677+ ptoappend = PyBytes_AS_STRING (colonzreplacement );
1678+ ntoappend = PyBytes_GET_SIZE (colonzreplacement );
1679+ }
16611680 else if (ch == 'Z' ) {
16621681 /* format tzname */
16631682 if (Zreplacement == NULL ) {
@@ -1686,7 +1705,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
16861705 ntoappend = PyBytes_GET_SIZE (freplacement );
16871706 }
16881707 else {
1689- /* percent followed by neither z nor Z */
1708+ /* percent followed by something else */
16901709 ptoappend = pin - 2 ;
16911710 ntoappend = 2 ;
16921711 }
@@ -1733,6 +1752,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
17331752 Done :
17341753 Py_XDECREF (freplacement );
17351754 Py_XDECREF (zreplacement );
1755+ Py_XDECREF (colonzreplacement );
17361756 Py_XDECREF (Zreplacement );
17371757 Py_XDECREF (newfmt );
17381758 return result ;
0 commit comments