annotate sat/tools/common/date_utils.py @ 4028:883db2790b11

tools (common/date_utils): let use a timezone name as str in `date_fmt`
author Goffi <goffi@goffi.org>
date Thu, 30 Mar 2023 16:51:09 +0200
parents 92482cc80d0b
children 432f7e422a27
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2825
diff changeset
1 #!/usr/bin/env python3
3137
559a625a236b fixed shebangs
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
2
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
3
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # SAT: a jabber client
3479
be6d91572633 date update
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
6
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
11
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
16
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
19
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
20 """tools to help manipulating time and dates"""
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
21
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
22 from typing import Union
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
23 import calendar
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
24 import datetime
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
25 import re
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
26 import time
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
27
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
28 from babel import dates
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
29 from dateutil import parser, tz
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
30 from dateutil.parser import ParserError
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
31 from dateutil.relativedelta import relativedelta
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
32 from dateutil.utils import default_tzinfo
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
33
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
34 from sat.core import exceptions
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
35 from sat.core.constants import Const as C
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
36 from sat.core.i18n import _
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
37
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
38 RELATIVE_RE = re.compile(
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
39 r"\s*(?P<in>\bin\b)?"
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
40 r"(?P<date>[^+-].+[^\s+-])?\s*(?P<direction>[-+])?\s*"
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
41 r"\s*(?P<quantity>\d+)\s*"
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
42 r"(?P<unit>(second|sec|s|minute|min|month|mo|m|hour|hr|h|day|d|week|w|year|yr|y))s?"
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
43 r"(?P<ago>\s+ago)?\s*",
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
44 re.I
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
45 )
3599
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
46 TIME_SYMBOL_MAP = {
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
47 "s": "second",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
48 "sec": "second",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
49 "m": "minute",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
50 "min": "minute",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
51 "h": "hour",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
52 "hr": "hour",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
53 "d": "day",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
54 "w": "week",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
55 "mo": "month",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
56 "y": "year",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
57 "yr": "year",
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
58 }
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2825
diff changeset
59 YEAR_FIRST_RE = re.compile(r"\d{4}[^\d]+")
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
60 TZ_UTC = tz.tzutc()
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
61 TZ_LOCAL = tz.gettz()
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
62
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
63
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
64 def date_parse(value, default_tz=TZ_UTC):
2612
3e4e78de9cca tools (date_utils): moved date_parse to common.date_utils, because it can be used in frontends
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
65 """Parse a date and return corresponding unix timestamp
3e4e78de9cca tools (date_utils): moved date_parse to common.date_utils, because it can be used in frontends
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
66
2797
7968c8b7b5e1 tools (common): fixed dateutil.parser import
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
67 @param value(unicode): date to parse, in any format supported by parser
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
68 @param default_tz(datetime.tzinfo): default timezone
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
69 @return (int): timestamp
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
70 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2825
diff changeset
71 value = str(value).strip()
2825
1b6547fb80da tools(common/date_utils): fixed order on year first + set default date for date_parse
Goffi <goffi@goffi.org>
parents: 2797
diff changeset
72 dayfirst = False if YEAR_FIRST_RE.match(value) else True
1b6547fb80da tools(common/date_utils): fixed order on year first + set default date for date_parse
Goffi <goffi@goffi.org>
parents: 2797
diff changeset
73
3629
025ea418032f tools (common/date_utils): parse `now` alone (when used without relative delta)
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
74 try:
025ea418032f tools (common/date_utils): parse `now` alone (when used without relative delta)
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
75 dt = default_tzinfo(
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
76 parser.parse(value, dayfirst=dayfirst),
3629
025ea418032f tools (common/date_utils): parse `now` alone (when used without relative delta)
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
77 default_tz)
025ea418032f tools (common/date_utils): parse `now` alone (when used without relative delta)
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
78 except ParserError as e:
025ea418032f tools (common/date_utils): parse `now` alone (when used without relative delta)
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
79 if value == "now":
025ea418032f tools (common/date_utils): parse `now` alone (when used without relative delta)
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
80 dt = datetime.datetime.now(tz.tzutc())
025ea418032f tools (common/date_utils): parse `now` alone (when used without relative delta)
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
81 else:
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
82 try:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
83 # the date may already be a timestamp
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
84 return int(value)
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
85 except ValueError:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
86 raise e
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
87 return calendar.timegm(dt.utctimetuple())
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
88
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
89 def date_parse_ext(value, default_tz=TZ_UTC):
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
90 """Extended date parse which accept relative date
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
91
2797
7968c8b7b5e1 tools (common): fixed dateutil.parser import
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
92 @param value(unicode): date to parse, in any format supported by parser
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
93 and with the hability to specify X days/weeks/months/years in the past or future.
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
94 Relative date are specified either with something like `[main_date] +1 week`
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
95 or with something like `3 days ago`, and it is case insensitive. [main_date] is
2797
7968c8b7b5e1 tools (common): fixed dateutil.parser import
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
96 a date parsable by parser, or empty to specify current date/time.
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
97 "now" can also be used to specify current date/time.
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
98 @param default_tz(datetime.tzinfo): same as for date_parse
2612
3e4e78de9cca tools (date_utils): moved date_parse to common.date_utils, because it can be used in frontends
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
99 @return (int): timestamp
3e4e78de9cca tools (date_utils): moved date_parse to common.date_utils, because it can be used in frontends
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
100 """
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
101 m = RELATIVE_RE.match(value)
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
102 if m is None:
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
103 return date_parse(value, default_tz=default_tz)
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
104
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
105 if sum(1 for g in ("direction", "in", "ago") if m.group(g)) > 1:
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
106 raise ValueError(
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
107 _('You can use only one of direction (+ or -), "in" and "ago"'))
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
108
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2825
diff changeset
109 if m.group("direction") == '-' or m.group("ago"):
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
110 direction = -1
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
111 else:
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
112 direction = 1
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
113
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
114 date = m.group("date")
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
115 if date is not None:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
116 date = date.strip()
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2825
diff changeset
117 if not date or date == "now":
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
118 dt = datetime.datetime.now(tz.tzutc())
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
119 else:
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
120 try:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
121 dt = default_tzinfo(parser.parse(date, dayfirst=True), default_tz)
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
122 except ParserError as e:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
123 try:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
124 timestamp = int(date)
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
125 except ValueError:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
126 raise e
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
127 else:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
128 dt = datetime.datetime.fromtimestamp(timestamp, tz.tzutc())
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
129
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2825
diff changeset
130 quantity = int(m.group("quantity"))
3599
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
131 unit = m.group("unit").lower()
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
132 try:
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
133 unit = TIME_SYMBOL_MAP[unit]
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
134 except KeyError:
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
135 pass
ab1fe6b25631 tools (common/date_utils): accept more units (shortcuts) + fix timezone when date with relative delta is used
Goffi <goffi@goffi.org>
parents: 3518
diff changeset
136 delta_kw = {f"{unit}s": direction * quantity}
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
137 dt = dt + relativedelta(**delta_kw)
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
138 return calendar.timegm(dt.utctimetuple())
2612
3e4e78de9cca tools (date_utils): moved date_parse to common.date_utils, because it can be used in frontends
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
139
3e4e78de9cca tools (date_utils): moved date_parse to common.date_utils, because it can be used in frontends
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
140
4028
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
141 def date_fmt(
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
142 timestamp: Union[float, int, str],
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
143 fmt: str = "short",
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
144 date_only: bool = False,
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
145 auto_limit: int = 7,
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
146 auto_old_fmt: str = "short",
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
147 auto_new_fmt: str = "relative",
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
148 locale_str: str = C.DEFAULT_LOCALE,
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
149 tz_info: Union[datetime.tzinfo, str] = TZ_UTC
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
150 ) -> str:
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
151 """Format date according to locale
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
152
4028
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
153 @param timestamp: unix time
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
154 @param fmt: one of:
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
155 - short: e.g. u'31/12/17'
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
156 - medium: e.g. u'Apr 1, 2007'
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
157 - long: e.g. u'April 1, 2007'
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
158 - full: e.g. u'Sunday, April 1, 2007'
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
159 - relative: format in relative time
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
160 e.g.: 3 hours
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
161 note that this format is not precise
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
162 - iso: ISO 8601 format
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
163 e.g.: u'2007-04-01T19:53:23Z'
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
164 - auto: use auto_old_fmt if date is older than auto_limit
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
165 else use auto_new_fmt
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
166 - auto_day: shorcut to set auto format with change on day
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
167 old format will be short, and new format will be time only
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
168 or a free value which is passed to babel.dates.format_datetime
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
169 (see http://babel.pocoo.org/en/latest/dates.html?highlight=pattern#pattern-syntax)
4028
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
170 @param date_only: if True, only display date (not datetime)
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
171 @param auto_limit: limit in days before using auto_old_fmt
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
172 use 0 to have a limit at last midnight (day change)
4028
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
173 @param auto_old_fmt: format to use when date is older than limit
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
174 @param auto_new_fmt: format to use when date is equal to or more recent
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
175 than limit
4028
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
176 @param locale_str: locale to use (as understood by babel)
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
177 @param tz_info: time zone to use
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
178
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
179 """
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
180 timestamp = float(timestamp)
4028
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
181 if isinstance(tz_info, str):
883db2790b11 tools (common/date_utils): let use a timezone name as str in `date_fmt`
Goffi <goffi@goffi.org>
parents: 3905
diff changeset
182 tz_info = tz.gettz(tz_info)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
183 if fmt == "auto_day":
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
184 fmt, auto_limit, auto_old_fmt, auto_new_fmt = "auto", 0, "short", "HH:mm"
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
185 if fmt == "auto":
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
186 if auto_limit == 0:
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
187 now = datetime.datetime.now(tz_info)
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
188 # we want to use given tz_info, so we don't use date() or today()
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
189 today = datetime.datetime(year=now.year, month=now.month, day=now.day,
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
190 tzinfo=now.tzinfo)
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
191 today = calendar.timegm(today.utctimetuple())
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
192 if timestamp < today:
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
193 fmt = auto_old_fmt
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
194 else:
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
195 fmt = auto_new_fmt
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
196 else:
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
197 days_delta = (time.time() - timestamp) / 3600
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
198 if days_delta > (auto_limit or 7):
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
199 fmt = auto_old_fmt
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
200 else:
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
201 fmt = auto_new_fmt
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
202
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
203 if fmt == "relative":
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
204 delta = timestamp - time.time()
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
205 return dates.format_timedelta(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
206 delta, granularity="minute", add_direction=True, locale=locale_str
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
207 )
3518
b258dce27d6d tools (common/date_utils): fix `date_only` for `short`, `long` and `full` format
Goffi <goffi@goffi.org>
parents: 3479
diff changeset
208 elif fmt in ("short", "long", "full"):
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
209 if date_only:
3518
b258dce27d6d tools (common/date_utils): fix `date_only` for `short`, `long` and `full` format
Goffi <goffi@goffi.org>
parents: 3479
diff changeset
210 dt = datetime.datetime.fromtimestamp(timestamp, tz_info)
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
211 return dates.format_date(dt, format=fmt, locale=locale_str)
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
212 else:
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
213 return dates.format_datetime(timestamp, format=fmt, locale=locale_str,
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
214 tzinfo=tz_info)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
215 elif fmt == "iso":
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
216 if date_only:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2612
diff changeset
217 fmt = "yyyy-MM-dd"
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
218 else:
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
219 fmt = "yyyy-MM-ddTHH:mm:ss'Z'"
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
220 return dates.format_datetime(timestamp, format=fmt)
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents:
diff changeset
221 else:
2703
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
222 return dates.format_datetime(timestamp, format=fmt, locale=locale_str,
3ba53b1cd1e6 tools (common/date_utils): date_parse_ext + timezone handling:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
223 tzinfo=tz_info)
3905
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
224
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
225
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
226 def delta2human(start_ts: Union[float, int], end_ts: Union[float, int]) -> str:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
227 """Convert delta of 2 unix times to human readable text
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
228
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
229 @param start_ts: timestamp of starting time
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
230 @param end_ts: timestamp of ending time
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
231 """
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
232 if end_ts < start_ts:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
233 raise exceptions.InternalError(
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
234 "end timestamp must be bigger or equal to start timestamp !"
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
235 )
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
236 rd = relativedelta(
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
237 datetime.datetime.fromtimestamp(end_ts),
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
238 datetime.datetime.fromtimestamp(start_ts)
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
239 )
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
240 text_elems = []
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
241 for unit in ("years", "months", "days", "hours", "minutes"):
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
242 value = getattr(rd, unit)
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
243 if value == 1:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
244 # we remove final "s" when there is only 1
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
245 text_elems.append(f"1 {unit[:-1]}")
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
246 elif value > 1:
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
247 text_elems.append(f"{value} {unit}")
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
248
92482cc80d0b tools (common/date_utils) handle timestamp and `in` + `delta2human`:
Goffi <goffi@goffi.org>
parents: 3631
diff changeset
249 return ", ".join(text_elems)