We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[clock] It is more intuitive to round clock emoji to the nearest 15 or 45 minutes
The emoji clock is being used in many apps these days, and I noticed that py3status implementation is not consistent with the rest and is less intuitive to me.

Currently the clock emoji is not being updated until the hour exactly reaches the next step, so for example:
- 14:59 🕝

Instead, it is more intuitive to choose icon for the time rounded to the nearest 15 or 45 minutes, that is:

- 14:01 🕑
- 14:14 🕑
- 14:15 🕝
- 14:44 🕝
- 14:45 🕒
- 14:59 🕒

/cc @tobes as you created this module.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `py3status/modules/clock.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """
3 Display date and time.
4 
5 This module allows one or more datetimes to be displayed.
6 All datetimes share the same format_time but can set their own timezones.
7 Timezones are defined in the `format` using the TZ name in squiggly brackets eg
8 `{GMT}`, `{Portugal}`, `{Europe/Paris}`, `{America/Argentina/Buenos_Aires}`.
9 
10 ISO-3166 two letter country codes eg `{de}` can also be used but if more than
11 one timezone exists for the country eg `{us}` the first one will be selected.
12 
13 `{Local}` can be used for the local settings of your computer.
14 
15 Note: Timezones are case sensitive
16 
17 A full list of timezones can be found at
18 https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
19 
20 Configuration parameters:
21     block_hours: length of time period for all blocks in hours (default 12)
22     blocks: a string, where each character represents time period
23         from the start of a time period.
24         (default '🕛🕧🕐🕜🕑🕝🕒🕞🕓🕟🕔🕠🕕🕡🕖🕢🕗🕣🕘🕤🕙🕥🕚🕦')
25     button_change_format: button that switches format used setting to None
26         disables (default 1)
27     button_change_time_format: button that switches format_time used. Setting
28         to None disables (default 2)
29     button_reset: button that switches display to the first timezone. Setting
30         to None disables (default 3)
31     cycle: If more than one display then how many seconds between changing the
32         display (default 0)
33     format: defines the timezones displayed. This can be a single string or a
34         list.  If a list is supplied then the formats can be cycled through
35         using `cycle` or by button click.  (default '{Local}')
36     format_time: format to use for the time, strftime directives such as `%H`
37         can be used this can be either a string or to allow multiple formats as
38         a list.  The one used can be changed by button click.
39         *(default ['[{name_unclear} ]%c', '[{name_unclear} ]%x %X',
40         '[{name_unclear} ]%a %H:%M', '[{name_unclear} ]{icon}'])*
41 
42 Format placeholders:
43     {icon} a character representing the time from `blocks`
44     {name} friendly timezone name eg `Buenos Aires`
45     {name_unclear} friendly timezone name eg `Buenos Aires` but is empty if
46         only one timezone is provided
47     {timezone} full timezone name eg `America/Argentina/Buenos_Aires`
48     {timezone_unclear} full timezone name eg `America/Argentina/Buenos_Aires`
49         but is empty if only one timezone is provided
50 
51 
52 Requires:
53     pytz: python library
54     tzlocal: python library
55 
56 i3status.conf example:
57 
58 ```
59 # cycling through London, Warsaw, Tokyo
60 clock {
61     cycle = 30
62     format = ["{Europe/London}", "{Europe/Warsaw}", "{Asia/Tokyo}"]
63     format_time = "{name} %H:%M"
64 }
65 
66 
67 # Show the time and date in New York
68 clock {
69    format = "Big Apple {America/New_York}"
70    format_time = "%Y-%m-%d %H:%M:%S"
71 }
72 
73 
74 # wall clocks
75 clock {
76     format = "{Asia/Calcutta} {Africa/Nairobi} {Asia/Bangkok}"
77     format_time = "{name} {icon}"
78 }
79 ```
80 
81 @author tobes
82 @license BSD
83 
84 SAMPLE OUTPUT
85 {'full_text': 'Sun 15 Jan 2017 23:27:17 GMT'}
86 
87 london
88 {'full_text': 'Thursday Feb 23 1:42 AM London'}
89 """
90 
91 import re
92 import math
93 from datetime import datetime
94 from time import time
95 
96 import pytz
97 import tzlocal
98 
99 CLOCK_BLOCKS = u'🕛🕧🕐🕜🕑🕝🕒🕞🕓🕟🕔🕠🕕🕡🕖🕢🕗🕣🕘🕤🕙🕥🕚🕦'
100 
101 
102 class Py3status:
103     """
104     """
105     # available configuration parameters
106     block_hours = 12
107     blocks = CLOCK_BLOCKS
108     button_change_format = 1
109     button_change_time_format = 2
110     button_reset = 3
111     cycle = 0
112     format = "{Local}"
113     format_time = [
114         '[{name_unclear} ]%c',
115         '[{name_unclear} ]%x %X',
116         '[{name_unclear} ]%a %H:%M',
117         '[{name_unclear} ]{icon}',
118     ]
119 
120     def post_config_hook(self):
121         # Multiple clocks are possible that can be cycled through
122         if not isinstance(self.format, list):
123             self.format = [self.format]
124         # if only one item we don't need to cycle
125         if len(self.format) == 1:
126             self.cycle = 0
127         # find any declared timezones eg {Europe/London}
128         self._items = {}
129         matches = re.findall('\{([^}]*)\}', ''.join(self.format))
130         for match in matches:
131             self._items[match] = self._get_timezone(match)
132 
133         self.multiple_tz = len(self._items) > 1
134 
135         if not isinstance(self.format_time, list):
136             self.format_time = [self.format_time]
137 
138         # workout how often in seconds we will need to do an update to keep the
139         # display fresh
140         self.time_deltas = []
141         for format in self.format_time:
142             format_time = re.sub('\{([^}]*)\}', '', format)
143             format_time = format_time.replace('%%', '')
144             if '%f' in format_time:
145                 # microseconds
146                 time_delta = 0
147             elif '%S' in format_time:
148                 # seconds
149                 time_delta = 1
150             elif '%s' in format_time:
151                 # seconds since unix epoch start
152                 time_delta = 1
153             elif '%T' in format_time:
154                 # seconds included in "%H:%M:%S"
155                 time_delta = 1
156             elif '%c' in format_time:
157                 # Locale’s appropriate date and time representation
158                 time_delta = 1
159             elif '%X' in format_time:
160                 # Locale’s appropriate time representation
161                 time_delta = 1
162             else:
163                 time_delta = 60
164             self.time_deltas.append(time_delta)
165 
166         self.active_time_format = 0
167 
168         self._cycle_time = time() + self.cycle
169         self.active = 0
170 
171     def _get_timezone(self, tz):
172         """
173         Find and return the time zone if possible
174         """
175         # special Local timezone
176         if tz == 'Local':
177             try:
178                 return tzlocal.get_localzone()
179             except pytz.UnknownTimeZoneError:
180                 return '?'
181 
182         # we can use a country code to get tz
183         # FIXME this is broken for multi-timezone countries eg US
184         # for now we just grab the first one
185         if len(tz) == 2:
186             try:
187                 zones = pytz.country_timezones(tz)
188             except KeyError:
189                 return '?'
190             tz = zones[0]
191 
192         # get the timezone
193         try:
194             zone = pytz.timezone(tz)
195         except pytz.UnknownTimeZoneError:
196             return '?'
197         return zone
198 
199     def _change_active(self, diff):
200         self.active = (self.active + diff) % len(self.format)
201 
202     def on_click(self, i3s_output_list, i3s_config, event):
203         """
204         Switch the displayed module or pass the event on to the active module
205         """
206         # reset cycle time
207         if event['button'] == self.button_reset:
208             self.active = 0
209             # reset the cycle time
210             self._cycle_time = time() + self.cycle
211         elif event['button'] == self.button_change_time_format:
212             self.active_time_format += 1
213             if self.active_time_format >= len(self.format_time):
214                 self.active_time_format = 0
215         elif event['button'] == self.button_change_format:
216             self._change_active(1)
217 
218     def clock(self, i3s_output_list, i3s_config):
219 
220         # cycling
221         if self.cycle and time() >= self._cycle_time:
222             self._change_active(1)
223             self._cycle_time = time() + self.cycle
224 
225         # update our times
226         times = {}
227         for name, zone in self._items.items():
228             if zone == '?':
229                 times[name] = '?'
230             else:
231                 t = datetime.now(zone)
232                 format_time = self.format_time[self.active_time_format]
233                 icon = None
234                 if self.py3.format_contains(format_time, 'icon'):
235                     # calculate the decimal hour
236                     h = t.hour + t.minute / 60.
237                     # make 12 hourly etc
238                     h = h % self.block_hours
239                     idx = int(math.floor(h / self.block_hours * (len(
240                         self.blocks))))
241                     icon = self.blocks[idx]
242 
243                 timezone = zone.zone
244                 tzname = timezone.split('/')[-1].replace('_', ' ')
245 
246                 if self.multiple_tz:
247                     name_unclear = tzname
248                     timezone_unclear = timezone
249                 else:
250                     name_unclear = ''
251                     timezone_unclear = ''
252 
253                 format_time = self.py3.safe_format(
254                     format_time,
255                     dict(
256                         icon=icon,
257                         name=tzname,
258                         name_unclear=name_unclear,
259                         timezone=timezone,
260                         timezone_unclear=timezone_unclear,
261                     ))
262                 if self.py3.is_python_2():
263                     format_time = t.strftime(format_time.encode('utf-8'))
264                 else:
265                     format_time = t.strftime(format_time)
266                 times[name] = format_time
267 
268         # work out when we need to update
269         timeout = self.py3.time_in(
270             sync_to=self.time_deltas[self.active_time_format]
271         )
272 
273         # if cycling we need to make sure we update when they are needed
274         if self.cycle:
275             cycle_timeout = self._cycle_time
276             timeout = min(timeout, cycle_timeout)
277 
278         return {
279             'full_text': self.py3.safe_format(self.format[self.active], times),
280             'cached_until': timeout
281         }
282 
283 
284 if __name__ == "__main__":
285     """
286     Run module in test mode.
287     """
288     from py3status.module_test import module_test
289     module_test(Py3status)
290
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/py3status/modules/clock.py b/py3status/modules/clock.py
--- a/py3status/modules/clock.py
+++ b/py3status/modules/clock.py
@@ -38,6 +38,10 @@
         a list.  The one used can be changed by button click.
         *(default ['[{name_unclear} ]%c', '[{name_unclear} ]%x %X',
         '[{name_unclear} ]%a %H:%M', '[{name_unclear} ]{icon}'])*
+    round_to_nearest_block: defines how a block icon is chosen. Examples:
+        when set to True,  '13:14' is '🕐', '13:16' is '🕜' and '13:31' is '🕜';
+        when set to False, '13:14' is '🕐', '13:16' is '🕐' and '13:31' is '🕜'.
+        (default True)
 
 Format placeholders:
     {icon} a character representing the time from `blocks`
@@ -87,9 +91,9 @@
 london
 {'full_text': 'Thursday Feb 23 1:42 AM London'}
 """
+from __future__ import division
 
 import re
-import math
 from datetime import datetime
 from time import time
 
@@ -116,6 +120,7 @@
         '[{name_unclear} ]%a %H:%M',
         '[{name_unclear} ]{icon}',
     ]
+    round_to_nearest_block = True
 
     def post_config_hook(self):
         # Multiple clocks are possible that can be cycled through
@@ -234,10 +239,11 @@
                 if self.py3.format_contains(format_time, 'icon'):
                     # calculate the decimal hour
                     h = t.hour + t.minute / 60.
+                    if self.round_to_nearest_block:
+                        h += (self.block_hours / len(self.blocks)) / 2
                     # make 12 hourly etc
                     h = h % self.block_hours
-                    idx = int(math.floor(h / self.block_hours * (len(
-                        self.blocks))))
+                    idx = int(h / self.block_hours * len(self.blocks))
                     icon = self.blocks[idx]
 
                 timezone = zone.zone

{"golden_diff": "diff --git a/py3status/modules/clock.py b/py3status/modules/clock.py\n--- a/py3status/modules/clock.py\n+++ b/py3status/modules/clock.py\n@@ -38,6 +38,10 @@\n         a list.  The one used can be changed by button click.\n         *(default ['[{name_unclear} ]%c', '[{name_unclear} ]%x %X',\n         '[{name_unclear} ]%a %H:%M', '[{name_unclear} ]{icon}'])*\n+    round_to_nearest_block: defines how a block icon is chosen. Examples:\n+        when set to True,  '13:14' is '\ud83d\udd50', '13:16' is '\ud83d\udd5c' and '13:31' is '\ud83d\udd5c';\n+        when set to False, '13:14' is '\ud83d\udd50', '13:16' is '\ud83d\udd50' and '13:31' is '\ud83d\udd5c'.\n+        (default True)\n \n Format placeholders:\n     {icon} a character representing the time from `blocks`\n@@ -87,9 +91,9 @@\n london\n {'full_text': 'Thursday Feb 23 1:42 AM London'}\n \"\"\"\n+from __future__ import division\n \n import re\n-import math\n from datetime import datetime\n from time import time\n \n@@ -116,6 +120,7 @@\n         '[{name_unclear} ]%a %H:%M',\n         '[{name_unclear} ]{icon}',\n     ]\n+    round_to_nearest_block = True\n \n     def post_config_hook(self):\n         # Multiple clocks are possible that can be cycled through\n@@ -234,10 +239,11 @@\n                 if self.py3.format_contains(format_time, 'icon'):\n                     # calculate the decimal hour\n                     h = t.hour + t.minute / 60.\n+                    if self.round_to_nearest_block:\n+                        h += (self.block_hours / len(self.blocks)) / 2\n                     # make 12 hourly etc\n                     h = h % self.block_hours\n-                    idx = int(math.floor(h / self.block_hours * (len(\n-                        self.blocks))))\n+                    idx = int(h / self.block_hours * len(self.blocks))\n                     icon = self.blocks[idx]\n \n                 timezone = zone.zone\n", "issue": "[clock] It is more intuitive to round clock emoji to the nearest 15 or 45 minutes\nThe emoji clock is being used in many apps these days, and I noticed that py3status implementation is not consistent with the rest and is less intuitive to me.\r\n\r\nCurrently the clock emoji is not being updated until the hour exactly reaches the next step, so for example:\r\n- 14:59 \ud83d\udd5d\r\n\r\nInstead, it is more intuitive to choose icon for the time rounded to the nearest 15 or 45 minutes, that is:\r\n\r\n- 14:01 \ud83d\udd51\r\n- 14:14 \ud83d\udd51\r\n- 14:15 \ud83d\udd5d\r\n- 14:44 \ud83d\udd5d\r\n- 14:45 \ud83d\udd52\r\n- 14:59 \ud83d\udd52\r\n\r\n/cc @tobes as you created this module.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nDisplay date and time.\n\nThis module allows one or more datetimes to be displayed.\nAll datetimes share the same format_time but can set their own timezones.\nTimezones are defined in the `format` using the TZ name in squiggly brackets eg\n`{GMT}`, `{Portugal}`, `{Europe/Paris}`, `{America/Argentina/Buenos_Aires}`.\n\nISO-3166 two letter country codes eg `{de}` can also be used but if more than\none timezone exists for the country eg `{us}` the first one will be selected.\n\n`{Local}` can be used for the local settings of your computer.\n\nNote: Timezones are case sensitive\n\nA full list of timezones can be found at\nhttps://en.wikipedia.org/wiki/List_of_tz_database_time_zones\n\nConfiguration parameters:\n    block_hours: length of time period for all blocks in hours (default 12)\n    blocks: a string, where each character represents time period\n        from the start of a time period.\n        (default '\ud83d\udd5b\ud83d\udd67\ud83d\udd50\ud83d\udd5c\ud83d\udd51\ud83d\udd5d\ud83d\udd52\ud83d\udd5e\ud83d\udd53\ud83d\udd5f\ud83d\udd54\ud83d\udd60\ud83d\udd55\ud83d\udd61\ud83d\udd56\ud83d\udd62\ud83d\udd57\ud83d\udd63\ud83d\udd58\ud83d\udd64\ud83d\udd59\ud83d\udd65\ud83d\udd5a\ud83d\udd66')\n    button_change_format: button that switches format used setting to None\n        disables (default 1)\n    button_change_time_format: button that switches format_time used. Setting\n        to None disables (default 2)\n    button_reset: button that switches display to the first timezone. Setting\n        to None disables (default 3)\n    cycle: If more than one display then how many seconds between changing the\n        display (default 0)\n    format: defines the timezones displayed. This can be a single string or a\n        list.  If a list is supplied then the formats can be cycled through\n        using `cycle` or by button click.  (default '{Local}')\n    format_time: format to use for the time, strftime directives such as `%H`\n        can be used this can be either a string or to allow multiple formats as\n        a list.  The one used can be changed by button click.\n        *(default ['[{name_unclear} ]%c', '[{name_unclear} ]%x %X',\n        '[{name_unclear} ]%a %H:%M', '[{name_unclear} ]{icon}'])*\n\nFormat placeholders:\n    {icon} a character representing the time from `blocks`\n    {name} friendly timezone name eg `Buenos Aires`\n    {name_unclear} friendly timezone name eg `Buenos Aires` but is empty if\n        only one timezone is provided\n    {timezone} full timezone name eg `America/Argentina/Buenos_Aires`\n    {timezone_unclear} full timezone name eg `America/Argentina/Buenos_Aires`\n        but is empty if only one timezone is provided\n\n\nRequires:\n    pytz: python library\n    tzlocal: python library\n\ni3status.conf example:\n\n```\n# cycling through London, Warsaw, Tokyo\nclock {\n    cycle = 30\n    format = [\"{Europe/London}\", \"{Europe/Warsaw}\", \"{Asia/Tokyo}\"]\n    format_time = \"{name} %H:%M\"\n}\n\n\n# Show the time and date in New York\nclock {\n   format = \"Big Apple {America/New_York}\"\n   format_time = \"%Y-%m-%d %H:%M:%S\"\n}\n\n\n# wall clocks\nclock {\n    format = \"{Asia/Calcutta} {Africa/Nairobi} {Asia/Bangkok}\"\n    format_time = \"{name} {icon}\"\n}\n```\n\n@author tobes\n@license BSD\n\nSAMPLE OUTPUT\n{'full_text': 'Sun 15 Jan 2017 23:27:17 GMT'}\n\nlondon\n{'full_text': 'Thursday Feb 23 1:42 AM London'}\n\"\"\"\n\nimport re\nimport math\nfrom datetime import datetime\nfrom time import time\n\nimport pytz\nimport tzlocal\n\nCLOCK_BLOCKS = u'\ud83d\udd5b\ud83d\udd67\ud83d\udd50\ud83d\udd5c\ud83d\udd51\ud83d\udd5d\ud83d\udd52\ud83d\udd5e\ud83d\udd53\ud83d\udd5f\ud83d\udd54\ud83d\udd60\ud83d\udd55\ud83d\udd61\ud83d\udd56\ud83d\udd62\ud83d\udd57\ud83d\udd63\ud83d\udd58\ud83d\udd64\ud83d\udd59\ud83d\udd65\ud83d\udd5a\ud83d\udd66'\n\n\nclass Py3status:\n    \"\"\"\n    \"\"\"\n    # available configuration parameters\n    block_hours = 12\n    blocks = CLOCK_BLOCKS\n    button_change_format = 1\n    button_change_time_format = 2\n    button_reset = 3\n    cycle = 0\n    format = \"{Local}\"\n    format_time = [\n        '[{name_unclear} ]%c',\n        '[{name_unclear} ]%x %X',\n        '[{name_unclear} ]%a %H:%M',\n        '[{name_unclear} ]{icon}',\n    ]\n\n    def post_config_hook(self):\n        # Multiple clocks are possible that can be cycled through\n        if not isinstance(self.format, list):\n            self.format = [self.format]\n        # if only one item we don't need to cycle\n        if len(self.format) == 1:\n            self.cycle = 0\n        # find any declared timezones eg {Europe/London}\n        self._items = {}\n        matches = re.findall('\\{([^}]*)\\}', ''.join(self.format))\n        for match in matches:\n            self._items[match] = self._get_timezone(match)\n\n        self.multiple_tz = len(self._items) > 1\n\n        if not isinstance(self.format_time, list):\n            self.format_time = [self.format_time]\n\n        # workout how often in seconds we will need to do an update to keep the\n        # display fresh\n        self.time_deltas = []\n        for format in self.format_time:\n            format_time = re.sub('\\{([^}]*)\\}', '', format)\n            format_time = format_time.replace('%%', '')\n            if '%f' in format_time:\n                # microseconds\n                time_delta = 0\n            elif '%S' in format_time:\n                # seconds\n                time_delta = 1\n            elif '%s' in format_time:\n                # seconds since unix epoch start\n                time_delta = 1\n            elif '%T' in format_time:\n                # seconds included in \"%H:%M:%S\"\n                time_delta = 1\n            elif '%c' in format_time:\n                # Locale\u2019s appropriate date and time representation\n                time_delta = 1\n            elif '%X' in format_time:\n                # Locale\u2019s appropriate time representation\n                time_delta = 1\n            else:\n                time_delta = 60\n            self.time_deltas.append(time_delta)\n\n        self.active_time_format = 0\n\n        self._cycle_time = time() + self.cycle\n        self.active = 0\n\n    def _get_timezone(self, tz):\n        \"\"\"\n        Find and return the time zone if possible\n        \"\"\"\n        # special Local timezone\n        if tz == 'Local':\n            try:\n                return tzlocal.get_localzone()\n            except pytz.UnknownTimeZoneError:\n                return '?'\n\n        # we can use a country code to get tz\n        # FIXME this is broken for multi-timezone countries eg US\n        # for now we just grab the first one\n        if len(tz) == 2:\n            try:\n                zones = pytz.country_timezones(tz)\n            except KeyError:\n                return '?'\n            tz = zones[0]\n\n        # get the timezone\n        try:\n            zone = pytz.timezone(tz)\n        except pytz.UnknownTimeZoneError:\n            return '?'\n        return zone\n\n    def _change_active(self, diff):\n        self.active = (self.active + diff) % len(self.format)\n\n    def on_click(self, i3s_output_list, i3s_config, event):\n        \"\"\"\n        Switch the displayed module or pass the event on to the active module\n        \"\"\"\n        # reset cycle time\n        if event['button'] == self.button_reset:\n            self.active = 0\n            # reset the cycle time\n            self._cycle_time = time() + self.cycle\n        elif event['button'] == self.button_change_time_format:\n            self.active_time_format += 1\n            if self.active_time_format >= len(self.format_time):\n                self.active_time_format = 0\n        elif event['button'] == self.button_change_format:\n            self._change_active(1)\n\n    def clock(self, i3s_output_list, i3s_config):\n\n        # cycling\n        if self.cycle and time() >= self._cycle_time:\n            self._change_active(1)\n            self._cycle_time = time() + self.cycle\n\n        # update our times\n        times = {}\n        for name, zone in self._items.items():\n            if zone == '?':\n                times[name] = '?'\n            else:\n                t = datetime.now(zone)\n                format_time = self.format_time[self.active_time_format]\n                icon = None\n                if self.py3.format_contains(format_time, 'icon'):\n                    # calculate the decimal hour\n                    h = t.hour + t.minute / 60.\n                    # make 12 hourly etc\n                    h = h % self.block_hours\n                    idx = int(math.floor(h / self.block_hours * (len(\n                        self.blocks))))\n                    icon = self.blocks[idx]\n\n                timezone = zone.zone\n                tzname = timezone.split('/')[-1].replace('_', ' ')\n\n                if self.multiple_tz:\n                    name_unclear = tzname\n                    timezone_unclear = timezone\n                else:\n                    name_unclear = ''\n                    timezone_unclear = ''\n\n                format_time = self.py3.safe_format(\n                    format_time,\n                    dict(\n                        icon=icon,\n                        name=tzname,\n                        name_unclear=name_unclear,\n                        timezone=timezone,\n                        timezone_unclear=timezone_unclear,\n                    ))\n                if self.py3.is_python_2():\n                    format_time = t.strftime(format_time.encode('utf-8'))\n                else:\n                    format_time = t.strftime(format_time)\n                times[name] = format_time\n\n        # work out when we need to update\n        timeout = self.py3.time_in(\n            sync_to=self.time_deltas[self.active_time_format]\n        )\n\n        # if cycling we need to make sure we update when they are needed\n        if self.cycle:\n            cycle_timeout = self._cycle_time\n            timeout = min(timeout, cycle_timeout)\n\n        return {\n            'full_text': self.py3.safe_format(self.format[self.active], times),\n            'cached_until': timeout\n        }\n\n\nif __name__ == \"__main__\":\n    \"\"\"\n    Run module in test mode.\n    \"\"\"\n    from py3status.module_test import module_test\n    module_test(Py3status)\n", "path": "py3status/modules/clock.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nDisplay date and time.\n\nThis module allows one or more datetimes to be displayed.\nAll datetimes share the same format_time but can set their own timezones.\nTimezones are defined in the `format` using the TZ name in squiggly brackets eg\n`{GMT}`, `{Portugal}`, `{Europe/Paris}`, `{America/Argentina/Buenos_Aires}`.\n\nISO-3166 two letter country codes eg `{de}` can also be used but if more than\none timezone exists for the country eg `{us}` the first one will be selected.\n\n`{Local}` can be used for the local settings of your computer.\n\nNote: Timezones are case sensitive\n\nA full list of timezones can be found at\nhttps://en.wikipedia.org/wiki/List_of_tz_database_time_zones\n\nConfiguration parameters:\n    block_hours: length of time period for all blocks in hours (default 12)\n    blocks: a string, where each character represents time period\n        from the start of a time period.\n        (default '\ud83d\udd5b\ud83d\udd67\ud83d\udd50\ud83d\udd5c\ud83d\udd51\ud83d\udd5d\ud83d\udd52\ud83d\udd5e\ud83d\udd53\ud83d\udd5f\ud83d\udd54\ud83d\udd60\ud83d\udd55\ud83d\udd61\ud83d\udd56\ud83d\udd62\ud83d\udd57\ud83d\udd63\ud83d\udd58\ud83d\udd64\ud83d\udd59\ud83d\udd65\ud83d\udd5a\ud83d\udd66')\n    button_change_format: button that switches format used setting to None\n        disables (default 1)\n    button_change_time_format: button that switches format_time used. Setting\n        to None disables (default 2)\n    button_reset: button that switches display to the first timezone. Setting\n        to None disables (default 3)\n    cycle: If more than one display then how many seconds between changing the\n        display (default 0)\n    format: defines the timezones displayed. This can be a single string or a\n        list.  If a list is supplied then the formats can be cycled through\n        using `cycle` or by button click.  (default '{Local}')\n    format_time: format to use for the time, strftime directives such as `%H`\n        can be used this can be either a string or to allow multiple formats as\n        a list.  The one used can be changed by button click.\n        *(default ['[{name_unclear} ]%c', '[{name_unclear} ]%x %X',\n        '[{name_unclear} ]%a %H:%M', '[{name_unclear} ]{icon}'])*\n    round_to_nearest_block: defines how a block icon is chosen. Examples:\n        when set to True,  '13:14' is '\ud83d\udd50', '13:16' is '\ud83d\udd5c' and '13:31' is '\ud83d\udd5c';\n        when set to False, '13:14' is '\ud83d\udd50', '13:16' is '\ud83d\udd50' and '13:31' is '\ud83d\udd5c'.\n        (default True)\n\nFormat placeholders:\n    {icon} a character representing the time from `blocks`\n    {name} friendly timezone name eg `Buenos Aires`\n    {name_unclear} friendly timezone name eg `Buenos Aires` but is empty if\n        only one timezone is provided\n    {timezone} full timezone name eg `America/Argentina/Buenos_Aires`\n    {timezone_unclear} full timezone name eg `America/Argentina/Buenos_Aires`\n        but is empty if only one timezone is provided\n\n\nRequires:\n    pytz: python library\n    tzlocal: python library\n\ni3status.conf example:\n\n```\n# cycling through London, Warsaw, Tokyo\nclock {\n    cycle = 30\n    format = [\"{Europe/London}\", \"{Europe/Warsaw}\", \"{Asia/Tokyo}\"]\n    format_time = \"{name} %H:%M\"\n}\n\n\n# Show the time and date in New York\nclock {\n   format = \"Big Apple {America/New_York}\"\n   format_time = \"%Y-%m-%d %H:%M:%S\"\n}\n\n\n# wall clocks\nclock {\n    format = \"{Asia/Calcutta} {Africa/Nairobi} {Asia/Bangkok}\"\n    format_time = \"{name} {icon}\"\n}\n```\n\n@author tobes\n@license BSD\n\nSAMPLE OUTPUT\n{'full_text': 'Sun 15 Jan 2017 23:27:17 GMT'}\n\nlondon\n{'full_text': 'Thursday Feb 23 1:42 AM London'}\n\"\"\"\nfrom __future__ import division\n\nimport re\nfrom datetime import datetime\nfrom time import time\n\nimport pytz\nimport tzlocal\n\nCLOCK_BLOCKS = u'\ud83d\udd5b\ud83d\udd67\ud83d\udd50\ud83d\udd5c\ud83d\udd51\ud83d\udd5d\ud83d\udd52\ud83d\udd5e\ud83d\udd53\ud83d\udd5f\ud83d\udd54\ud83d\udd60\ud83d\udd55\ud83d\udd61\ud83d\udd56\ud83d\udd62\ud83d\udd57\ud83d\udd63\ud83d\udd58\ud83d\udd64\ud83d\udd59\ud83d\udd65\ud83d\udd5a\ud83d\udd66'\n\n\nclass Py3status:\n    \"\"\"\n    \"\"\"\n    # available configuration parameters\n    block_hours = 12\n    blocks = CLOCK_BLOCKS\n    button_change_format = 1\n    button_change_time_format = 2\n    button_reset = 3\n    cycle = 0\n    format = \"{Local}\"\n    format_time = [\n        '[{name_unclear} ]%c',\n        '[{name_unclear} ]%x %X',\n        '[{name_unclear} ]%a %H:%M',\n        '[{name_unclear} ]{icon}',\n    ]\n    round_to_nearest_block = True\n\n    def post_config_hook(self):\n        # Multiple clocks are possible that can be cycled through\n        if not isinstance(self.format, list):\n            self.format = [self.format]\n        # if only one item we don't need to cycle\n        if len(self.format) == 1:\n            self.cycle = 0\n        # find any declared timezones eg {Europe/London}\n        self._items = {}\n        matches = re.findall('\\{([^}]*)\\}', ''.join(self.format))\n        for match in matches:\n            self._items[match] = self._get_timezone(match)\n\n        self.multiple_tz = len(self._items) > 1\n\n        if not isinstance(self.format_time, list):\n            self.format_time = [self.format_time]\n\n        # workout how often in seconds we will need to do an update to keep the\n        # display fresh\n        self.time_deltas = []\n        for format in self.format_time:\n            format_time = re.sub('\\{([^}]*)\\}', '', format)\n            format_time = format_time.replace('%%', '')\n            if '%f' in format_time:\n                # microseconds\n                time_delta = 0\n            elif '%S' in format_time:\n                # seconds\n                time_delta = 1\n            elif '%s' in format_time:\n                # seconds since unix epoch start\n                time_delta = 1\n            elif '%T' in format_time:\n                # seconds included in \"%H:%M:%S\"\n                time_delta = 1\n            elif '%c' in format_time:\n                # Locale\u2019s appropriate date and time representation\n                time_delta = 1\n            elif '%X' in format_time:\n                # Locale\u2019s appropriate time representation\n                time_delta = 1\n            else:\n                time_delta = 60\n            self.time_deltas.append(time_delta)\n\n        self.active_time_format = 0\n\n        self._cycle_time = time() + self.cycle\n        self.active = 0\n\n    def _get_timezone(self, tz):\n        \"\"\"\n        Find and return the time zone if possible\n        \"\"\"\n        # special Local timezone\n        if tz == 'Local':\n            try:\n                return tzlocal.get_localzone()\n            except pytz.UnknownTimeZoneError:\n                return '?'\n\n        # we can use a country code to get tz\n        # FIXME this is broken for multi-timezone countries eg US\n        # for now we just grab the first one\n        if len(tz) == 2:\n            try:\n                zones = pytz.country_timezones(tz)\n            except KeyError:\n                return '?'\n            tz = zones[0]\n\n        # get the timezone\n        try:\n            zone = pytz.timezone(tz)\n        except pytz.UnknownTimeZoneError:\n            return '?'\n        return zone\n\n    def _change_active(self, diff):\n        self.active = (self.active + diff) % len(self.format)\n\n    def on_click(self, i3s_output_list, i3s_config, event):\n        \"\"\"\n        Switch the displayed module or pass the event on to the active module\n        \"\"\"\n        # reset cycle time\n        if event['button'] == self.button_reset:\n            self.active = 0\n            # reset the cycle time\n            self._cycle_time = time() + self.cycle\n        elif event['button'] == self.button_change_time_format:\n            self.active_time_format += 1\n            if self.active_time_format >= len(self.format_time):\n                self.active_time_format = 0\n        elif event['button'] == self.button_change_format:\n            self._change_active(1)\n\n    def clock(self, i3s_output_list, i3s_config):\n\n        # cycling\n        if self.cycle and time() >= self._cycle_time:\n            self._change_active(1)\n            self._cycle_time = time() + self.cycle\n\n        # update our times\n        times = {}\n        for name, zone in self._items.items():\n            if zone == '?':\n                times[name] = '?'\n            else:\n                t = datetime.now(zone)\n                format_time = self.format_time[self.active_time_format]\n                icon = None\n                if self.py3.format_contains(format_time, 'icon'):\n                    # calculate the decimal hour\n                    h = t.hour + t.minute / 60.\n                    if self.round_to_nearest_block:\n                        h += (self.block_hours / len(self.blocks)) / 2\n                    # make 12 hourly etc\n                    h = h % self.block_hours\n                    idx = int(h / self.block_hours * len(self.blocks))\n                    icon = self.blocks[idx]\n\n                timezone = zone.zone\n                tzname = timezone.split('/')[-1].replace('_', ' ')\n\n                if self.multiple_tz:\n                    name_unclear = tzname\n                    timezone_unclear = timezone\n                else:\n                    name_unclear = ''\n                    timezone_unclear = ''\n\n                format_time = self.py3.safe_format(\n                    format_time,\n                    dict(\n                        icon=icon,\n                        name=tzname,\n                        name_unclear=name_unclear,\n                        timezone=timezone,\n                        timezone_unclear=timezone_unclear,\n                    ))\n                if self.py3.is_python_2():\n                    format_time = t.strftime(format_time.encode('utf-8'))\n                else:\n                    format_time = t.strftime(format_time)\n                times[name] = format_time\n\n        # work out when we need to update\n        timeout = self.py3.time_in(\n            sync_to=self.time_deltas[self.active_time_format]\n        )\n\n        # if cycling we need to make sure we update when they are needed\n        if self.cycle:\n            cycle_timeout = self._cycle_time\n            timeout = min(timeout, cycle_timeout)\n\n        return {\n            'full_text': self.py3.safe_format(self.format[self.active], times),\n            'cached_until': timeout\n        }\n\n\nif __name__ == \"__main__\":\n    \"\"\"\n    Run module in test mode.\n    \"\"\"\n    from py3status.module_test import module_test\n    module_test(Py3status)\n", "path": "py3status/modules/clock.py"}]}