1# Lint as: python2, python3 2# Copyright (c) 2014 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6# This module contains some commonly used time conversion function. 7 8from __future__ import absolute_import 9from __future__ import division 10from __future__ import print_function 11 12import datetime 13import six 14import time 15 16from autotest_lib.client.common_lib import decorators 17 18 19try: 20 import pytz 21except ImportError: 22 pytz = None 23 24 25try: 26 import tzlocal 27except ImportError: 28 tzlocal = None 29 30 31# This format is used to parse datetime value in MySQL database and should not 32# be modified. 33TIME_FMT = '%Y-%m-%d %H:%M:%S' 34TIME_FMT_MICRO = '%Y-%m-%d %H:%M:%S.%f' 35 36def time_string_to_datetime(time_string, handle_type_error=False): 37 """Convert a string of time to a datetime object. 38 39 The format of date string must match '%Y-%m-%d %H:%M:%S' or 40 '%Y-%m-%d %H:%M:%S.%f'. 41 42 @param time_string: String of date, e.g., 2014-12-05 15:32:45 43 @param handle_type_error: Set to True to prevent the method raise 44 TypeError if given time_string is corrupted. Default is False. 45 46 @return: A datetime object with time of the given date string. 47 48 """ 49 try: 50 try: 51 return datetime.datetime.strptime(time_string, TIME_FMT) 52 except ValueError: 53 return datetime.datetime.strptime(time_string, TIME_FMT_MICRO) 54 except TypeError: 55 if handle_type_error: 56 return None 57 else: 58 raise 59 60 61def date_string_to_epoch_time(date_string): 62 """Parse a date time string into seconds since the epoch. 63 64 @param date_string: A string, formatted according to `TIME_FMT`. 65 66 @return The number of seconds since the UNIX epoch, as a float. 67 68 """ 69 return time.mktime(time.strptime(date_string, TIME_FMT)) 70 71 72def epoch_time_to_date_string(epoch_time, fmt_string=TIME_FMT): 73 """Convert epoch time (float) to a human readable date string. 74 75 @param epoch_time The number of seconds since the UNIX epoch, as 76 a float. 77 @param fmt_string: A string describing the format of the datetime 78 string output. 79 80 @returns: string formatted in the following way: "yyyy-mm-dd hh:mm:ss" 81 """ 82 if epoch_time: 83 return datetime.datetime.fromtimestamp( 84 int(epoch_time)).strftime(fmt_string) 85 return None 86 87 88def to_epoch_time(value): 89 """Convert the given value to epoch time. 90 91 Convert the given value to epoch time if it is a datetime object or a string 92 can be converted to datetime object. 93 If the given value is a number, this function assume the value is a epoch 94 time value, and returns the value itself. 95 96 @param value: A datetime object or a number. 97 @returns: epoch time if value is datetime.datetime, 98 otherwise returns the value. 99 @raise ValueError: If value is not a datetime object or a number. 100 """ 101 if isinstance(value, six.string_types): 102 value = time_string_to_datetime(value) 103 if isinstance(value, datetime.datetime): 104 return time.mktime(value.timetuple()) + 0.000001 * value.microsecond 105 if not isinstance(value, int) and not isinstance(value, float): 106 raise ValueError('Value should be a datetime object, string or a ' 107 'number. Unexpected value: %s.' % value) 108 return value 109 110 111@decorators.test_module_available(pytz, raise_error=True) 112@decorators.test_module_available(tzlocal, raise_error=True) 113def to_utc_timestamp(datetime_val): 114 """Transforms a datetime object into a utc timestamp. 115 116 @param datetime_val: A datetime timestamp. 117 118 @returns A datetime as a UTC floating point timestamp in seconds since 119 epoch. 120 """ 121 if datetime_val is None: 122 return None 123 124 epoch = datetime.datetime(1970, 1, 1, tzinfo=pytz.utc) 125 local_datetime = datetime_val.replace(tzinfo=tzlocal.get_localzone()) 126 utc_datetime = local_datetime.astimezone(tz=pytz.utc) 127 return (utc_datetime - epoch).total_seconds() 128