<jupyter_start><jupyter_text>`time`    Table of Contents * [Dealing With Python Time Using Seconds](dealing_with_python_time_using_seconds)    * [The Epoch](the_epoch)* [Python Time in Seconds as a Floating Point Number](python_time_in_seconds_as_a_floating_point_number)* [Python Time in Seconds as a String Representing Local Time](python_time_in_seconds_as_a_string_representing_local_time)* [Understanding Time Zones](understanding_time_zones)    * [UTC and Time Zones](utc_and_time_zones)* [Dealing With Python Time Using Data Structures](dealing_with_python_time_using_data_structures)    * [Python Time as a Tuple](python_time_as_a_tuple)* [Python Time as an Object](python_time_as_an_object)* [Converting Python Time in Seconds to an Object](converting_python_time_in_seconds_to_an_object)    * [Coordinated Universal Time (UTC)](coordinated_universal_time_(utc))    * [Local Time](local_time)* [Converting a Local Time Object to Seconds](converting_a_local_time_object_to_seconds)* [Converting a Python Time Object to a String](converting_a_python_time_object_to_a_string)    * [`asctime()`](`asctime()`)    * [`strftime()`](`strftime()`)* [Converting a Python Time String to an Object](converting_a_python_time_string_to_an_object)* [Suspending Execution](suspending_execution)* [Measuring Performance](measuring_performance)* [ Conclusion](_conclusion)* [Further Reading](further_reading)---<jupyter_code>import time<jupyter_output><empty_output><jupyter_text>The Python `time` module provides many ways of representing time in code, such as objects, numbers, and strings. It also provides functionality other than representing time, like waiting during code execution and measuring the efficiency of your code.  Dealing With Python Time Using Seconds One of the ways you can manage the concept of Python time in your application is by using a floating point number that represents the number of seconds that have passed since the beginning of an era—that is, since a certain starting point.Let’s dive deeper into what that means, why it’s useful, and how you can use it to implement logic, based on Python time, in your application.  The EpochYou learned in the previous section that you can manage Python time with a floating point number representing elapsed time since the beginning of an era. Merriam-Webster defines an **era** as:> A fixed point in time from which a series of years is reckonedA system of chronological notation computed from a given date as basisThe important concept to grasp here is that, when dealing with Python time, you’re considering a period of time identified by a starting point. In computing, you call this starting point the epoch. **The epoch, then, is the starting point against which you can measure the passage of time.** For example, if you define the epoch to be midnight on **January 1, 1970 UTC**—the epoch as defined on Windows and most UNIX systems—then you can represent midnight on January 2, 1970 UTC as 86400 seconds since the epoch. This is because there are 60 seconds in a minute, 60 minutes in an hour, and 24 hours in a day. January 2, 1970 UTC is only one day after the epoch, so you can apply basic math to arrive at that result:<jupyter_code>60 * 60 * 24<jupyter_output><empty_output><jupyter_text>It is also important to note that you can still represent time before the epoch. The number of seconds would just be negative.For example, you would represent midnight on December 31, 1969 UTC (using an epoch of January 1, 1970) as **-86400** seconds. While January 1, 1970 UTC is a common epoch, it is not the only epoch used in computing. In fact, different operating systems, filesystems, and APIs sometimes use different epochs. As you saw before, UNIX systems define the epoch as January 1, 1970. The Win32 API, on the other hand, defines the epoch as **January 1, 1601**. You can use `time.gmtime()` (Greenwich Mean Time) to determine your system’s epoch:<jupyter_code>time.gmtime()<jupyter_output><empty_output><jupyter_text>You’ll learn about `gmtime()` and `struct_time` throughout the course of this article. For now, just know that you can use time to discover the epoch using this function. Now that you understand more about how to measure time in seconds using an epoch, let’s take a look at Python’s `time` module to see what functions it offers that help you do so.  Python Time in Seconds as a Floating Point Number First, `time.time()` returns the number of seconds that have passed since the epoch. The return value is a floating point number to account for fractional seconds:<jupyter_code>import time
time.time()<jupyter_output><empty_output><jupyter_text>The number you get on your machine may be very different because the reference point considered to be the epoch may be very different. > **Note:** Python 3.7 introduced `time_ns()`, which returns an integer value representing the same elapsed time since the epoch, but in nanoseconds rather than seconds.<jupyter_code>time.time_ns()<jupyter_output><empty_output><jupyter_text>Measuring time in seconds is useful for a number of reasons:- You can use a float to calculate the difference between two points in time.- A float is easily serializable, meaning that it can be stored for data transfer and come out intact on the other side.Sometimes, however, you may want to see the current time represented as a string. To do so, you can pass the number of seconds you get from `time()` into `time.ctime()`.<jupyter_code>time.ctime()
time.ctime(0)
time.ctime(100000)<jupyter_output><empty_output><jupyter_text>Python Time in Seconds as a String Representing Local Time As you saw before, you may want to convert the Python time, represented as the number of elapsed seconds since the epoch, to a string. You can do so using `ctime()` (convert time):<jupyter_code>t = time.time()
time.ctime(t)<jupyter_output><empty_output><jupyter_text>Here, you’ve recorded the current time in seconds into the variable `t`, then passed `t` as an argument to `ctime()`, which returns a string representation of that same time. > Technical Detail: The argument, representing seconds since the epoch, is optional according to the `ctime()` definition. If you don’t pass an argument, then ctime() uses the return value of `time()` by default. So, you could simplify the example above:<jupyter_code>time.ctime()<jupyter_output><empty_output><jupyter_text>The string representation of time, also known as a timestamp, returned by `ctime()` is formatted with the following structure:- Day of the week: Mon (Monday)- Month of the year: Feb (February)- Day of the month: 25- Hours, minutes, and seconds using the 24-hour clock notation: 19:11:59- Year: 2019 Notice that the day of week, day of month, and hour portions of the timestamp are most probabely different in your computer.These outputs are different because the timestamp returned by `ctime()` depends on your geographical location. > **Note:** While the concept of time zones is relative to your physical location, you can modify this in your computer’s settings without actually relocating. The representation of time dependent on your physical location is called **local time** and makes use of a concept called **time zones**. > **Note:** Since local time is related to your locale, timestamps often account for locale-specific details such as the order of the elements in the string and translations of the day and month abbreviations. `ctime()` ignores these details. Let’s dig a little deeper into the notion of time zones so that you can better understand Python time representations.  Understanding Time ZonesA time zone is a region of the world that conforms to a standardized time. Time zones are defined by their offset from Coordinated Universal Time (UTC) and, potentially, the inclusion of daylight savings time (which we’ll cover in more detail later in this article). > **Fun Fact**: If you’re a native English speaker, you might be wondering why the abbreviation for “Coordinated Universal Time” is UTC rather than the more obvious CUT. However, if you’re a native French speaker, you would call it “Temps Universel Coordonné,” which suggests a different abbreviation: TUC.> Ultimately, the International Telecommunication Union and the International Astronomical Union compromised on UTC as the official abbreviation so that, regardless of language, the abbreviation would be the same.  UTC and Time ZonesUTC is the time standard against which all the world’s timekeeping is synchronized (or coordinated). It is not, itself, a time zone but rather a transcendent standard that defines what time zones are. UTC time is precisely measured using astronomical time, referring to the Earth’s rotation, and atomic clocks. Time zones are then defined by their offset from UTC. For example, in North and South America, the Central Time Zone (CT) is behind UTC by five or six hours and, therefore, uses the notation UTC-5:00 or UTC-6:00. Sydney, Australia, on the other hand, belongs to the Australian Eastern Time Zone (AET), which is ten or eleven hours ahead of UTC (UTC+10:00 or UTC+11:00). This difference (UTC-6:00 to UTC+10:00) is the reason for the variance you observed in the two outputs from ctime() in the previous examples: Central Time (CT): 'Mon Feb 25 19:11:59 2019'Australian Eastern Time (AET): 'Tue Feb 26 12:11:59 2019'These times are exactly sixteen hours apart, which is consistent with the time zone offsets mentioned above. You may be wondering why CT can be either five or six hours behind UTC or why AET can be ten or eleven hours ahead. The reason for this is that some areas around the world, including parts of these time zones, observe daylight savings time.  Dealing With Python Time Using Data StructuresNow that you have a firm grasp on many fundamental concepts of time including epochs, time zones, and UTC, let’s take a look at more ways to represent time using the Python `time` module.  Python Time as a Tuple Instead of using a number to represent Python time, you can use another primitive data structure: a `tuple`. The `tuple` allows you to manage time a little more easily by abstracting some of the data and making it more readable. When you represent time as a tuple, each element in your tuple corresponds to a specific element of time:- Year- Month as an integer, ranging between 1 (January) and 12 (December)- Day of the month- Hour as an integer, ranging between 0 (12 A.M.) and 23 (11 P.M.)- Minute- Second- Day of the week as an integer, ranging between 0 (Monday) and 6 (Sunday)- Day of the year- Daylight savings time as an integer with the following values:    - 1 is daylight savings time.    - 0 is standard time.    - -1 is unknown. Using the methods you’ve already learned, you can represent the same Python time in two different ways:<jupyter_code>time.time()
time.ctime(t)
time_tuple = (2021, 5, 16, 19, 16, 45, 6, 136, 0)<jupyter_output><empty_output><jupyter_text>In this case, both `t` and `time_tuple` represent the same time, but the tuple provides a more readable interface for working with time components. > **Note:** `tuple` doesn’t have a way to represent fractional seconds. While the tuple provides a more manageable interface for working with Python time, there is an even better object: `struct_time`.  Python Time as an ObjectThe problem with the tuple construct is that it still looks like a bunch of numbers, even though it’s better organized than a single, seconds-based number. `struct_time` provides a solution to this by utilizing `NamedTuple`, from Python’s collections module, to associate the tuple’s sequence of numbers with useful identifiers:<jupyter_code>time_tuple = (2019, 2, 26, 7, 6, 55, 1, 57, 0)
time_obj = time.struct_time(time_tuple)
time_obj<jupyter_output><empty_output><jupyter_text>> **Technical Detail**: If you’re coming from another language, the terms struct and object might be in opposition to one another.>> In Python, there is no data type called `struct`. Instead, everything is an object.>> However, the name `struct_time` is derived from the C-based time library where the data type is actually a `struct`.>> In fact, Python’s time module, which is implemented in `C`, uses this `struct` directly by including the header file `times.h`.<jupyter_code>time_obj.tm_yday
time_obj.tm_mday<jupyter_output><empty_output><jupyter_text>Beyond the readability and usability of struct_time, **it is also important to know because it is the return type of many of the functions in the Python time module**.  Converting Python Time in Seconds to an ObjectNow that you’ve seen the three primary ways of working with Python time, you’ll learn how to convert between the different time data types.Converting between time data types is dependent on whether the time is in UTC or local time.  Coordinated Universal Time (UTC)The epoch uses UTC for its definition rather than a time zone. Therefore, the seconds elapsed since the epoch is not variable depending on your geographical location.However, the same cannot be said of `struct_time`. The object representation of Python time may or may not take your time zone into account. There are two ways to convert a float representing seconds to a `struct_time`:- UTC- Local time To convert a Python time float to a UTC-based `struct_time`, the Python time module provides a function called `gmtime()`. You’ve seen `gmtime()` used once before in this article:<jupyter_code>time.gmtime(0)<jupyter_output><empty_output><jupyter_text>You used this call to discover your system’s epoch. Now, you have a better foundation for understanding what’s actually happening here.`gmtime()` converts the number of elapsed seconds since the epoch to a `struct_time` in **UTC**. In this case, you’ve passed `0` as the number of seconds, meaning you’re trying to find the epoch, itself, in UTC. > **Note:** Notice the attribute tm_isdst is set to 0. This attribute represents whether the time zone is using daylight savings time. UTC never subscribes to DST, so that flag will always be 0 when using gmtime(). As you saw before, `struct_time` cannot represent fractional seconds, so `gmtime()` ignores the fractional seconds in the argument:<jupyter_code>time.gmtime(1.99)<jupyter_output><empty_output><jupyter_text>Notice that even though the number of seconds you passed was very close to 2, the .99 fractional seconds were simply ignored, as shown by `tm_sec=1`. The secs parameter for `gmtime()` is optional, meaning you can call `gmtime()` with no arguments. Doing so will provide the current time in UTC:<jupyter_code>time.gmtime()<jupyter_output><empty_output><jupyter_text>Interestingly, there is no inverse for this function within time. Instead, you’ll have to look in Python’s calendar module for a function named `timegm():<jupyter_code>import calendar

now = time.gmtime()
now
calendar.timegm(now)<jupyter_output><empty_output><jupyter_text>`timegm()` takes a `tuple` (or `struct_time`, since it is a subclass of `tuple`) and returns the corresponding number of seconds since the epoch. > **Historical Context**: If you’re interested in why `timegm()` is not in time, you can view the discussion in Python Issue 6280.>> In short, it was originally added to calendar because time closely follows C’s time library (defined in `time.h`), which contains no matching function. The above-mentioned issue proposed the idea of moving or copying `timegm()` into time.>> However, with advances to the `datetime` library, inconsistencies in the patched implementation of `time.timegm()`, and a question of how to then handle `calendar.timegm()`, the maintainers declined the patch, encouraging the use of `datetime` instead. Working with UTC is valuable in programming because it’s a standard. You don’t have to worry about DST, time zone, or locale information.That said, there are plenty of cases when you’d want to use local time. Next, you’ll see how to convert from seconds to local time so that you can do just that.  Local Time In your application, you may need to work with local time rather than UTC. Python’s time module provides a function for getting local time from the number of seconds elapsed since the epoch called `localtime()`. The signature of `localtime()` is similar to `gmtime()` in that it takes an optional secs argument, which it uses to build a `struct_time` using your local time zone:<jupyter_code>time.time()
time.localtime(time.time())<jupyter_output><empty_output><jupyter_text>Notice that `tm_isdst=0`. Since DST matters with local time, `tm_isdst` will change between 0 and 1 depending on whether or not DST is applicable for the given time. If `tm_isdst=1`, DST is applicable for the current time. Since Python 3.3, `struct_time` has also included two attributes that are useful in determining the time zone of the struct_time:- `tm_zone`- `tm_gmtoff` At first, these attributes were platform dependent, but they have been available on all platforms since Python 3.6. First, `tm_zone` stores the local time zone:<jupyter_code>time.localtime().tm_zone<jupyter_output><empty_output><jupyter_text>Here, you can see that `localtime()` returns a `struct_time` with the time zone. As you saw before, you can also tell the time zone based on two pieces of information, the UTC offset and DST (if applicable):<jupyter_code>current_local = time.localtime()
current_local.tm_gmtoff
current_local.tm_isdst<jupyter_output><empty_output><jupyter_text>In this case, you can see that current_local is `14400` seconds behind GMT, which stands for **Greenwich Mean Time**. GMT is the time zone with no UTC offset: UTC ± 00:00. 14400 seconds divided by seconds per hour (3,600) means that `current_local` time is GMT-04:00 (or UTC-04:00). Like `gmtime()`, you can ignore the secs argument when calling `localtime()`, and it will return the current local time in a `struct_time`:<jupyter_code>time.localtime()<jupyter_output><empty_output><jupyter_text>Unlike `gmtime()`, the inverse function of `localtime()` does exist in the Python `time` module. Let’s take a look at how that works.  Converting a Local Time Object to Seconds You’ve already seen how to convert a UTC time object to seconds using `calendar.timegm()`. To convert local time to seconds, you’ll use `mktime()`. `mktime()` requires you to pass a parameter called t that takes the form of either a normal 9-tuple or a `struct_time` object representing local time:<jupyter_code>time_tuple = (2019, 3, 10, 8, 50, 6, 6, 69, 1)
time.mktime(time_tuple)
time_struct = time.struct_time(time_tuple)
time.mktime(time_struct)<jupyter_output><empty_output><jupyter_text>It’s important to keep in mind that `t` must be a tuple **representing local time, not UTC**: ```python>>>  1>>> current_utc = time.gmtime()>>> current_utctime.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=14, tm_min=51, tm_sec=19, tm_wday=4, tm_yday=60, tm_isdst=0)>>>  2>>> current_utc_secs = time.mktime(current_utc)>>> current_utc_secs1551473479.0>>>  3>>> time.gmtime(current_utc_secs)time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=20, tm_min=51, tm_sec=19, tm_wday=4, tm_yday=60, tm_isdst=0)``` > Note: For this example, assume that the local time is **March 1, 2019 08:51:19 CST**. This example shows why it’s important to use `mktime()` with local time, rather than UTC: - `gmtime()` with no argument returns a `struct_time` using UTC. `current_utc` shows March 1, 2019 14:51:19 UTC. This is accurate because CST is UTC-06:00, so UTC should be 6 hours ahead of local time.- `mktime()` tries to return the number of seconds, expecting local time, but you passed current_utc instead. So, instead of understanding that `current_utc` is UTC time, it assumes you meant March 1, 2019 14:51:19 CST.- `gmtime()` is then used to convert those seconds back into UTC, which results in an inconsistency. The time is now March 1, 2019 20:51:19 UTC. The reason for this discrepancy is the fact that `mktime()` expected local time. So, the conversion back to UTC adds another 6 hours to local time. > **Note:** Working with time zones is notoriously difficult, so it’s important to set yourself up for success by understanding the differences between UTC and local time and the Python time functions that deal with each.  Converting a Python Time Object to a String While working with tuples is fun and all, sometimes it’s best to work with strings.String representations of time, also known as **timestamps**, help make times more readable and can be especially useful for building intuitive user interfaces.There are two Python time functions that you use for converting a `time.struct_time` object to a string:- `asctime()`- `strftime()` You’ll begin by learning about `asctime()`.  `asctime()`You use `asctime()` for converting a time tuple or `struct_time` to a timestamp:<jupyter_code>time.asctime(time.gmtime())
time.asctime(time.localtime())<jupyter_output><empty_output><jupyter_text>Both `gmtime()` and `localtime()` return `struct_time` instances, for UTC and local time respectively. You can use `asctime()` to convert either `struct_time` to a timestamp. `asctime(`) works similarly to `ctime()`, which you learned about earlier in this article, except instead of passing a floating point number, you pass a tuple. Even the timestamp format is the same between the two functions. As with ‍‍`ctime()`, the parameter for `asctime()` is optional. If you do not pass a time object to `asctime()`, then it will use the current local time:<jupyter_code>time.asctime()<jupyter_output><empty_output><jupyter_text>As with `ctime()`, it also ignores locale information. One of the biggest drawbacks of `asctime()` is its format inflexibility. `strftime()` solves this problem by allowing you to format your timestamps.  `strftime()` You may find yourself in a position where the string format from `ctime()` and `asctime()` isn’t satisfactory for your application. Instead, you may want to format your strings in a way that’s more meaningful to your users. One example of this is if you would like to display your time in a string that takes locale information into account. To format strings, given a `struct_time` or Python time tuple, you use `strftime()`, which stands for string **format** time. `strftime()` takes two arguments:- format specifies the order and form of the time elements in your string.- `t` is an optional time tuple. To format a string, you use directives. Directives are character sequences that begin with a `%` that specify a particular time element, such as:- `%d`: Day of the month- `%m`: Month of the year- `%Y`: Year For example, you can output the date in your local time using the ISO 8601 standard like this:<jupyter_code>time.strftime('%Y-%m-%d', time.localtime())<jupyter_output><empty_output><jupyter_text>> **Further Reading:** While representing dates using Python time is completely valid and acceptable, you should also consider using Python’s datetime module, which provides shortcuts and a more robust framework for working with dates and times together.> > For example, you can simplify outputting a date in the ISO 8601 format using datetime:> > ```python>>> from datetime import date>>> date(year=2019, month=3, day=1).isoformat()'2019-03-01'``` If the time tuple is not passed to the parameter `t`, then `strftime()` will use the result of `localtime()` by default.<jupyter_code>time.strftime('The current local datetime is: %c')<jupyter_output><empty_output><jupyter_text>> **Note:** `%c` is the directive for locale-appropriate date and time. Here, you’ve used the default time instead of passing your own as an argument. Also, notice that the `format` argument can consist of text other than formatting directives. The Python time module also includes the inverse operation of converting a timestamp back into a `struct_time` object.  Converting a Python Time String to an Object When you’re working with date and time related strings, it can be very valuable to convert the timestamp to a time object.To convert a time string to a struct_time, you use `strptime()`, which stands for **"string parse time"**:<jupyter_code>time.strptime('2019-03-01', '%Y-%m-%d')
time.strptime('2019-03-01', '%Y   -%m-%d')<jupyter_output><empty_output><jupyter_text>The first argument to `strptime()` must be the timestamp you wish to convert. The second argument is the format that the timestamp is in.The format parameter is optional and defaults to `'%a %b %d %H:%M:%S %Y'`. Therefore, if you have a timestamp in that format, you don’t need to pass it as an argument:<jupyter_code>time.strptime('Fri Mar 01 23:38:40 2019')<jupyter_output><empty_output><jupyter_text>Since a `struct_time` has 9 key date and time components, `strptime()` must provide reasonable defaults for values for those components it can’t parse from string.In the previous examples, `tm_isdst=-1`. This means that `strptime()` can’t determine by the timestamp whether it represents daylight savings time or not.Now you know how to work with Python times and dates using the `time` module in a variety of ways. However, there are other uses for time outside of simply creating time objects, getting Python time strings, and using seconds elapsed since the epoch.  Suspending ExecutionOne really useful Python time function is `sleep()`, which suspends the thread’s execution for a specified amount of time. For example, you can suspend your program’s execution for 1 second like this:<jupyter_code>for _ in range(3):
    print(_)
    time.sleep(1)<jupyter_output>0
1
2<jupyter_text>`sleep()` is useful for testing or making your program wait for any reason, but you must be careful not to halt your production code unless you have good reason to do so.Before Python 3.5, a signal sent to your process could interrupt `sleep()`. However, in 3.5 and later, `sleep()` will always suspend execution for at least the amount of specified time, even if the process receives a signal.`sleep()` is just one Python time function that can help you test your programs and make them more robust.  Measuring PerformanceYou can use `time` to measure the performance of your program.The way you do this is to use `perf_counter()` which, as the name suggests, provides a performance counter with a high resolution to measure short distances of time.To use `perf_counter()`, you place a counter before your code begins execution as well as after your code’s execution completes:<jupyter_code>def longrunning_function():
    for i in range(1, 11):
        time.sleep(i / i ** 2)

start = time.perf_counter()
longrunning_function()
end = time.perf_counter()
execution_time = (end - start)
print(f"Program took {execution_time} Second(s) to finish")<jupyter_output>Program took 2.9348958999999013 Second(s) to finish
{'fraction_non_alphanumeric': 0.07360329958755156, 'fraction_numerical': 0.015935508061492312, 'mean_word_length': 5.37299880525687, 'pattern_counts': {'":': 0, '<': 111, '<?xml version=': 0, '>': 170, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '28', 'dir': 'jupyter-structured-clean-dedup', 'id': '630422', 'license': 'MIT', 'n_tokens_mistral': 7512, 'n_tokens_neox': 6963, 'n_words': 3763, 'path': '01. Python/05. Modules/04.2 time.ipynb', 'repo_name': 'rostamimahdi1997/CS-Tutorial', 'size': '26670'}