xref: /aosp_15_r20/external/autotest/client/common_lib/time_utils.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li# Lint as: python2, python3
2*9c5db199SXin Li# Copyright (c) 2014 The Chromium Authors. All rights reserved.
3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be
4*9c5db199SXin Li# found in the LICENSE file.
5*9c5db199SXin Li
6*9c5db199SXin Li# This module contains some commonly used time conversion function.
7*9c5db199SXin Li
8*9c5db199SXin Lifrom __future__ import absolute_import
9*9c5db199SXin Lifrom __future__ import division
10*9c5db199SXin Lifrom __future__ import print_function
11*9c5db199SXin Li
12*9c5db199SXin Liimport datetime
13*9c5db199SXin Liimport six
14*9c5db199SXin Liimport time
15*9c5db199SXin Li
16*9c5db199SXin Li
17*9c5db199SXin Li# This format is used to parse datetime value in MySQL database and should not
18*9c5db199SXin Li# be modified.
19*9c5db199SXin LiTIME_FMT = '%Y-%m-%d %H:%M:%S'
20*9c5db199SXin LiTIME_FMT_MICRO = '%Y-%m-%d %H:%M:%S.%f'
21*9c5db199SXin Li
22*9c5db199SXin Lidef time_string_to_datetime(time_string, handle_type_error=False):
23*9c5db199SXin Li    """Convert a string of time to a datetime object.
24*9c5db199SXin Li
25*9c5db199SXin Li    The format of date string must match '%Y-%m-%d %H:%M:%S' or
26*9c5db199SXin Li    '%Y-%m-%d %H:%M:%S.%f'.
27*9c5db199SXin Li
28*9c5db199SXin Li    @param time_string: String of date, e.g., 2014-12-05 15:32:45
29*9c5db199SXin Li    @param handle_type_error: Set to True to prevent the method raise
30*9c5db199SXin Li            TypeError if given time_string is corrupted. Default is False.
31*9c5db199SXin Li
32*9c5db199SXin Li    @return: A datetime object with time of the given date string.
33*9c5db199SXin Li
34*9c5db199SXin Li    """
35*9c5db199SXin Li    try:
36*9c5db199SXin Li        try:
37*9c5db199SXin Li            return datetime.datetime.strptime(time_string, TIME_FMT)
38*9c5db199SXin Li        except ValueError:
39*9c5db199SXin Li            return datetime.datetime.strptime(time_string, TIME_FMT_MICRO)
40*9c5db199SXin Li    except TypeError:
41*9c5db199SXin Li        if handle_type_error:
42*9c5db199SXin Li            return None
43*9c5db199SXin Li        else:
44*9c5db199SXin Li            raise
45*9c5db199SXin Li
46*9c5db199SXin Li
47*9c5db199SXin Lidef date_string_to_epoch_time(date_string):
48*9c5db199SXin Li    """Parse a date time string into seconds since the epoch.
49*9c5db199SXin Li
50*9c5db199SXin Li    @param date_string: A string, formatted according to `TIME_FMT`.
51*9c5db199SXin Li
52*9c5db199SXin Li    @return The number of seconds since the UNIX epoch, as a float.
53*9c5db199SXin Li
54*9c5db199SXin Li    """
55*9c5db199SXin Li    return time.mktime(time.strptime(date_string, TIME_FMT))
56*9c5db199SXin Li
57*9c5db199SXin Li
58*9c5db199SXin Lidef epoch_time_to_date_string(epoch_time, fmt_string=TIME_FMT):
59*9c5db199SXin Li    """Convert epoch time (float) to a human readable date string.
60*9c5db199SXin Li
61*9c5db199SXin Li    @param epoch_time The number of seconds since the UNIX epoch, as
62*9c5db199SXin Li                      a float.
63*9c5db199SXin Li    @param fmt_string: A string describing the format of the datetime
64*9c5db199SXin Li        string output.
65*9c5db199SXin Li
66*9c5db199SXin Li    @returns: string formatted in the following way: "yyyy-mm-dd hh:mm:ss"
67*9c5db199SXin Li    """
68*9c5db199SXin Li    if epoch_time:
69*9c5db199SXin Li        return datetime.datetime.fromtimestamp(
70*9c5db199SXin Li                int(epoch_time)).strftime(fmt_string)
71*9c5db199SXin Li    return None
72*9c5db199SXin Li
73*9c5db199SXin Li
74*9c5db199SXin Lidef to_epoch_time(value):
75*9c5db199SXin Li    """Convert the given value to epoch time.
76*9c5db199SXin Li
77*9c5db199SXin Li    Convert the given value to epoch time if it is a datetime object or a string
78*9c5db199SXin Li    can be converted to datetime object.
79*9c5db199SXin Li    If the given value is a number, this function assume the value is a epoch
80*9c5db199SXin Li    time value, and returns the value itself.
81*9c5db199SXin Li
82*9c5db199SXin Li    @param value: A datetime object or a number.
83*9c5db199SXin Li    @returns: epoch time if value is datetime.datetime,
84*9c5db199SXin Li              otherwise returns the value.
85*9c5db199SXin Li    @raise ValueError: If value is not a datetime object or a number.
86*9c5db199SXin Li    """
87*9c5db199SXin Li    if isinstance(value, six.string_types):
88*9c5db199SXin Li        value = time_string_to_datetime(value)
89*9c5db199SXin Li    if isinstance(value, datetime.datetime):
90*9c5db199SXin Li        return time.mktime(value.timetuple()) + 0.000001 * value.microsecond
91*9c5db199SXin Li    if not isinstance(value, int) and not isinstance(value, float):
92*9c5db199SXin Li        raise ValueError('Value should be a datetime object, string or a '
93*9c5db199SXin Li                         'number. Unexpected value: %s.' % value)
94*9c5db199SXin Li    return value
95