File: timedelta.py

package info (click to toggle)
tryton-client 7.0.27-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,476 kB
  • sloc: python: 27,180; sh: 37; makefile: 18
file content (112 lines) | stat: -rw-r--r-- 3,180 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

import datetime
import gettext
import locale
from collections import OrderedDict

__all__ = ['format', 'parse']

_ = gettext.gettext

DEFAULT_CONVERTER = {
    's': 1,
    }
DEFAULT_CONVERTER['m'] = DEFAULT_CONVERTER['s'] * 60
DEFAULT_CONVERTER['h'] = DEFAULT_CONVERTER['m'] * 60
DEFAULT_CONVERTER['d'] = DEFAULT_CONVERTER['h'] * 24
DEFAULT_CONVERTER['w'] = DEFAULT_CONVERTER['d'] * 7
DEFAULT_CONVERTER['M'] = DEFAULT_CONVERTER['d'] * 30
DEFAULT_CONVERTER['Y'] = DEFAULT_CONVERTER['d'] * 365


def _get_separators():
    return OrderedDict([
            ('Y', _('Y')),
            ('M', _('M')),
            ('w', _('w')),
            ('d', _('d')),
            ('h', _('h')),
            ('m', _('m')),
            ('s', _('s')),
            ])


def format(value, converter=None):
    'Convert timedelta to text'
    if value is None:
        return ''
    if not converter:
        converter = DEFAULT_CONVERTER

    text = []
    value = value.total_seconds()
    sign = ''
    if value < 0:
        sign = '-'
    value = abs(value)
    converter = [(k, converter.get(k)) for k in _get_separators()]
    values = []
    for k, v in converter:
        if v:
            part = value // v
            value -= part * v
            values.append(part)
        else:
            values.append(0)

    for (k, _), v in zip(converter[:-3], values):
        if v:
            text.append(
                locale.format_string('%d', v, True) + _get_separators()[k])
    if any(values[-3:]) or not text:
        time = '%02d:%02d' % tuple(values[-3:-1])
        if values[-1] or value:
            time += ':%02d' % values[-1]
        text.append(time)
    text = sign + ' '.join(text)
    if value:
        if not any(values[-3:]):
            # Add space if no time
            text += ' '
        text += locale.format_string('%.6f', value)[1:]
    return text


def parse(text, converter=None):
    if not text:
        return
    if not converter:
        converter = DEFAULT_CONVERTER

    for separator in list(_get_separators().values()):
        text = text.replace(separator, separator + ' ')

    seconds = 0
    for part in text.split():
        if ':' in part:
            for t, v in zip(part.split(':'),
                    [converter['h'], converter['m'], converter['s']]):
                try:
                    seconds += abs(locale.atof(t)) * v
                except ValueError:
                    pass
        else:
            for key, separator in list(_get_separators().items()):
                if part.endswith(separator):
                    part = part[:-len(separator)]
                    try:
                        seconds += abs(locale.atof(part)) * converter[key]
                    except ValueError:
                        pass
                    break
            else:
                try:
                    seconds += abs(locale.atof(part))
                except ValueError:
                    pass

    if '-' in text:
        seconds *= -1
    return datetime.timedelta(seconds=seconds)