RobotFramework之DateTime

weixin_34124651發表於2017-05-18

背景

繼續學習RobotFramework框架,這次看的是DateTime庫。

DateTime庫是RobotFramework操作時間的一個庫,可以進行很多時間方面的操作。

DateTime is a Robot Framework standard library that supports creating and converting date and time values (e.g. Get Current Date, Convert Time), as well as doing simple calculations with them (e.g. Subtract Time From Date, Add Time To Time). It supports dates and times in various formats, and can also be used by other libraries programmatically.

Get Current Date

示例程式碼

*** Settings ***
Library     DateTime

*** Test Cases ***
test1
    ${tm}       get_current_date
    log     ${tm

執行結果

11:08:49.158    INFO    2017-05-01 11:08:49.157

原始碼

def get_current_date(time_zone='local', increment=0,
                     result_format='timestamp', exclude_millis=False):
    if time_zone.upper() == 'LOCAL':
        dt = datetime.now()
    elif time_zone.upper() == 'UTC':
        dt = datetime.utcnow()
    else:
        raise ValueError("Unsupported timezone '%s'." % time_zone)
    date = Date(dt) + Time(increment)
    return date.convert(result_format, millis=is_falsy(exclude_millis))

說明

這個方法可以不傳入引數,預設使用的是當地時間,如果第一個引數傳入utc不區分大小寫,則會使用utc時間。如果需要一個時間偏移量,則可以在第二個引數中傳入時間偏移,傳入的引數可以是一個數字或者str的數字,單位為秒,比如如下程式碼,執行的結果就會相差1分鐘

test1
    ${tmdl}       get_current_date    local       60
    ${tm}       get_current_date
    log     ${tm}
    log     ${tmdl}
    
Result

KEYWORD BuiltIn . Log ${tm}
Documentation:  
Logs the given message with the given level.
Start / End / Elapsed:  20170501 11:22:13.600 / 20170501 11:22:13.600 / 00:00:00.000
11:22:13.600    INFO    2017-05-01 11:22:13.600 
00:00:00.001KEYWORD BuiltIn . Log ${tmdl}
Documentation:  
Logs the given message with the given level.
Start / End / Elapsed:  20170501 11:22:13.600 / 20170501 11:22:13.601 / 00:00:00.001
11:22:13.601    INFO    2017-05-01 11:23:13.599

當然,也可以傳入一個timedelta,會通過如下程式碼解析成秒數進行處理。

class Time(object):

    def __init__(self, time):
        self.seconds = float(self._convert_time_to_seconds(time))

    def _convert_time_to_seconds(self, time):
        if isinstance(time, timedelta):
            # timedelta.total_seconds() is new in Python 2.7
            return (time.days * 24 * 60 * 60 +
                    time.seconds +
                    time.microseconds / 1e6)
        return timestr_to_secs(time, round_to=None)

第三個引數為格式化引數,從程式碼中可以看到,預設傳入的是timestamp,而這裡的解析原始碼如下

def convert(self, format, millis=True):
        dt = self.datetime
        if not millis:
            secs = 1 if dt.microsecond >= 5e5 else 0
            dt = dt.replace(microsecond=0) + timedelta(seconds=secs)
        if '%' in format:
            return self._convert_to_custom_timestamp(dt, format)
        format = format.lower()
        if format == 'timestamp':
            return self._convert_to_timestamp(dt, millis)
        if format == 'datetime':
            return dt
        if format == 'epoch':
            return self._convert_to_epoch(dt)
        raise ValueError("Unknown format '%s'." % format)

所以,可以傳入timestampdatetimeepoch或者是我們正常格式化時間的%Y%m%d

第四個引數傳入的是布林值,是否需要毫秒級的資料,預設是False,也就是有毫秒的,如果不需要的話,傳入${true}即可

Convert Date

示例程式碼

*** Settings ***
Library     DateTime

*** Test Cases ***
test1
    ${tm}       convert_date        20170501
    log     ${tm}

執行結果

11:58:27.558    INFO    2017-05-01 00:00:00.000

原始碼

def convert_date(date, result_format='timestamp', exclude_millis=False,
                 date_format=None):
    return Date(date, date_format).convert(result_format,
                                           millis=is_falsy(exclude_millis))
                                           
def convert(self, format, millis=True):
        dt = self.datetime
        if not millis:
            secs = 1 if dt.microsecond >= 5e5 else 0
            dt = dt.replace(microsecond=0) + timedelta(seconds=secs)
        if '%' in format:
            return self._convert_to_custom_timestamp(dt, format)
        format = format.lower()
        if format == 'timestamp':
            return self._convert_to_timestamp(dt, millis)
        if format == 'datetime':
            return dt
        if format == 'epoch':
            return self._convert_to_epoch(dt)
        raise ValueError("Unknown format '%s'." % format)

說明

該方法就是一個時間格式轉換的方法,在上一個方法Get Current Date中獲取的結果如果需要其他格式,就可以用這個方法進行轉換,引數傳入與上一個方法一樣。

Convert Time

示例程式碼

*** Settings ***
Library     DateTime

*** Test Cases ***
test1
    ${tm}       convert_time    10      timedelta
    log     ${tm}

執行結果

12:06:08.990    INFO    0:00:10

原始碼

def convert_time(time, result_format='number', exclude_millis=False):
    return Time(time).convert(result_format, millis=is_falsy(exclude_millis))
    
class Time(object):

    def __init__(self, time):
        self.seconds = float(self._convert_time_to_seconds(time))
    
    def convert(self, format, millis=True):
        try:
            result_converter = getattr(self, '_convert_to_%s' % format.lower())
        except AttributeError:
            raise ValueError("Unknown format '%s'." % format)
        seconds = self.seconds if millis else float(roundup(self.seconds))
        return result_converter(seconds, millis)

    def _convert_to_number(self, seconds, millis=True):
        return seconds

    def _convert_to_verbose(self, seconds, millis=True):
        return secs_to_timestr(seconds)

    def _convert_to_compact(self, seconds, millis=True):
        return secs_to_timestr(seconds, compact=True)

    def _convert_to_timer(self, seconds, millis=True):
        return elapsed_time_to_string(seconds * 1000, include_millis=millis)

    def _convert_to_timedelta(self, seconds, millis=True):
        return timedelta(seconds=seconds)

說明

第一個引數是必傳的,會在初始化Time類的時候轉換成秒。原始碼中的convert用了一個反射的方法,所以預設呼叫的是_convert_to_number會直接把傳入的第一個引數轉換成秒,然後返回。我寫的示例程式碼填的是timedelta,會轉換成時間格式。

Subtract Date From Date

示例程式碼

test
    ${time}     Subtract Date From Date         2014-05-28 12:05:52     2014-05-28 12:05:10
    log     ${time}

執行結果

    INFO    42.0

原始碼

def subtract_date_from_date(date1, date2, result_format='number',
                            exclude_millis=False, date1_format=None,
                            date2_format=None):
    time = Date(date1, date1_format) - Date(date2, date2_format)
    return time.convert(result_format, millis=is_falsy(exclude_millis))
    
class Date(object):

    def __init__(self, date, input_format=None):
        self.seconds = self._convert_date_to_seconds(date, input_format)
        
    def _convert_date_to_seconds(self, date, input_format):
        if is_string(date):
            return self._string_to_epoch(date, input_format)
        elif isinstance(date, datetime):
            return self._mktime_with_millis(date)
        elif is_number(date):
            return float(date)
        raise ValueError("Unsupported input '%s'." % date)

說明

方法是獲取兩個日期之間的差值,最終結果單位是秒,從示例程式碼中可以看得出來。Date類會將傳入的date1date2轉換成預設的格式,然後做一次減法。最後得到的日期結果,通過time.convert方法轉成秒

Add Time To Date

示例程式碼

test
    ${time}     add time to date    2014-05-28 12:05:03.111     7 days
    log     ${time}

執行結果

INFO    2014-06-04 12:05:03.111

示例程式碼

def add_time_to_date(date, time, result_format='timestamp',
                     exclude_millis=False, date_format=None):
    date = Date(date, date_format) + Time(time)
    return date.convert(result_format, millis=is_falsy(exclude_millis))

說明

傳入的引數7 days表示7天,這裡的時間型別用的是timedelta類,支援以下的單位days, seconds, minutes, hours,如果不傳,預設是seconds

Subtract Time From Date

示例程式碼

test
    ${time}     subtract time from date    2014-05-28 12:05:03.111     7 days
    log     ${time}

執行結果

INFO    2014-05-21 12:05:03.111

原始碼

def subtract_time_from_date(date, time, result_format='timestamp',
                            exclude_millis=False, date_format=None):
    date = Date(date, date_format) - Time(time)
    return date.convert(result_format, millis=is_falsy(exclude_millis))

Add Time To Time

示例程式碼

test
    ${time}     add time to time    1 days     7 days
    log     ${time}

執行結果

INFO    691200.0

原始碼

def add_time_to_time(time1, time2, result_format='number',
                     exclude_millis=False):
    time = Time(time1) + Time(time2)
    return time.convert(result_format, millis=is_falsy(exclude_millis))

Subtract Time From Time

示例程式碼

test
    ${time}     subtract time from time    1 days     7 days
    log     ${time}

執行結果

INFO    -518400.0

原始碼

def subtract_time_from_time(time1, time2, result_format='number',
                            exclude_millis=False):
    time = Time(time1) - Time(time2)
    return time.convert(result_format, millis=is_falsy(exclude_millis))

總結

DateTime庫主要的操作方式就只有DateTime這兩個類,只要搞懂這兩個類的處理邏輯,就能理解DateTime這個庫的操作方式

相關文章