How to use subtract_time_from_date method in Robotframework

Best Python code snippet using robotframework

Run Robotframework automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

DateTime.py

Source: DateTime.py Github

copy
1#  Copyright 2008-2015 Nokia Networks
2#  Copyright 2016-     Robot Framework Foundation
3#
4#  Licensed under the Apache License, Version 2.0 (the "License");
5#  you may not use this file except in compliance with the License.
6#  You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10#  Unless required by applicable law or agreed to in writing, software
11#  distributed under the License is distributed on an "AS IS" BASIS,
12#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13#  See the License for the specific language governing permissions and
14#  limitations under the License.
15
16"""A test library for handling date and time values.
17
18``DateTime`` is a Robot Framework standard library that supports creating and
19converting date and time values (e.g. `Get Current Date`, `Convert Time`),
20as well as doing simple calculations with them (e.g. `Subtract Time From Date`,
21`Add Time To Time`). It supports dates and times in various formats, and can
22also be used by other libraries programmatically.
23
24This library is new in Robot Framework 2.8.5.
25
26= Table of Contents =
27
28- `Terminology`
29- `Date formats`
30- `Time formats`
31- `Millisecond handling`
32- `Programmatic usage`
33- `Shortcuts`
34- `Keywords`
35
36= Terminology =
37
38In the context of this library, ``date`` and ``time`` generally have following
39meanings:
40
41- ``date``: An entity with both date and time components but without any
42   timezone information. For example, ``2014-06-11 10:07:42``.
43- ``time``: A time interval. For example, ``1 hour 20 minutes`` or ``01:20:00``.
44
45This terminology differs from what Python's standard
46[https://docs.python.org/2/library/datetime.html|datetime] module uses.
47Basically its
48[https://docs.python.org/2/library/datetime.html#datetime-objects|datetime] and
49[https://docs.python.org/2/library/datetime.html#timedelta-objects|timedelta]
50objects match ``date`` and ``time`` as defined by this library.
51
52= Date formats =
53
54Dates can given to and received from keywords in `timestamp`, `custom
55timestamp`, `Python datetime` and `epoch time` formats. These formats are
56discussed thoroughly in subsequent sections.
57
58Input format is determined automatically based on the given date except when
59using custom timestamps, in which case it needs to be given using
60``date_format`` argument. Default result format is timestamp, but it can
61be overridden using ``result_format`` argument.
62
63== Timestamp ==
64
65If a date is given as a string, it is always considered to be a timestamp.
66If no custom formatting is given using ``date_format`` argument, the timestamp
67is expected to be in [http://en.wikipedia.org/wiki/ISO_8601|ISO 8601] like
68format ``YYYY-MM-DD hh:mm:ss.mil``, where any non-digit character can be used
69as a separator or separators can be omitted altogether. Additionally,
70only the date part is mandatory, all possibly missing time components are
71considered to be zeros.
72
73Dates can also be returned in the same ``YYYY-MM-DD hh:mm:ss.mil`` format by
74using ``timestamp`` value with ``result_format`` argument. This is also the
75default format that keywords returning dates use. Milliseconds can be excluded
76using ``exclude_millis`` as explained in `Millisecond handling` section.
77
78Examples:
79| ${date1} =      | Convert Date | 2014-06-11 10:07:42.000 |
80| ${date2} =      | Convert Date | 20140611 100742         | result_format=timestamp |
81| Should Be Equal | ${date1}     | ${date2}                |
82| ${date} =       | Convert Date | 20140612 12:57          | exclude_millis=yes |
83| Should Be Equal | ${date}      | 2014-06-12 12:57:00     |
84
85== Custom timestamp ==
86
87It is possible to use custom timestamps in both input and output.
88The custom format is same as accepted by Python's
89[https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior|
90datatime.strptime] function. For example, the default timestamp discussed
91in the previous section would match ``%Y-%m-%d %H:%M:%S.%f``.
92
93When using a custom timestamp in input, it must be specified using
94``date_format`` argument. The actual input value must be a string that matches
95the specified format exactly. When using a custom timestamp in output, it must
96be given using ``result_format`` argument.
97
98Examples:
99| ${date} =       | Convert Date | 28.05.2014 12:05        | date_format=%d.%m.%Y %H:%M |
100| Should Be Equal | ${date}      | 2014-05-28 12:05:00.000 |
101| ${date} =       | Convert Date | ${date}                 | result_format=%d.%m.%Y |
102| Should Be Equal | ${date}      | 28.05.2014              |
103
104Notice that locale aware directives like ``%b``  do not work correctly with
105Jython on non-English locales: http://bugs.jython.org/issue2285
106
107== Python datetime ==
108
109Python's standard
110[https://docs.python.org/2/library/datetime.html#datetime.datetime|datetime]
111objects can be used both in input and output. In input they are recognized
112automatically, and in output it is possible to get them by giving ``datetime``
113value to ``result_format`` argument.
114
115One nice benefit with datetime objects is that they have different time
116components available as attributes that can be easily accessed using the
117extended variable syntax.
118
119Examples:
120| ${datetime} = | Convert Date | 2014-06-11 10:07:42.123 | datetime |
121| Should Be Equal As Integers | ${datetime.year}        | 2014   |
122| Should Be Equal As Integers | ${datetime.month}       | 6      |
123| Should Be Equal As Integers | ${datetime.day}         | 11     |
124| Should Be Equal As Integers | ${datetime.hour}        | 10     |
125| Should Be Equal As Integers | ${datetime.minute}      | 7      |
126| Should Be Equal As Integers | ${datetime.second}      | 42     |
127| Should Be Equal As Integers | ${datetime.microsecond} | 123000 |
128
129== Epoch time ==
130
131Epoch time is the time in seconds since the
132[http://en.wikipedia.org/wiki/Unix_time|UNIX epoch] i.e. 00:00:00.000 (UTC)
1331 January 1970. To give a date in epoch time, it must be given as a number
134(integer or float), not as a string. To return a date in epoch time,
135it is possible to use ``epoch`` value with ``result_format`` argument.
136Epoch time is returned as a floating point number.
137
138Notice that epoch time itself is independent on timezones and thus same
139around the world at a certain time. What local time a certain epoch time
140matches obviously then depends on the timezone. For example, examples below
141were tested in Finland but verifications would fail on other timezones.
142
143Examples:
144| ${date} =       | Convert Date | ${1000000000}           |
145| Should Be Equal | ${date}      | 2001-09-09 04:46:40.000 |
146| ${date} =       | Convert Date | 2014-06-12 13:27:59.279 | epoch |
147| Should Be Equal | ${date}      | ${1402568879.279}       |
148
149== Earliest supported date ==
150
151The earliest date that is supported depends on the date format and to some
152extend on the platform:
153
154- Timestamps support year 1900 and above.
155- Python datetime objects support year 1 and above.
156- Epoch time supports 1970 and above on Windows with Python and IronPython.
157- On other platforms epoch time supports 1900 and above or even earlier.
158
159Prior to Robot Framework 2.9.2, all formats had same limitation as epoch time
160has nowadays.
161
162= Time formats =
163
164Similarly as dates, times can be given to and received from keywords in
165various different formats. Supported formats are `number`, `time string`
166(verbose and compact), `timer string` and `Python timedelta`.
167
168Input format for time is always determined automatically based on the input.
169Result format is number by default, but it can be customised using
170``result_format`` argument.
171
172== Number ==
173
174Time given as a number is interpreted to be seconds. It can be given
175either as an integer or a float, or it can be a string that can be converted
176to a number.
177
178To return a time as a number, ``result_format`` argument must have value
179``number``, which is also the default. Returned number is always a float.
180
181Examples:
182| ${time} =       | Convert Time | 3.14    |
183| Should Be Equal | ${time}      | ${3.14} |
184| ${time} =       | Convert Time | ${time} | result_format=number |
185| Should Be Equal | ${time}      | ${3.14} |
186
187== Time string ==
188
189Time strings are strings in format like ``1 minute 42 seconds`` or ``1min 42s``.
190The basic idea of this format is having first a number and then a text
191specifying what time that number represents. Numbers can be either
192integers or floating point numbers, the whole format is case and space
193insensitive, and it is possible to add a minus prefix to specify negative
194times. The available time specifiers are:
195
196- ``days``, ``day``, ``d``
197- ``hours``, ``hour``, ``h``
198- ``minutes``, ``minute``, ``mins``, ``min``, ``m``
199- ``seconds``, ``second``, ``secs``, ``sec``, ``s``
200- ``milliseconds``, ``millisecond``, ``millis``, ``ms``
201
202When returning a time string, it is possible to select between ``verbose``
203and ``compact`` representations using ``result_format`` argument. The verbose
204format uses long specifiers ``day``, ``hour``, ``minute``, ``second`` and
205``millisecond``, and adds ``s`` at the end when needed. The compact format uses
206shorter specifiers ``d``, ``h``, ``min``, ``s`` and ``ms``, and even drops
207the space between the number and the specifier.
208
209Examples:
210| ${time} =       | Convert Time | 1 minute 42 seconds |
211| Should Be Equal | ${time}      | ${102}              |
212| ${time} =       | Convert Time | 4200                | verbose |
213| Should Be Equal | ${time}      | 1 hour 10 minutes   |
214| ${time} =       | Convert Time | - 1.5 hours         | compact |
215| Should Be Equal | ${time}      | - 1h 30min          |
216
217== Timer string ==
218
219Timer string is a string given in timer like format ``hh:mm:ss.mil``. In this
220format both hour and millisecond parts are optional, leading and trailing
221zeros can be left out when they are not meaningful, and negative times can
222be represented by adding a minus prefix.
223
224To return a time as timer string, ``result_format`` argument must be given
225value ``timer``. Timer strings are by default returned in full ``hh:mm:ss.mil``
226format, but milliseconds can be excluded using ``exclude_millis`` as explained
227in `Millisecond handling` section.
228
229Examples:
230| ${time} =       | Convert Time | 01:42        |
231| Should Be Equal | ${time}      | ${102}       |
232| ${time} =       | Convert Time | 01:10:00.123 |
233| Should Be Equal | ${time}      | ${4200.123}  |
234| ${time} =       | Convert Time | 102          | timer |
235| Should Be Equal | ${time}      | 00:01:42.000 |
236| ${time} =       | Convert Time | -101.567     | timer | exclude_millis=yes |
237| Should Be Equal | ${time}      | -00:01:42    |
238
239== Python timedelta ==
240
241Python's standard
242[https://docs.python.org/2/library/datetime.html#datetime.timedelta|timedelta]
243objects are also supported both in input and in output. In input they are
244recognized automatically, and in output it is possible to receive them by
245giving ``timedelta`` value to ``result_format`` argument.
246
247Examples:
248| ${timedelta} =  | Convert Time                 | 01:10:02.123 | timedelta |
249| Should Be Equal | ${timedelta.total_seconds()} | ${4202.123}  |
250
251= Millisecond handling =
252
253This library handles dates and times internally using the precision of the
254given input. With `timestamp`, `time string`, and `timer string` result
255formats seconds are, however, rounded to millisecond accuracy. Milliseconds
256may also be included even if there would be none.
257
258All keywords returning dates or times have an option to leave milliseconds out
259by giving a true value to ``exclude_millis`` argument. If the argument is given
260as a string, it is considered true unless it is empty or case-insensitively
261equal to ``false``, ``none`` or ``no``. Other argument types are tested using
262same [http://docs.python.org/2/library/stdtypes.html#truth-value-testing|rules
263as in Python]. Notice that prior to Robot Framework 2.9, all strings except
264the empty string were considered true, and that considering ``none`` false is
265new in Robot Framework 3.0.3.
266
267When milliseconds are excluded, seconds in returned dates and times are
268rounded to the nearest full second. With `timestamp` and `timer string`
269result formats, milliseconds will also be removed from the returned string
270altogether.
271
272Examples:
273| ${date} =       | Convert Date | 2014-06-11 10:07:42     |
274| Should Be Equal | ${date}      | 2014-06-11 10:07:42.000 |
275| ${date} =       | Convert Date | 2014-06-11 10:07:42.500 | exclude_millis=yes |
276| Should Be Equal | ${date}      | 2014-06-11 10:07:43     |
277| ${dt} =         | Convert Date | 2014-06-11 10:07:42.500 | datetime | exclude_millis=yes |
278| Should Be Equal | ${dt.second} | ${43}        |
279| Should Be Equal | ${dt.microsecond} | ${0}    |
280| ${time} =       | Convert Time | 102          | timer | exclude_millis=false |
281| Should Be Equal | ${time}      | 00:01:42.000 |       |
282| ${time} =       | Convert Time | 102.567      | timer | exclude_millis=true |
283| Should Be Equal | ${time}      | 00:01:43     |       |
284
285= Programmatic usage =
286
287In addition to be used as normal library, this library is intended to
288provide a stable API for other libraries to use if they want to support
289same date and time formats as this library. All the provided keywords
290are available as functions that can be easily imported:
291
292| from robot.libraries.DateTime import convert_time
293|
294| def example_keyword(timeout):
295|     seconds = convert_time(timeout)
296|     # ...
297
298Additionally helper classes ``Date`` and ``Time`` can be used directly:
299
300| from robot.libraries.DateTime import Date, Time
301|
302| def example_keyword(date, interval):
303|     date = Date(date).convert('datetime')
304|     interval = Time(interval).convert('number')
305|     # ...
306"""
307
308from datetime import datetime, timedelta
309import time
310import re
311
312from robot.version import get_version
313from robot.utils import (elapsed_time_to_string, is_falsy, is_number,
314                         is_string, roundup, secs_to_timestr, timestr_to_secs,
315                         type_name, IRONPYTHON)
316
317__version__ = get_version()
318__all__ = ['convert_time', 'convert_date', 'subtract_date_from_date',
319           'subtract_time_from_date', 'subtract_time_from_time',
320           'add_time_to_time', 'add_time_to_date', 'get_current_date']
321
322
323def get_current_date(time_zone='local', increment=0,
324                     result_format='timestamp', exclude_millis=False):
325    """Returns current local or UTC time with an optional increment.
326
327    Arguments:
328    - ``time_zone:``      Get the current time on this time zone. Currently only
329                          ``local`` (default) and ``UTC`` are supported.
330    - ``increment:``      Optional time increment to add to the returned date in
331                          one of the supported `time formats`. Can be negative.
332    - ``result_format:``  Format of the returned date (see `date formats`).
333    - ``exclude_millis:`` When set to any true value, rounds and drops
334                          milliseconds as explained in `millisecond handling`.
335
336    Examples:
337    | ${date} =       | Get Current Date |
338    | Should Be Equal | ${date}          | 2014-06-12 20:00:58.946 |
339    | ${date} =       | Get Current Date | UTC                     |
340    | Should Be Equal | ${date}          | 2014-06-12 17:00:58.946 |
341    | ${date} =       | Get Current Date | increment=02:30:00      |
342    | Should Be Equal | ${date}          | 2014-06-12 22:30:58.946 |
343    | ${date} =       | Get Current Date | UTC                     | - 5 hours |
344    | Should Be Equal | ${date}          | 2014-06-12 12:00:58.946 |
345    | ${date} =       | Get Current Date | result_format=datetime  |
346    | Should Be Equal | ${date.year}     | ${2014}                 |
347    | Should Be Equal | ${date.month}    | ${6}                    |
348    """
349    if time_zone.upper() == 'LOCAL':
350        dt = datetime.now()
351    elif time_zone.upper() == 'UTC':
352        dt = datetime.utcnow()
353    else:
354        raise ValueError("Unsupported timezone '%s'." % time_zone)
355    date = Date(dt) + Time(increment)
356    return date.convert(result_format, millis=is_falsy(exclude_millis))
357
358
359def convert_date(date, result_format='timestamp', exclude_millis=False,
360                 date_format=None):
361    """Converts between supported `date formats`.
362
363    Arguments:
364    - ``date:``           Date in one of the supported `date formats`.
365    - ``result_format:``  Format of the returned date.
366    - ``exclude_millis:`` When set to any true value, rounds and drops
367                          milliseconds as explained in `millisecond handling`.
368    - ``date_format:``    Specifies possible `custom timestamp` format.
369
370    Examples:
371    | ${date} =       | Convert Date | 20140528 12:05:03.111   |
372    | Should Be Equal | ${date}      | 2014-05-28 12:05:03.111 |
373    | ${date} =       | Convert Date | ${date}                 | epoch |
374    | Should Be Equal | ${date}      | ${1401267903.111}       |
375    | ${date} =       | Convert Date | 5.28.2014 12:05         | exclude_millis=yes | date_format=%m.%d.%Y %H:%M |
376    | Should Be Equal | ${date}      | 2014-05-28 12:05:00     |
377    """
378    return Date(date, date_format).convert(result_format,
379                                           millis=is_falsy(exclude_millis))
380
381
382def convert_time(time, result_format='number', exclude_millis=False):
383    """Converts between supported `time formats`.
384
385    Arguments:
386    - ``time:``           Time in one of the supported `time formats`.
387    - ``result_format:``  Format of the returned time.
388    - ``exclude_millis:`` When set to any true value, rounds and drops
389                          milliseconds as explained in `millisecond handling`.
390
391    Examples:
392    | ${time} =       | Convert Time  | 10 seconds        |
393    | Should Be Equal | ${time}       | ${10}             |
394    | ${time} =       | Convert Time  | 1:00:01           | verbose |
395    | Should Be Equal | ${time}       | 1 hour 1 second   |
396    | ${time} =       | Convert Time  | ${3661.5} | timer | exclude_milles=yes |
397    | Should Be Equal | ${time}       | 01:01:02          |
398    """
399    return Time(time).convert(result_format, millis=is_falsy(exclude_millis))
400
401
402def subtract_date_from_date(date1, date2, result_format='number',
403                            exclude_millis=False, date1_format=None,
404                            date2_format=None):
405    """Subtracts date from another date and returns time between.
406
407    Arguments:
408    - ``date1:``          Date to subtract another date from in one of the
409                          supported `date formats`.
410    - ``date2:``          Date that is subtracted in one of the supported
411                          `date formats`.
412    - ``result_format:``  Format of the returned time (see `time formats`).
413    - ``exclude_millis:`` When set to any true value, rounds and drops
414                          milliseconds as explained in `millisecond handling`.
415    - ``date1_format:``   Possible `custom timestamp` format of ``date1``.
416    - ``date2_format:``   Possible `custom timestamp` format of ``date2``.
417
418     Examples:
419    | ${time} =       | Subtract Date From Date | 2014-05-28 12:05:52     | 2014-05-28 12:05:10 |
420    | Should Be Equal | ${time}                 | ${42}                   |
421    | ${time} =       | Subtract Date From Date | 2014-05-28 12:05:52     | 2014-05-27 12:05:10 | verbose |
422    | Should Be Equal | ${time}                 | 1 day 42 seconds        |
423    """
424    time = Date(date1, date1_format) - Date(date2, date2_format)
425    return time.convert(result_format, millis=is_falsy(exclude_millis))
426
427
428def add_time_to_date(date, time, result_format='timestamp',
429                     exclude_millis=False, date_format=None):
430    """Adds time to date and returns the resulting date.
431
432    Arguments:
433    - ``date:``           Date to add time to in one of the supported
434                          `date formats`.
435    - ``time:``           Time that is added in one of the supported
436                          `time formats`.
437    - ``result_format:``  Format of the returned date.
438    - ``exclude_millis:`` When set to any true value, rounds and drops
439                          milliseconds as explained in `millisecond handling`.
440    - ``date_format:``    Possible `custom timestamp` format of ``date``.
441
442    Examples:
443    | ${date} =       | Add Time To Date | 2014-05-28 12:05:03.111 | 7 days       |
444    | Should Be Equal | ${date}          | 2014-06-04 12:05:03.111 |              |
445    | ${date} =       | Add Time To Date | 2014-05-28 12:05:03.111 | 01:02:03:004 |
446    | Should Be Equal | ${date}          | 2014-05-28 13:07:06.115 |
447    """
448    date = Date(date, date_format) + Time(time)
449    return date.convert(result_format, millis=is_falsy(exclude_millis))
450
451
452def subtract_time_from_date(date, time, result_format='timestamp',
453                            exclude_millis=False, date_format=None):
454    """Subtracts time from date and returns the resulting date.
455
456    Arguments:
457    - ``date:``           Date to subtract time from in one of the supported
458                          `date formats`.
459    - ``time:``           Time that is subtracted in one of the supported
460                         `time formats`.
461    - ``result_format:``  Format of the returned date.
462    - ``exclude_millis:`` When set to any true value, rounds and drops
463                          milliseconds as explained in `millisecond handling`.
464    - ``date_format:``    Possible `custom timestamp` format of ``date``.
465
466    Examples:
467    | ${date} =       | Subtract Time From Date | 2014-06-04 12:05:03.111 | 7 days |
468    | Should Be Equal | ${date}                 | 2014-05-28 12:05:03.111 |
469    | ${date} =       | Subtract Time From Date | 2014-05-28 13:07:06.115 | 01:02:03:004 |
470    | Should Be Equal | ${date}                 | 2014-05-28 12:05:03.111 |
471    """
472    date = Date(date, date_format) - Time(time)
473    return date.convert(result_format, millis=is_falsy(exclude_millis))
474
475
476def add_time_to_time(time1, time2, result_format='number',
477                     exclude_millis=False):
478    """Adds time to another time and returns the resulting time.
479
480    Arguments:
481    - ``time1:``          First time in one of the supported `time formats`.
482    - ``time2:``          Second time in one of the supported `time formats`.
483    - ``result_format:``  Format of the returned time.
484    - ``exclude_millis:`` When set to any true value, rounds and drops
485                          milliseconds as explained in `millisecond handling`.
486
487    Examples:
488    | ${time} =       | Add Time To Time | 1 minute          | 42       |
489    | Should Be Equal | ${time}          | ${102}            |
490    | ${time} =       | Add Time To Time | 3 hours 5 minutes | 01:02:03 | timer | exclude_millis=yes |
491    | Should Be Equal | ${time}          | 04:07:03          |
492    """
493    time = Time(time1) + Time(time2)
494    return time.convert(result_format, millis=is_falsy(exclude_millis))
495
496
497def subtract_time_from_time(time1, time2, result_format='number',
498                            exclude_millis=False):
499    """Subtracts time from another time and returns the resulting time.
500
501    Arguments:
502    - ``time1:``          Time to subtract another time from in one of
503                          the supported `time formats`.
504    - ``time2:``          Time to subtract in one of the supported `time formats`.
505    - ``result_format:``  Format of the returned time.
506    - ``exclude_millis:`` When set to any true value, rounds and drops
507                          milliseconds as explained in `millisecond handling`.
508
509    Examples:
510    | ${time} =       | Subtract Time From Time | 00:02:30 | 100      |
511    | Should Be Equal | ${time}                 | ${50}    |
512    | ${time} =       | Subtract Time From Time | ${time}  | 1 minute | compact |
513    | Should Be Equal | ${time}                 | - 10s    |
514    """
515    time = Time(time1) - Time(time2)
516    return time.convert(result_format, millis=is_falsy(exclude_millis))
517
518
519class Date(object):
520
521    def __init__(self, date, input_format=None):
522        self.datetime = self._convert_to_datetime(date, input_format)
523
524    @property
525    def seconds(self):
526        # Mainly for backwards compatibility with RF 2.9.1 and earlier.
527        return self._convert_to_epoch(self.datetime)
528
529    def _convert_to_datetime(self, date, input_format):
530        if isinstance(date, datetime):
531            return date
532        if is_number(date):
533            return self._seconds_to_datetime(date)
534        if is_string(date):
535            return self._string_to_datetime(date, input_format)
536        raise ValueError("Unsupported input '%s'." % date)
537
538    def _seconds_to_datetime(self, secs):
539        # Workaround microsecond rounding errors with IronPython:
540        # https://github.com/IronLanguages/main/issues/1170
541        # Also Jython had similar problems, but they seem to be fixed in 2.7.
542        dt = datetime.fromtimestamp(secs)
543        return dt.replace(microsecond=roundup(secs % 1 * 1e6))
544
545    def _string_to_datetime(self, ts, input_format):
546        if not input_format:
547            ts = self._normalize_timestamp(ts)
548            input_format = '%Y-%m-%d %H:%M:%S.%f'
549        if self._need_to_handle_f_directive(input_format):
550            return self._handle_un_supported_f_directive(ts, input_format)
551        return datetime.strptime(ts, input_format)
552
553    def _normalize_timestamp(self, date):
554        ts = ''.join(d for d in date if d.isdigit())
555        if len(ts) < 8:
556            raise ValueError("Invalid timestamp '%s'." % date)
557        ts = ts.ljust(20, '0')
558        return '%s-%s-%s %s:%s:%s.%s' % (ts[:4], ts[4:6], ts[6:8], ts[8:10],
559                                         ts[10:12], ts[12:14], ts[14:])
560
561    def _need_to_handle_f_directive(self, format):
562        # https://github.com/IronLanguages/main/issues/1169
563        return IRONPYTHON and '%f' in format
564
565    def _handle_un_supported_f_directive(self, ts, input_format):
566        input_format = self._remove_f_from_format(input_format)
567        match = re.search('\d+$', ts)
568        if not match:
569            raise ValueError("time data '%s' does not match format '%s%%f'."
570                             % (ts, input_format))
571        end_digits = match.group(0)
572        micro = int(end_digits.ljust(6, '0'))
573        dt = datetime.strptime(ts[:-len(end_digits)], input_format)
574        return dt.replace(microsecond=micro)
575
576    def _remove_f_from_format(self, format):
577        if not format.endswith('%f'):
578            raise ValueError('%f directive is supported only at the end of '
579                             'the format string on this Python interpreter.')
580        return format[:-2]
581
582    def convert(self, format, millis=True):
583        dt = self.datetime
584        if not millis:
585            secs = 1 if dt.microsecond >= 5e5 else 0
586            dt = dt.replace(microsecond=0) + timedelta(seconds=secs)
587        if '%' in format:
588            return self._convert_to_custom_timestamp(dt, format)
589        format = format.lower()
590        if format == 'timestamp':
591            return self._convert_to_timestamp(dt, millis)
592        if format == 'datetime':
593            return dt
594        if format == 'epoch':
595            return self._convert_to_epoch(dt)
596        raise ValueError("Unknown format '%s'." % format)
597
598    def _convert_to_custom_timestamp(self, dt, format):
599        if not self._need_to_handle_f_directive(format):
600            return dt.strftime(format)
601        format = self._remove_f_from_format(format)
602        return dt.strftime(format) + '%06d' % dt.microsecond
603
604    def _convert_to_timestamp(self, dt, millis=True):
605        if not millis:
606            return dt.strftime('%Y-%m-%d %H:%M:%S')
607        ms = roundup(dt.microsecond / 1000.0)
608        if ms == 1000:
609            dt += timedelta(seconds=1)
610            ms = 0
611        return dt.strftime('%Y-%m-%d %H:%M:%S') + '.%03d' % ms
612
613    def _convert_to_epoch(self, dt):
614        return time.mktime(dt.timetuple()) + dt.microsecond / 1e6
615
616    def __add__(self, other):
617        if isinstance(other, Time):
618            return Date(self.datetime + other.timedelta)
619        raise TypeError('Can only add Time to Date, got %s.' % type_name(other))
620
621    def __sub__(self, other):
622        if isinstance(other, Date):
623            return Time(self.datetime - other.datetime)
624        if isinstance(other, Time):
625            return Date(self.datetime - other.timedelta)
626        raise TypeError('Can only subtract Date or Time from Date, got %s.'
627                        % type_name(other))
628
629
630class Time(object):
631
632    def __init__(self, time):
633        self.seconds = float(self._convert_time_to_seconds(time))
634
635    def _convert_time_to_seconds(self, time):
636        if isinstance(time, timedelta):
637            # timedelta.total_seconds() is new in Python 2.7
638            return (time.days * 24 * 60 * 60 +
639                    time.seconds +
640                    time.microseconds / 1e6)
641        return timestr_to_secs(time, round_to=None)
642
643    @property
644    def timedelta(self):
645        return timedelta(seconds=self.seconds)
646
647    def convert(self, format, millis=True):
648        try:
649            result_converter = getattr(self, '_convert_to_%s' % format.lower())
650        except AttributeError:
651            raise ValueError("Unknown format '%s'." % format)
652        seconds = self.seconds if millis else float(roundup(self.seconds))
653        return result_converter(seconds, millis)
654
655    def _convert_to_number(self, seconds, millis=True):
656        return seconds
657
658    def _convert_to_verbose(self, seconds, millis=True):
659        return secs_to_timestr(seconds)
660
661    def _convert_to_compact(self, seconds, millis=True):
662        return secs_to_timestr(seconds, compact=True)
663
664    def _convert_to_timer(self, seconds, millis=True):
665        return elapsed_time_to_string(seconds * 1000, include_millis=millis)
666
667    def _convert_to_timedelta(self, seconds, millis=True):
668        return timedelta(seconds=seconds)
669
670    def __add__(self, other):
671        if isinstance(other, Time):
672            return Time(self.seconds + other.seconds)
673        raise TypeError('Can only add Time to Time, got %s.' % type_name(other))
674
675    def __sub__(self, other):
676        if isinstance(other, Time):
677            return Time(self.seconds - other.seconds)
678        raise TypeError('Can only subtract Time from Time, got %s.'
679                        % type_name(other))
680
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run Python Tests on LambdaTest Cloud Grid

Execute automation tests with Robotframework on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)