ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
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
113
114
115
116
117
118
119
120
121
# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
 
# This module contains some commonly used time conversion function.
 
import datetime
import time
 
from autotest_lib.client.common_lib import decorators
 
 
try:
    import pytz
except ImportError:
    pytz = None
 
 
try:
    import tzlocal
except ImportError:
    tzlocal = None
 
 
# This format is used to parse datetime value in MySQL database and should not
# be modified.
TIME_FMT = '%Y-%m-%d %H:%M:%S'
TIME_FMT_MICRO = '%Y-%m-%d %H:%M:%S.%f'
 
def time_string_to_datetime(time_string, handle_type_error=False):
    """Convert a string of time to a datetime object.
 
    The format of date string must match '%Y-%m-%d %H:%M:%S' or
    '%Y-%m-%d %H:%M:%S.%f'.
 
    @param time_string: String of date, e.g., 2014-12-05 15:32:45
    @param handle_type_error: Set to True to prevent the method raise
            TypeError if given time_string is corrupted. Default is False.
 
    @return: A datetime object with time of the given date string.
 
    """
    try:
        try:
            return datetime.datetime.strptime(time_string, TIME_FMT)
        except ValueError:
            return datetime.datetime.strptime(time_string, TIME_FMT_MICRO)
    except TypeError:
        if handle_type_error:
            return None
        else:
            raise
 
 
def date_string_to_epoch_time(date_string):
    """Parse a date time string into seconds since the epoch.
 
    @param date_string: A string, formatted according to `TIME_FMT`.
 
    @return The number of seconds since the UNIX epoch, as a float.
 
    """
    return time.mktime(time.strptime(date_string, TIME_FMT))
 
 
def epoch_time_to_date_string(epoch_time, fmt_string=TIME_FMT):
    """Convert epoch time (float) to a human readable date string.
 
    @param epoch_time The number of seconds since the UNIX epoch, as
                      a float.
    @param fmt_string: A string describing the format of the datetime
        string output.
 
    @returns: string formatted in the following way: "yyyy-mm-dd hh:mm:ss"
    """
    if epoch_time:
        return datetime.datetime.fromtimestamp(
                int(epoch_time)).strftime(fmt_string)
    return None
 
 
def to_epoch_time(value):
    """Convert the given value to epoch time.
 
    Convert the given value to epoch time if it is a datetime object or a string
    can be converted to datetime object.
    If the given value is a number, this function assume the value is a epoch
    time value, and returns the value itself.
 
    @param value: A datetime object or a number.
    @returns: epoch time if value is datetime.datetime,
              otherwise returns the value.
    @raise ValueError: If value is not a datetime object or a number.
    """
    if isinstance(value, basestring):
        value = time_string_to_datetime(value)
    if isinstance(value, datetime.datetime):
        return time.mktime(value.timetuple()) + 0.000001 * value.microsecond
    if not isinstance(value, int) and not isinstance(value, float):
        raise ValueError('Value should be a datetime object, string or a '
                         'number. Unexpected value: %s.' % value)
    return value
 
 
@decorators.test_module_available(pytz, raise_error=True)
@decorators.test_module_available(tzlocal, raise_error=True)
def to_utc_timestamp(datetime_val):
    """Transforms a datetime object into a utc timestamp.
 
    @param datetime_val: A datetime timestamp.
 
    @returns A datetime as a UTC floating point timestamp in seconds since
             epoch.
    """
    if datetime_val is None:
        return None
 
    epoch = datetime.datetime(1970, 1, 1, tzinfo=pytz.utc)
    local_datetime = datetime_val.replace(tzinfo=tzlocal.get_localzone())
    utc_datetime = local_datetime.astimezone(tz=pytz.utc)
    return (utc_datetime - epoch).total_seconds()