Repository: apache/airflow

Issue:
TimeSensor triggers immediately when used over midnight (UTC)
<!--

Welcome to Apache Airflow!  For a smooth issue process, try to answer the following questions.
Don't worry if they're not all applicable; just try to include what you can :-)

If you need to include code snippets or logs, please put them in fenced code
blocks.  If they're super-long, please use the details tag like
<details><summary>super-long log</summary> lots of stuff </details>

Please delete these comment blocks before submitting the issue.

-->

<!--

IMPORTANT!!!

PLEASE CHECK "SIMILAR TO X EXISTING ISSUES" OPTION IF VISIBLE
NEXT TO "SUBMIT NEW ISSUE" BUTTON!!!

PLEASE CHECK IF THIS ISSUE HAS BEEN REPORTED PREVIOUSLY USING SEARCH!!!

Please complete the next sections or the issue will be closed.
This questions are the first thing we need to know to understand the context.

-->

**Apache Airflow version**: 1.10.10 (issue exists in current master as well)

**Environment**: does not seem relevant

**What happened**:

The TimeSensor does trigger if the current time is later than the defined trigger time. Looking at the [source code](https://github.com/apache/airflow/blob/master/airflow/sensors/time_sensor.py), the trigger rule is defined as
```
return timezone.utcnow().time() > self.target_time
```
This leads to problems when the DAG runs over midnight UTC. For example, suppose the following DAG:

```
with DAG('foo', 
    default_args={'start_date': datetime(2020, 7, 1, tzinfo=pendulum.timezone("Europe/Berlin"))}, 
    schedule_interval="0 0 * * *") as dag:

    # in summer, Europe/Berlin is two hours after UTC, hence: 
    time_04h00_local = TimeSensor(task_id="time_01h30", target_time=time(hour=2, minute=00))
```

This DAG will be triggered at 22:00 UTC. Then, according to the trigger rule:
```
22:00 UTC > 2:00 UTC
```
Hence, the TimeSensor will be triggered immediately. 

**What you expected to happen**:

The TimeSensor should trigger at the following day if `target_time < next_execution_date.time()`

**Possible workarounds**:

One can always use the TimeDeltaSensor to archive similar effects. This does result in code that is not as readable, though. 


Discussion:
Thanks for opening your first issue here! Be sure to follow the issue template!

I would say this is a feature request rather than a bug. The TimeSensor behaves as expected.

I would like to propose a new sensor `DateTimeSensor`.

So in case above, it will be something like
```
sensor = DateTimeSensor(
    task_id="sensor",
    target_time='{{ next_execution_date.add(days=1).replace(hour=2, minute=0) }}'
)
```

WDYT?
I would also be fine with a new sensor. I still believe that this problem should be at least documented, as it is everything but obvious if the DAG is initialized timezone aware. 
I just realize your case is a little different. You must have set `default_timezone` in the Airflow config. I think we should fix it in `TimeSensor` itself. I'll make a quick PR

Resolving patch:
diff --git a/airflow/sensors/time_sensor.py b/airflow/sensors/time_sensor.py
--- a/airflow/sensors/time_sensor.py
+++ b/airflow/sensors/time_sensor.py
@@ -36,4 +36,4 @@ def __init__(self, target_time, *args, **kwargs):
 
     def poke(self, context):
         self.log.info('Checking if the time (%s) has come', self.target_time)
-        return timezone.utcnow().time() > self.target_time
+        return timezone.make_naive(timezone.utcnow()).time() > self.target_time


Test patch: