| 199 | |
| 200 | # Correctly substitute for %z and %Z escapes in strftime formats. |
| 201 | def _wrap_strftime(object, format, timetuple): |
| 202 | # Don't call utcoffset() or tzname() unless actually needed. |
| 203 | freplace = None # the string to use for %f |
| 204 | zreplace = None # the string to use for %z |
| 205 | Zreplace = None # the string to use for %Z |
| 206 | |
| 207 | # Scan format for %z and %Z escapes, replacing as needed. |
| 208 | newformat = [] |
| 209 | push = newformat.append |
| 210 | i, n = 0, len(format) |
| 211 | while i < n: |
| 212 | ch = format[i] |
| 213 | i += 1 |
| 214 | if ch == '%': |
| 215 | if i < n: |
| 216 | ch = format[i] |
| 217 | i += 1 |
| 218 | if ch == 'f': |
| 219 | if freplace is None: |
| 220 | freplace = '%06d' % getattr(object, |
| 221 | 'microsecond', 0) |
| 222 | newformat.append(freplace) |
| 223 | elif ch == 'z': |
| 224 | if zreplace is None: |
| 225 | zreplace = "" |
| 226 | if hasattr(object, "utcoffset"): |
| 227 | offset = object.utcoffset() |
| 228 | if offset is not None: |
| 229 | sign = '+' |
| 230 | if offset.days < 0: |
| 231 | offset = -offset |
| 232 | sign = '-' |
| 233 | h, rest = divmod(offset, timedelta(hours=1)) |
| 234 | m, rest = divmod(rest, timedelta(minutes=1)) |
| 235 | s = rest.seconds |
| 236 | u = offset.microseconds |
| 237 | if u: |
| 238 | zreplace = '%c%02d%02d%02d.%06d' % (sign, h, m, s, u) |
| 239 | elif s: |
| 240 | zreplace = '%c%02d%02d%02d' % (sign, h, m, s) |
| 241 | else: |
| 242 | zreplace = '%c%02d%02d' % (sign, h, m) |
| 243 | assert '%' not in zreplace |
| 244 | newformat.append(zreplace) |
| 245 | elif ch == 'Z': |
| 246 | if Zreplace is None: |
| 247 | Zreplace = "" |
| 248 | if hasattr(object, "tzname"): |
| 249 | s = object.tzname() |
| 250 | if s is not None: |
| 251 | # strftime is going to have at this: escape % |
| 252 | Zreplace = s.replace('%', '%%') |
| 253 | newformat.append(Zreplace) |
| 254 | else: |
| 255 | push('%') |
| 256 | push(ch) |
| 257 | else: |
| 258 | push('%') |