Repository: python-telegram-bot/python-telegram-bot

Issue:
[BUG] Job_queue is skipping job if timezone is not provided for job.run_daily
For example, my local timezone is +3 UTC and I want to run job every working day at 23:00 UTC.

`launch_time.tzinfo` is `None` so it's expected to be interpreted as 23:00 UTC.
```python
launch_time = dtm.time(hour=23)
job = job_queue.run_daily(run_once, launch_time,
                          days=(0, 1, 3, 4))
```

Since `launch_time.tzinfo` was `None`, `job.tzinfo` is also equals `None` because of the following code from `JobQueue.run_daily` https://github.com/python-telegram-bot/python-telegram-bot/blob/3d42df3366d7cff030c3ce06d6a95259b3bdf62e/telegram/ext/jobqueue.py#L225-L232

Let's assume now is 23:00 UTC Friday. 

The following code from `JobQueue.tick` won't run the job because 
1) `datetime.datetime.now(None)` returns local time and local time now is 02:00 Saturday.
2) then `datetime.datetime.now(job.tzinfo).date().weekday()` will return `5`
3) `any(day == current_week_day for day in job.days)` will return `False` because we're looking for `(0, 1, 3, 4)`
So job won't be run until 23:00 UTC Sunday.
https://github.com/python-telegram-bot/python-telegram-bot/blob/3d42df3366d7cff030c3ce06d6a95259b3bdf62e/telegram/ext/jobqueue.py#L275-L280


And one more thing - when #1685 will be merged, in the described case `Job.next_t` will be returning local time when utc time is expected:
```python
    @property
    def next_t(self):
        return datetime.datetime.fromtimestamp(self._next_t, self.tzinfo) if self._next_t else None

```



Discussion:
So if I see correctly, adding a `tzinfo` argument to `run_daily` would solve the issue?
It would work.

Other solution is to change part of `run_daily` to something like:
```python
job = Job(callback,
          interval=datetime.timedelta(days=1),
          repeat=True,
          days=days,
          tzinfo=time.tzinfo or _UTC,
          context=context,
          name=name,
          job_queue=self)
```

But after #1685 `Job.tzinfo` will be used for often, so maybe it's a good idea to add an optional argument `tzinfo` to `run_daily` and also to `run_repeating` and `run_once`? So it will be always possible to specify preferred timezone with job initialization.
Adding an optional argument seems cleaner to me, too.
If we're on it, yes add it to `run_repeating` and `run_once`, too. Maybe add a note, that just having an aware dtm object would be better.

Resolving patch:
diff --git a/telegram/ext/jobqueue.py b/telegram/ext/jobqueue.py
--- a/telegram/ext/jobqueue.py
+++ b/telegram/ext/jobqueue.py
@@ -275,7 +275,7 @@ def tick(self):
             if job.enabled:
                 try:
                     current_week_day = datetime.datetime.now(job.tzinfo).date().weekday()
-                    if any(day == current_week_day for day in job.days):
+                    if current_week_day in job.days:
                         self.logger.debug('Running job %s', job.name)
                         job.run(self._dispatcher)
 
@@ -387,7 +387,7 @@ def __init__(self,
                  days=Days.EVERY_DAY,
                  name=None,
                  job_queue=None,
-                 tzinfo=_UTC):
+                 tzinfo=None):
 
         self.callback = callback
         self.context = context
@@ -400,7 +400,7 @@ def __init__(self,
 
         self._days = None
         self.days = days
-        self.tzinfo = tzinfo
+        self.tzinfo = tzinfo or _UTC
 
         self._job_queue = weakref.proxy(job_queue) if job_queue is not None else None
 


Test patch:
diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py
--- a/tests/test_jobqueue.py
+++ b/tests/test_jobqueue.py
@@ -28,7 +28,7 @@
 
 from telegram.ext import JobQueue, Updater, Job, CallbackContext
 from telegram.utils.deprecate import TelegramDeprecationWarning
-from telegram.utils.helpers import _UtcOffsetTimezone
+from telegram.utils.helpers import _UtcOffsetTimezone, _UTC
 
 
 @pytest.fixture(scope='function')
@@ -325,3 +325,14 @@ def test_context_based_callback(self, job_queue):
         sleep(0.03)
 
         assert self.result == 0
+
+    def test_job_default_tzinfo(self, job_queue):
+        """Test that default tzinfo is always set to UTC"""
+        job_1 = job_queue.run_once(self.job_run_once, 0.01)
+        job_2 = job_queue.run_repeating(self.job_run_once, 10)
+        job_3 = job_queue.run_daily(self.job_run_once, time=dtm.time(hour=15))
+
+        jobs = [job_1, job_2, job_3]
+
+        for job in jobs:
+            assert job.tzinfo == _UTC