datetime module is not working properly on vps

94 views Asked by At

my code works properly in local machine:

from datetime import datetime
import pytz
def convert_time(timestamp):
      formats = ['%a, %d %b %Y %H:%M:%S %Z',
        '%a, %d %b %Y %H:%M:%S %z',
        '%Y-%m-%dT%H:%M:%S.%fZ']
      for fmt in formats:
        try:
          dt = datetime.strptime(timestamp, fmt)
          break
        except ValueError as v:
          print(v)
          pass
      utc_dt = dt.astimezone(pytz.UTC)
      return str(utc_dt.strftime('%Y-%m-%d %H:%M:%S'))
print(convert_time("Mon, 04 Dec 2023 06:13:24 EDT"))

this code is for converting my date format to UTC format. For Example this format will convert as i expected:

"Thu, 01 Nov 2018 16:50:27 EDT"

and the output will be:

2018-11-01 20:50:27

but when i run this code on my vps i got this error:

time data 'Thu, 01 Nov 2018 16:50:27 EDT' does not match format ...

what should i do? this is what i ran in my local machine this is what i ran in my local machine

And this is what i ran in my VPS And this is what i ran in my VPS

2

There are 2 answers

3
furas On

I added print() in code and it shows that %Z doesn't parse EDT nor EST.
So you have to add %a, %d %b %Y %H:%M:%S EDT'


Full code which I used to test it:

from datetime import datetime

def convert_timestamp(timestamp):
    print(timestamp)
    
    formats = ['%a, %d %b %Y %H:%M:%S %Z',
               '%a, %d %b %Y %H:%M:%S %z',
               '%a, %d %b %Y %H:%M:%S EST',
               '%Y-%m-%dT%H:%M:%S.%fZ']
               
    for fmt in formats:
        try:
            dt = datetime.strptime(timestamp, fmt)
            print('     OK:', fmt)
            break
        except ValueError:
            print('  error:', fmt)
            pass
            
    utc_dt = dt.astimezone(pytz.UTC)
    
    return str(utc_dt.strftime('%Y-%m-%d %H:%M:%S'))

# --- test ---

examples = [
    "Thu, 01 Nov 2018 16:50:27 EDT", 
    "Thu, 01 Nov 2018 16:50:27 EST", 
    "Thu, 01 Nov 2018 16:50:27 UTC",
    "Thu, 01 Nov 2018 16:50:27 -0400",  # EDT
    "Thu, 01 Nov 2018 16:50:27 -0500",  # EST
]

for item in examples:
    try:
        convert_timestamp(item)    
    except:
        pass

Result:

Thu, 01 Nov 2018 16:50:27 EDT
  error: %a, %d %b %Y %H:%M:%S %Z
  error: %a, %d %b %Y %H:%M:%S %z
  error: %a, %d %b %Y %H:%M:%S EST
  error: %Y-%m-%dT%H:%M:%S.%fZ
Thu, 01 Nov 2018 16:50:27 EST
  error: %a, %d %b %Y %H:%M:%S %Z
  error: %a, %d %b %Y %H:%M:%S %z
     OK: %a, %d %b %Y %H:%M:%S EST
Thu, 01 Nov 2018 16:50:27 UTC
     OK: %a, %d %b %Y %H:%M:%S %Z
Thu, 01 Nov 2018 16:50:27 -0400
  error: %a, %d %b %Y %H:%M:%S %Z
     OK: %a, %d %b %Y %H:%M:%S %z
Thu, 01 Nov 2018 16:50:27 -0500
  error: %a, %d %b %Y %H:%M:%S %Z
     OK: %a, %d %b %Y %H:%M:%S %z
1
Malcolm On

The problem (and the disconnect between the behavior between locally and on the VPS) is that datetime.strptime's %Z format only recognizes GMT, UTC, and the local timezones specified in time.tzname. So if you are in the US Eastern Time timezone, then the datetime.strptime%Z will recognize EDT and EST, but if you are in another timezone, it will not. For reference see note #6 in this documentation https://docs.python.org/3/library/datetime.html#technical-detail.

Part of the reason for this is that timezone abbreviations are not unique. For example, CST can be China Standard Time or Central Standard Time. So, a universal parser is not possible.

I would suggest using the dateutil.parser (https://dateutil.readthedocs.io/en/stable/parser.html) as it provides a general mechanism for identifying the timezone names you want to be able to handle.

>>> from dateutil import parser
>>> tzinfos = {'EDT': -4*3600, 'EST': -5*3600}
>>> dateutil.parser.parse("Thu, 01 Nov 2018 16:50:27 EDT", tzinfos=tzinfos)
datetime.datetime(2018, 11, 1, 16, 50, 27, tzinfo=tzoffset('EDT', -14400))
>>>