1
0
mirror of https://github.com/mikf/gallery-dl.git synced 2024-11-25 04:02:32 +01:00

[formatter] implement 'O' format specifier (#2736)

to apply a UTC offset to 'date' values and other datetime objects
This commit is contained in:
Mike Fährmann 2022-07-08 12:51:03 +02:00
parent e4f48cc810
commit 90ae48c40c
No known key found for this signature in database
GPG Key ID: 5680CA389D365A88
3 changed files with 56 additions and 1 deletions

View File

@ -173,10 +173,16 @@ Format specifiers can be used for advanced formatting by using the options provi
<td><code>{updated:D%b %d %Y %I:%M %p/}</code></td>
<td><code>2010-01-01 00:00:00</code></td>
</tr>
<tr>
<td><code>O&lt;offset&gt;/</code></td>
<td>Apply <code>&lt;offset&gt;</code> to a <code>datetime</code> object, either as <code>±HH:MM</code> or <code>local</code> for local UTC offset</td>
<td><code>{date:O-06:30/}</code></td>
<td><code>2009-12-31 17:30:00</code></td>
</tr>
</tbody>
</table>
All special format specifiers (`?`, `L`, `J`, `R`, `D`) can be chained and combined with one another, but must always come before any standard format specifiers:
All special format specifiers (`?`, `L`, `J`, `R`, `D`, `O`) can be chained and combined with one another, but must always come before any standard format specifiers:
For example `{foo:?//RF/B/Ro/e/> 10}` -> `   Bee Bar`
- `?//` - Tests if `foo` has a value

View File

@ -10,6 +10,7 @@
import os
import json
import time
import string
import _string
import datetime
@ -323,6 +324,27 @@ def _parse_datetime(format_spec, default):
return dt
def _parse_offset(format_spec, default):
offset, _, format_spec = format_spec.partition("/")
offset = offset[1:]
fmt = _build_format_func(format_spec, default)
if not offset or offset == "local":
is_dst = time.daylight and time.localtime().tm_isdst > 0
offset = -(time.altzone if is_dst else time.timezone)
else:
hours, _, minutes = offset.partition(":")
offset = 3600 * int(hours)
if minutes:
offset += 60 * (int(minutes) if offset > 0 else -int(minutes))
offset = datetime.timedelta(seconds=offset)
def off(obj):
return fmt(obj + offset)
return off
def _default_format(format_spec, default):
def wrap(obj):
return format(obj, format_spec)
@ -367,5 +389,6 @@ _FORMAT_SPECIFIERS = {
"D": _parse_datetime,
"L": _parse_maxlen,
"J": _parse_join,
"O": _parse_offset,
"R": _parse_replace,
}

View File

@ -9,6 +9,7 @@
import os
import sys
import time
import unittest
import datetime
import tempfile
@ -192,6 +193,31 @@ class TestFormatter(unittest.TestCase):
self._run_test("{ds:D%Y}", "2010-01-01T01:00:00+0100")
self._run_test("{l:D%Y}", "None")
def test_offset(self):
self._run_test("{dt:O 01:00}", "2010-01-01 01:00:00")
self._run_test("{dt:O+02:00}", "2010-01-01 02:00:00")
self._run_test("{dt:O-03:45}", "2009-12-31 20:15:00")
self._run_test("{dt:O12}", "2010-01-01 12:00:00")
self._run_test("{dt:O-24}", "2009-12-31 00:00:00")
self._run_test("{ds:D%Y-%m-%dT%H:%M:%S%z/O1}", "2010-01-01 01:00:00")
self._run_test("{t!d:O2}", "2010-01-01 02:00:00")
orig_daylight = time.daylight
orig_timezone = time.timezone
orig_altzone = time.altzone
try:
time.daylight = False
time.timezone = -3600
self._run_test("{dt:O}", "2010-01-01 01:00:00")
time.timezone = 7200
self._run_test("{dt:Olocal}", "2009-12-31 22:00:00")
finally:
time.daylight = orig_daylight
time.timezone = orig_timezone
time.altzone = orig_altzone
def test_chain_special(self):
# multiple replacements
self._run_test("{a:Rh/C/RE/e/RL/l/}", "Cello wOrld")