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