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