tnknepp wrote:All of this behind-the-scenes time zone shifting is frustrating and confusing. It would make more sense to just convert time to seconds, datetime, etc. without trying to "fix" the locale/UTC offset.
There is no actual "conversion" taking place. A timestamp does not have time zone information -- it's literaly just a float that is the number of seconds since Epoc. gm functions just assume UTC, becuase that's what they are for. If you don't want UTC, don't use gm functions. If you want your local time zone, you can use localtime function instead; for other time zones, you'll have to attach time zone information manually.
The easiest way to work with dates in various timezones is to parse the dates/times into datetime objects, e.g. using datetime.strptime. If the time zone is not parsed as a part of that, the resulting object will be "naive", i.e. not aware of the time zone. You will then have to attach time zone information manually by providing it with an appropriate tzinfo object. That is what pytz is for. Once your datetime objects are time zone aware, they will behave correctly and you can use them around your program.
The problem is that you may eventually have to do something that loses the time zone information. E.g. you might have to pass the datetime into an API that expects a Unix time stamp; or you might have to persist it in a format that does not support time zone information. If that happens, you will have to track tz info separately and that will quickly become very confusing and error prone. That is why if you have
to deal with multiple time zones, the best practice is to convert everything
to UTC and always work with that internally in your program and convert into your local (or whatever) time zone at the last possible moment (this is similar to working with unicode and encodings).