You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.0 KiB
128 lines
4.0 KiB
# Lint as: python2, python3
|
|
# 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.
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
|
|
import datetime
|
|
import six
|
|
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, six.string_types):
|
|
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()
|