sdispater / pendulum

Python datetimes made easy
https://pendulum.eustace.io
MIT License
6.25k stars 387 forks source link

is_utc() returns False when parsing from a UTC date #293

Open joaonc opened 6 years ago

joaonc commented 6 years ago

This date is UTC: '2018-06-21T09:30:00+00:00', however, the is_utc() method returns False.

>>> pendulum.parse('2018-06-21T09:30:00+00:00').timezone
Timezone('+00:00')

>>> pendulum.parse('2018-06-21T09:30:00+00:00').is_utc()
False

The current implementation is:

    def is_utc(self):
        return self.timezone_name == 'UTC'

Maybe it can be something like:

    def is_utc(self):
        return self.timezone.offset == 0
redlickigrzegorz commented 6 years ago

I created a pull request #295 for resolving this issue. I hope it resolves the problem. I would like to ask for a review also.

dazza-codes commented 6 years ago

Pendulum 1.5.1 example where UTC parsing is OK:

In [1]: import pendulum                                                                                                                                                            
In [2]: dt = pendulum.now('UTC')                                                                                                                                                   
In [3]: date_str = dt.strftime('%Y%m%dT%H%M%SZ') # a file-name compatible format
In [4]: dt = pendulum.parse(date_str, tz='UTC')                                                                                                                                    
In [5]: dt                                                                                                                                                                         
Out[5]: <Pendulum [2018-11-15T23:15:39+00:00]>
In [6]: dt.tz                                                                                                                                                                      
Out[6]: <Timezone [+00:00]>
In [9]: dt.utc                                                                                                                                                                     
Out[9]: True

python 3.7.x and pendulum 2.0.4:

In [1]: import pendulum                                                                                                                                                            
In [2]: dt = pendulum.now('UTC')                                                                                                                                                   
In [3]: date_str = dt.strftime('%Y%m%dT%H%M%SZ')                                                                                                                                   
In [4]: date_str                                                                                                                                                                   
Out[4]: '20181115T232350Z'
In [5]: dt = pendulum.parse(date_str, tz='UTC')                                                                                                                                    
In [6]: dt                                                                                                                                                                         
Out[6]: DateTime(2018, 11, 15, 23, 23, 50, tzinfo=Timezone('+00:00'))
In [7]: dt.tz                                                                                                                                                                      
Out[7]: Timezone('+00:00')
In [10]: dt.is_utc()                                                                                                                                                               
Out[10]: False

# just to be a little more ISO-8601 compatible
In [11]: date_str = dt.strftime('%Y-%m-%dT%H:%M:%SZ')                                                                                                                              
In [12]: dt = pendulum.parse(date_str, tz='UTC')                                                                                                                                   
In [13]: dt                                                                                                                                                                        
Out[13]: DateTime(2018, 11, 15, 23, 23, 50, tzinfo=Timezone('+00:00'))
In [14]: dt.tz                                                                                                                                                                     
Out[14]: Timezone('+00:00')
In [15]: dt.is_utc()                                                                                                                                                               
Out[15]: False

In [20]: utc = pendulum.timezone('UTC')                                                                                                                                            
In [21]: dt = pendulum.parse(date_str, tz=utc)                                                                                                                                     
In [22]: dt.is_utc()                                                                                                                                                               
Out[22]: False
joaonc commented 6 years ago

@darrenleeweber Are you saying/asking something or simply demonstrating cases where it returns False when should be returning True? (ie, reproing the bug)

dazza-codes commented 6 years ago

Yes, reproducing the behavior in 1.5.1 vs 2.x is important for me (and possibly others landing here).

dazza-codes commented 6 years ago

295 seems to help with the logic in the is_utc() method, but that doesn't entirely resolve some concerns about the pendulum.parse() method and how it should behave, esp. when given an explicit timezone to apply. (Not entirely clear on the scope of this issue and whether this latter concern has broader scope and/or other issues address it.)

joaonc commented 6 years ago

My take is that the scope of this issue is the is_utc() method which, regardless of how the DateTime object was created, if the timzone has an offset of 0 (no offset, aka UTC), then is_utc() should return True, which hopefully now it does.