File: README.rst

package info (click to toggle)
undertime 4.3.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 704 kB
  • sloc: python: 957; makefile: 6; sh: 2
file content (258 lines) | stat: -rw-r--r-- 13,559 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
Undertime - pick a meeting time
===============================

This program allows you to quickly pick a meeting time across multiple
timezones for conference calls or other coordinated events. It shows
all times of a given day for all the timezones selected, in a table
that aligns the time so a line shows simultaneous times across all
timezones. This takes into account daylight savings and other
peculiarities (provided that the local timezone database is up to
date) so you can also schedule meetings in the future as well.

.. image:: https://gitlab.com/anarcat/undertime/-/raw/main/undertime.png
   :alt: screenshot of undertime computing possible meeting time for
         multiple timezones on a daylight savings switch in the
         America/Vancouver, America/New_York, UTC and Europe/Paris timezones

.. image:: https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg 
   :alt: Say thanks to the author
   :target: https://saythanks.io/to/anarcat

Usage
=====

Timezones should be passed on the commandline and are matched against
the `list of known timezones`_, as defined by the `pytz`_
package. Exact matches are attempted at first, but if that fails,
substring matches are allowed, which makes it possible to do this::

  undertime --timezones New_York Los_Angeles

Example output::

    ananarcat@angela:undertime$ ./undertime --no-colors --config=undertime.yml --no-default-zone
    ╔═════════════╤════════════╤════════╤═════════╤═══════════════╤═════════════╤════════════╤═════╗
    ║  Vancouver  │  New_York  │  UTC   │  Paris  │  Addis_Ababa  │  Hong_Kong  │  Auckland  │   n ║
    ╠═════════════╪════════════╪════════╪═════════╪═══════════════╪═════════════╪════════════╪═════╣
    ║    21:00    │   00:00    │ 05:00  │  06:00  │     08:00     │   13:00_    │   18:00    │   1 ║
    ║    22:00    │   01:00    │ 06:00  │  07:00  │    09:00_     │   14:00_    │   19:00    │   2 ║
    ║    23:00    │   02:00    │ 07:00  │  08:00  │    10:00_     │   15:00_    │   20:00    │   2 ║
    ║    00:00    │   03:00    │ 08:00  │ 09:00_  │    11:00_     │   16:00_    │   21:00    │   3 ║
    ║    01:00    │   04:00    │ 09:00_ │ 10:00_  │    12:00_     │   17:00_    │   22:00    │   4 ║
    ║    02:00    │   05:00    │ 10:00_ │ 11:00_  │    13:00_     │    18:00    │   23:00    │   3 ║
    ║    03:00    │   06:00    │ 11:00_ │ 12:00_  │    14:00_     │    19:00    │   00:00    │   3 ║
    ║    04:00    │   07:00    │ 12:00_ │ 13:00_  │    15:00_     │    20:00    │   01:00    │   3 ║
    ║    05:00    │   08:00    │ 13:00_ │ 14:00_  │    16:00_     │    21:00    │   02:00    │   3 ║
    ║    06:00    │   09:00_   │ 14:00_ │ 15:00_  │    17:00_     │    22:00    │   03:00    │   4 ║
    ║    07:00    │   10:00_   │ 15:00_ │ 16:00_  │     18:00     │    23:00    │   04:00    │   3 ║
    ║    08:00    │   11:00_   │ 16:00_ │ 17:00_  │     19:00     │    00:00    │   05:00    │   3 ║
    ║   09:00_    │   12:00_   │ 17:00_ │  18:00  │     20:00     │    01:00    │   06:00    │   3 ║
    ║   10:00_    │   13:00_   │ 18:00  │  19:00  │     21:00     │    02:00    │   07:00    │   2 ║
    ║   11:00_    │   14:00_   │ 19:00  │  20:00  │     22:00     │    03:00    │   08:00    │   2 ║
    ║   12:00_    │   15:00_   │ 20:00  │  21:00  │     23:00     │    04:00    │   09:00_   │   3 ║
    ║   13:00_    │   16:00_   │ 21:00  │  22:00  │     00:00     │    05:00    │   10:00_   │   3 ║
    ║   14:00_    │   17:00_   │ 22:00  │  23:00  │     01:00     │    06:00    │   11:00_   │   3 ║
    ║   14:07*    │   17:07*   │ 22:07* │ 23:07*  │    01:07*     │   06:07*    │   11:07*   │   3 ║
    ║   15:00_    │   18:00    │ 23:00  │  00:00  │     02:00     │    07:00    │   12:00_   │   2 ║
    ║   16:00_    │   19:00    │ 00:00  │  01:00  │     03:00     │    08:00    │   13:00_   │   2 ║
    ║   17:00_    │   20:00    │ 01:00  │  02:00  │     04:00     │   09:00_    │   14:00_   │   3 ║
    ║    18:00    │   21:00    │ 02:00  │  03:00  │     05:00     │   10:00_    │   15:00_   │   2 ║
    ║    19:00    │   22:00    │ 03:00  │  04:00  │     06:00     │   11:00_    │   16:00_   │   2 ║
    ║    20:00    │   23:00    │ 04:00  │  05:00  │     07:00     │   12:00_    │   17:00_   │   2 ║
    ╚═════════════╧════════════╧════════╧═════════╧═══════════════╧═════════════╧════════════╧═════╝
    UTC time: 2025-01-07 22:07:21+00:00
    local time: 2025-01-07 17:07:21-05:00
    equivalent to:
    - 14:07 America/Vancouver
    - 17:07 America/New_York
    - 22:07 UTC
    - 23:07 Europe/Paris
    - 2025-01-08 01:07 Africa/Addis_Ababa
    - 2025-01-08 06:07 Asia/Hong_Kong
    - 2025-01-08 11:07 Pacific/Auckland

In the above, the underscored lines are the ones during the predefined
"business hours" range, and the ones with stars are the current
time. Those are rendered in yellow and bold, respectively, if colors
are enabled.

Because daylight savings may actually change time, you can also
specify the time to pick an arbitrary time for the meeting, using
natural language (as parsed by the `dateparser`_ or `parsedatetime`_
modules, if available). The current time is also shown, in bold. This,
for example, will show the time "tomorrow" at the same time as today:

    undertime tomorrow

Or the next September 21st at 19:00 local time:

    undertime September 21 19:00

Colors are used to highlight the "work hours" where possible meeting
times could overlap. You can change those work hours with the
``--start`` and ``--end`` flags. The number of zones matching those
hours is listed in the last column.

The output format is controlled by the `tabulate`_ program. See the
`tabulate documentation`_ for more information about the
possible outputs.

A configuration file can be used to set defaults, see the
``undertime.yml`` file for an example.

The complete list of timezones is also shown when the
``--list-zones`` commandline option is provided. Note that in recent
tzdata versions, legacy zones like ``US/Eastern`` or ``US/Pacific``
have been removed, as many others. Install the ``tzdata-legacy``
package to restore those.

Also, be careful with those zone names, some are pretty confusing!
``Etc/GMT+12``, for example, is actually UTC-12, confusingly (see
`this explanation`_. For people on the american east, you might also
be tempted by the ``EST5EDT`` zone, hoping it will give you summer
time, but it will *not* do that: pick a summer date and your normal
zone (e.g. ``US/Eastern``) and ``undertime`` will do the right thing::

  > undertime 2024-06-21T12:00:00-0000 --timezones US/Eastern
  UTC time: 2024-06-21 12:00:00+00:00
  local time: 2024-06-21 08:00:00-04:00
  equivalent to: 08:00 US/Eastern

The ``--list-zones`` options also shows the offset of each zone, in
hours. Note that those are floats: offsets are actually in *seconds*
in the underlying API, but we are trying to save you from this
horror. You should be able to sort zones by offset with the ``sort``
command::

  undertime --list-zones | sort -k2 -n

Finally, note that you can specify zones with a fixed offset with
`UTC+-N`. For example, ``UTC-12`` is `Anywhere on Earth`_. 
``UTC-5`` is "normal" (non-daylight) for ``US/Eastern``, but it
doesn't take into account daylight savings, so be careful!

Summary usage is available with the ``--help`` flag and full help in
the manpage. Instructions for how to contribute to the project are in
``CONTRIBUTING.rst`` and there is a ``CODE_OF_CONDUCT.rst``.

.. _list of known timezones: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
.. _pytz: https://pypi.python.org/pypi/pytz
.. _dateparser: https://dateparser.readthedocs.io/
.. _parsedatetime: https://pypi.python.org/pypi/parsedatetime/
.. _overtime-cli: https://github.com/diit/overtime-cli
.. _tabulate: https://pypi.org/project/tabulate/
.. _tabulate documentation: `tabulate`_
.. _this explanation: https://en.wikipedia.org/wiki/Tz_database#Area
.. _Anywhere on Earth: https://en.wikipedia.org/wiki/Anywhere_on_Earth

Known issues and limitations
============================

Undertime was written using Python 3.5 and 3.7 and there is no
guarantee it will work in older (or newer) Python releases.

Timezones -- and time in general -- are hard problems: the math is
hard, and the zones constantly. What may be applicable to your
location at the current time may not be reflected by your operating
system or the chain of software used by this program to determine
time. `According to this video <timezone-video>`_ from `Tom Scott
<tomscott>`_, "*you really should never, ever deal with timezones if
you can help it*". This sounds a lot like what this program does, but
do note that:

    "What you learn, after dealing with timezones, is that what you
    do, is you put away your code, you don't try and write anything to
    deal with this. You look at the people who have been there before
    you. You look at the first people, the people who've done this
    before, the people who've built the spaghetti code, and you go to
    them, and you thank them very much for making it open source, and
    you give them credit, and you take what they've made, you put it
    in your program. and you never ever look at it again. because that
    way lies madness."

    -- Tom Scott

That is what this program does. It reuses the `pytz`_ library based on
the `Olson tz database`_. See the Credits section for more information.

.. _timezone-video: https://www.youtube.com/watch?v=-5wpm-gesOY
.. _tomscott: https://twitter.com/tomscott
.. _Olson tz database: https://en.wikipedia.org/wiki/Tz_database

Time is an illusion we created to rationalize our unbearable
ephemerality and is bound to be imprecise, confusing and flawed. It's
neither your fault or your computer's: accept and embrace its
humanity.

.. _issue #3: https://gitlab.com/anarcat/undertime/issues/3
.. _issue #4: https://gitlab.com/anarcat/undertime/issues/4

Installing
==========

This program can be installed using ``pip`` from the `PyPI
repository`_, like so::

  pip3 install undertime

The above assumes you're running a distribution that installs the
Python 3 version of ``pip`` as ``pip3``, you might need to replace
that with just ``pip`` on some setups.

This program is also packaged in Debian (since Debian 10 "buster"), so
you can also install it with::

  apt install undertime

If you downloaded this source code and want to install *that*
directly, you can simply run::

  pip3 install .

.. _PyPI repository: https://pypi.org/project/undertime/

Credits
=======

This program was written by Antoine Beaupré and is licensed under the
AGPLv3+. I rewrote `overtime-cli`_ in Python because I felt we
shouldn't need a Javascript virtual machine to pick a time. I was also
curious to see how such a rewrite would look like and was tired of
loading a web browser every time I needed to figure out what time it
was elsewhere in the world or when I needed to coordinate
international meetings.

All of this wouldn't have been possible without the `pytz`_ library
written by Stuart Bishop, itself based on the `Olson tz database`_
founded by Arthur David Olson and currently maintained by Paul
Eggert. Those packages are shipped to your favorite Debian
distribution by package maintainers who struggle to keep up with those
constant changes so credits should also go to the `tzdata package
maintainers`_ (currently Adam Conrad, Aurelien Jarno, and Clint Adams)
along with everyone in the Debian project keeping all those packages
up to date. Thank you for dealing with humanity's confusing,
beautiful and complex quirks for all of us.

.. _tzdata package maintainers: https://tracker.debian.org/pkg/tzdata

Similar projects
=====================

 * `crab fit`_: web-based, timezone-sensitive meeting planner, free
   software
 * `overtime-cli`_: primary inspiration for undertime
 * `timeanddate.com`_: what I was using before, non-free
 * `tzdiff`_: strickingly similar, but discovered a few months after
   writing undertime
 * `when`_: shows time as blocks, Rust, strange syntax (e.g.
   ``now in yyz -> sfo -> lhr``), not updated in 3 years as of 2025
 * `worldchatclock.com`_: beautiful round, web interface, non-free
 * `worldtimebuddy.com`_: simple web interface, clever horizontal
   design, non-free

.. _crab fit: https://crab.fit/
.. _worldtimebuddy.com: https://www.worldtimebuddy.com/
.. _timeanddate.com: https://www.timeanddate.com/
.. _worldchatclock.com: http://worldchatclock.com/
.. _tzdiff: https://github.com/belgianbeer/tzdiff
.. _when: https://github.com/mitsuhiko/when