3

When I use msg.SentOn.stftime("%Y-%m-%d %H:%M:%S %Z %z %p") I get GMT as timezone however all the message times are in IST for example an email sent at 1.30PM IST shows 2017-09-19 13:30:51 GMT+00:00 +000. However what I want is 2017-09-19 09:00:51 GMT+00:00 +000. The code is as below

import datetime, win32com.client as win32

outlook = win32.Dispatch("Outlook.Application").GetNamespace("MAPI")
excel = win32.gencache.EnsureDispatch("Excel.Application")

inbox = outlook.GetDefaultFolder(6) 

for msg in inbox.Items:
    print(msg.SentOn.strftime("%Y-%m-%d %H:%M:%S %Z %z %p"), msg.Subject)
Ethan Field
  • 4,646
  • 3
  • 22
  • 43
Swadesh
  • 31
  • 3
  • Welcome to SO! Your question is very unclear and you haven't provided us with an MCVE (https://stackoverflow.com/help/mcve) so we don't know enough about the specifics of your question. Please can you amend this so that we can help you. – Ethan Field Sep 19 '17 at 09:27
  • I can confirm what the OP was seeing. The `SentOn` property returns a timezone aware `datetime` with `tzinfo` set to UTC. However, the time component contains the local time when the message was sent. For example, I have a message that was sent at 17:00:16 central daylight time. `SentOn` returns `17:00:16+00:00` instead of `22:00:16+00:00` or `17:00:16-05:00`. I think the OP wanted to fudge the time back to the correct value. – bigh_29 Jun 28 '19 at 17:46
  • @bigh_29 did you find a way to solve this then? If so, you could leave an answer for anyone that stumbles over this question. – Ethan Field Jun 30 '19 at 09:05
  • @EthanField added – bigh_29 Jul 01 '19 at 14:10

2 Answers2

2

This is actually a lot easier than I thought it would be.

Python has a library called pytz which can be used in conjunction with datetime to allow for easy timezone conversions.

This can be done by using .astimezone(pytz.timezone([TIMEZONE])), substituting [TIMEZONE] with whatever timezone you need from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List

Please see my example below which sets the timezone of the sent time on the message to America/Los_Angeles:

import datetime, pytz, win32com.client as win32

outlook = win32.Dispatch("Outlook.Application").GetNamespace("MAPI")
excel = win32.gencache.EnsureDispatch("Excel.Application")

inbox = outlook.GetDefaultFolder(6) 

for msg in inbox.Items:
    print(msg.SentOn.astimezone(pytz.timezone('America/Los_Angeles')).strftime("%Y-%m-%d %H:%M:%S %Z %z %p"), msg.Subject)
Ethan Field
  • 4,646
  • 3
  • 22
  • 43
  • Ethan, thanks. Still no luck! I am not sure whats causing this issue. The time zone should be IST when I print it as the message sent date time stamp is in IST. The UTC time is 4 and a half hours behind us so timestamp should be different than what I see, however it is 2017-09-20 11:49:51 UTC +0000 AM – Swadesh Sep 20 '17 at 07:46
  • The modified code snippet is import datetime, pytz, win32com.client as win32 outlook = win32.Dispatch("Outlook.Application").GetNamespace("MAPI") inbox = outlook.GetDefaultFolder(6) # Default inbox folder for msg in inbox.Items: sent_tm = msg.SentOn.astimezone(pytz.timezone('UTC')) print(sent_tm.strftime("%Y-%m-%d %H:%M:%S %Z %z %p"), msg.Subject) – Swadesh Sep 20 '17 at 07:48
  • I'm confused, judging by what you're doing in this comment you should be printing the UTC time that each email was sent, if this isn't the time zone you want to use then replace it with another? – Ethan Field Sep 20 '17 at 09:13
  • Exactly that is not happening, the %Z part returns UTC however the %Y-%m-%d %H:%M:%S is still the local Indian time, so do I need to do some other logic to convert the date time to UTC, cause the above piece just changed the TImeZone. I dont think subtracting 5 Hrs 30 Min can help as we have to use 6 or 7 zones. I hope that clarifies things a bit – Swadesh Sep 20 '17 at 10:21
  • I can assure you that this is updating the time correctly. For example I have an email that I received at 14:10 yesterday and I have set the timezone option in the snippet to `America/Los_Angeles` and the snippet prints that the received time was 07:10 PDT -0700 AM. The snippet I have provided you will convert the time the email was sent into whatever timezone you provide it. – Ethan Field Sep 20 '17 at 10:24
  • OK thank you so much. I will try to figure out from the above. – Swadesh Sep 21 '17 at 06:15
  • I and my colleagues work in different countries. So physically adding local = pytz.timezone("Europe\London") does not solve the problem. Because when I run the code lets say from India its going to take current indian time to GMT time and then covert it to UTC. Precisely the problem comes if a a file received at 23:30 GMT on 1st Feb when I see my outlook, the email I will see received at 4AM IST. (please see next comment) – Swadesh Feb 08 '18 at 20:04
  • If I use "Europe/London as the local timezone then python will take 4AM on 2nd Feb as the GMT time and converts it to UTC which is 2nd Feb instead of 1st. Is there a way to make the script ...take local time irrespective of timezone they are run from. – Swadesh Feb 08 '18 at 20:05
  • The script I provided simply converts the time to whichever timezone you give it. All you need to do is enter the timezone you wish to display the time/date as and it will print the conversion. The time on your machine or your Outlook will not affect this. – Ethan Field Feb 09 '18 at 12:52
1

I fixed the timezone of message.SentOn with this code.

from datetime import datetime
import pytz

def fix_timezone(dt):
    local_tz = dt.astimezone().tzinfo # is there a cleaner way to get the local tz?
    shifted = dt.replace(tzinfo=local_tz)
    return shifted.astimezone(pytz.utc)

wrong_time = datetime(2019, 6, 1, 17, 0, 16, tzinfo=pytz.utc)
correct_time_utc = fix_timezone(wrong_time)
print(correct_time_utc)

I tried to find a cleaner way to get the timezone of the local computer, but was not happy with anything I found. I just steal it from the return value of astimezone()

bigh_29
  • 2,529
  • 26
  • 22