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:
parent
e4f48cc810
commit
90ae48c40c
@ -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<offset>/</code></td>
|
||||
<td>Apply <code><offset></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
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user