pytz adding extra minutes - datetime

What's the difference between US/Mountain and AZ timezone. Why is it adding an extra 28 min?
>>> strtime = datetime.datetime.strptime('10:00pm', '%I:%M%p')
>>> tz = timezone('US/Mountain').localize(strtime)
>>> print tz
1900-01-01 22:00:00-07:00
>>> tz = timezone(us.states.lookup('AZ').capital_tz).localize(strtime)
>>> print tz
1900-01-01 22:00:00-07:28 <<-----

this is most likely due to the fact that your year is 1900 (see also this question); it works fine if you add a current year:
import datetime
from pytz import timezone
import us
strtime = datetime.datetime.strptime('2020 10:00pm', '%Y %I:%M%p')
tz = timezone('US/Mountain').localize(strtime)
print(tz)
# 2020-01-01 22:00:00-07:00
tz = timezone(us.states.lookup('AZ').capital_tz).localize(strtime)
print(tz)
# 2020-01-01 22:00:00-07:00
(I'm using Python3 but that shouldn't make a difference, I get the same 28 min offset for year 1900)

Related

python 3.9.1 datetime arithmetic

While trying the new zoneinfo support in python3.9.1, I noticed that time differences of datetime aware objects differ from those produced by pytz as shown by the output of the below program:
import datetime,zoneinfo,pytz
from sys import version_info
print(f'Python{version_info.major}.{version_info.minor}{version_info.micro}'
f' pytz{pytz.__version__}')
Athens=zoneinfo.ZoneInfo('Europe/Athens')
f='%Y-%m-%d %H:%M:%S'
d=[datetime.datetime.strptime('2020-10-25 00:00:00',f),
datetime.datetime.strptime('2020-10-25 23:59:59',f)]
print('naive ',d[1]-d[0])
d=[x.astimezone(Athens) for x in d]
print('zoneinfo',d[1]-d[0])
d=[datetime.datetime.strptime('2020-10-25 00:00:00',f),
datetime.datetime.strptime('2020-10-25 23:59:59',f)]
athens=pytz.timezone('Europe/Athens')
print('pytz as ',d[1].astimezone(athens)-d[0].astimezone(athens))
print('pytz loc',athens.localize(d[1])-athens.localize(d[0]))
Python3.91 pytz2020.4
naive 23:59:59
zoneinfo 23:59:59
pytz as 1 day, 0:59:59
pytz loc 1 day, 0:59:59
It appears that the native timezone supports ignores the fact that 2020-10-25 was the day of changeover from summertime to winter time and therefore that day's duration was 25 hours.
What am I missing?
An illustration of my comment; aware datetime with tzinfo set with a ZoneInfo from zoneinfo returns a wall time timedelta. If you do the same with pytz.timezone aware datetime, you get absolute time timedelta.
from datetime import datetime
from zoneinfo import ZoneInfo
import pytz
from sys import version_info
print(f'Python {version_info.major}.{version_info.minor}{version_info.micro} pytz {pytz.__version__}')
# Python 3.90 pytz 2020.4
d=[datetime.fromisoformat('2020-10-25 00:00:00'), datetime.fromisoformat('2020-10-25 23:59:59')]
Athens = ZoneInfo('Europe/Athens')
print('wall time diff, zoneinfo:', d[1].replace(tzinfo=Athens)-d[0].replace(tzinfo=Athens))
# wall time diff, zoneinfo: 23:59:59
athens = pytz.timezone('Europe/Athens')
print('absolute time diff, pytz:', athens.localize(d[1])-athens.localize(d[0]))
# absolute time diff, pytz: 1 day, 0:59:59
# to get absolute time delta with zoneinfo:
utc = ZoneInfo('UTC')
print('absolute time diff, zoneinfo:', d[1].replace(tzinfo=Athens).astimezone(utc)
-d[0].replace(tzinfo=Athens).astimezone(utc))
# absolute time diff, zoneinfo: 1 day, 0:59:59

Why is the difference of two datetime.now() objects not close to 0?

I am confused about the output of the following code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import datetime
import pytz
local_time = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
utc_time = datetime.datetime.now(datetime.timezone.utc)
print(local_time - utc_time)
I thought a timezone is simply an offset (depending on factors such as the date and the location with DST and changing definitions over time... so not that simple, but still an offset). So a timezone-aware datetime I thought would simply be:
utc_time == '12:34'
+ timezone is Europe/Berlin in UTC 2018-01-01 at 12:34
=> local time = (utc + local timezone) = 2018-01-01 at 13:34
Then I thought, the difference between two datetime objects should be equal to the difference to the UTC at the same point in time (not considering the thought-construct of timezones).
Hence, if I execute "datetime.now" at (about) the same point in time and "assign" it to different time zones, the difference should be on the order of milliseconds that passed between the two commands.
But it actually is -1 day, 23:59:59.999982.
Found it; it's just a representation issue:
>>> print(local_time)
2018-03-13 14:01:14.973876+01:00
>>> print(utc_time)
2018-03-13 13:01:14.973899+00:00
>>> print(utc_time - local_time)
0:00:00.000023
>>> print(local_time - utc_time)
-1 day, 23:59:59.999977
>>> print((local_time - utc_time).total_seconds())
-2.3e-05
so it is -1 day + 23:59:59.999977

How can I create basic timestamps or dates? (Python 3.4)

As a beginner, creating timestamps or formatted dates ended up being a little more of a challenge than I would have expected. What are some basic examples for reference?
Ultimately you want to review the datetime documentation and become familiar with the formatting variables, but here are some examples to get you started:
import datetime
print('Timestamp: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()))
print('Timestamp: {:%Y-%b-%d %H:%M:%S}'.format(datetime.datetime.now()))
print('Date now: %s' % datetime.datetime.now())
print('Date today: %s' % datetime.date.today())
today = datetime.date.today()
print("Today's date is {:%b, %d %Y}".format(today))
schedule = '{:%b, %d %Y}'.format(today) + ' - 6 PM to 10 PM Pacific'
schedule2 = '{:%B, %d %Y}'.format(today) + ' - 1 PM to 6 PM Central'
print('Maintenance: %s' % schedule)
print('Maintenance: %s' % schedule2)
The output:
Timestamp: 2014-10-18 21:31:12
Timestamp: 2014-Oct-18 21:31:12
Date now: 2014-10-18 21:31:12.318340
Date today: 2014-10-18
Today's date is Oct, 18 2014
Maintenance: Oct, 18 2014 - 6 PM to 10 PM Pacific
Maintenance: October, 18 2014 - 1 PM to 6 PM Central
Reference link: https://docs.python.org/3.4/library/datetime.html#strftime-strptime-behavior
>>> import time
>>> print(time.strftime('%a %H:%M:%S'))
Mon 06:23:14
from datetime import datetime
dt = datetime.now() # for date and time
ts = datetime.timestamp(dt) # for timestamp
print("Date and time is:", dt)
print("Timestamp is:", ts)
You might want to check string to datetime operations for formatting.
from datetime import datetime
datetime_str = '09/19/18 13:55:26'
datetime_object = datetime.strptime(datetime_str, '%m/%d/%y %H:%M:%S')
print(type(datetime_object))
print(datetime_object) # printed in default format
Output:
<class 'datetime.datetime'>
2018-09-19 13:55:26

Python incorrectly extracting month from string [duplicate]

The month format specifier doesn't seem to work.
from datetime import datetime
endDate = datetime.strptime('10 3 2011', '%j %m %Y')
print endDate
2011-01-10 00:00:00
endDate = datetime.strptime('21 5 1987', '%j %m %Y')
print endDate
1987-01-21 00:00:00
Now, according to the manual the manual:
%m = Month as a decimal number [01,12].
So, what am I missing, other than the hair I've pulled out trying to understand why my django __filter queries return nothing (the dates going in aren't valid!)? I've tried 03 and 05 to no avail.
Versions of things, platform, architecture et al:
$ python --version
Python 2.7
$ python3 --version
Python 3.1.2
$ uname -r
2.6.35.11-83.fc14.x86_64 (that's Linux/Fedora 14/64-bit).
You can't mix the %j with others format code like %m because if you look in the table that you linked %j is the Day of the year as a decimal number [001,366] so 10 correspondent to the 10 day of the year so it's 01 of January ...
So you have just to write :
>>> datetime.strptime('10 2011', '%j %Y')
datetime.datetime(2011, 1, 10, 0, 0)
Else if you you wanted to use 10 as the day of the mount you should do :
>>> datetime.strptime('10 3 2011', '%d %m %Y')
datetime.datetime(2011, 3, 10, 0, 0)
Isn't %j the "day of year" parser, which may be forcing strptime to choose January 21, overriding the %m rule?
%j specifies a day of the year. It's impossible for the 10th day of the year, January 10, to occur in March, so your month specification is being ignored. Garbage In, Garbage Out.

Convert 12-hour date/time to 24-hour date/time

I have a tab delimited file where each record has a timestamp field in 12-hour format:
mm/dd/yyyy hh:mm:ss [AM|PM].
I need to quickly convert these fields to 24-hour time:
mm/dd/yyyy HH:mm:ss.
What would be the best way to do this? I'm running on a Windows platform, but I have access to sed, awk, perl, python, and tcl in addition to the usual Windows tools.
Using Perl and hand-crafted regexes instead of facilities like strptime:
#!/bin/perl -w
while (<>)
{
# for date times that don't use leading zeroes, use this regex instead:
# (?:\d{1,2}/\d{1,2}/\d{4} )(\d{1,2})(?::\d\d:\d\d) (AM|PM)
while (m%(?:\d\d/\d\d/\d{4} )(\d\d)(?::\d\d:\d\d) (AM|PM)%)
{
my $hh = $1;
$hh -= 12 if ($2 eq 'AM' && $hh == 12);
$hh += 12 if ($2 eq 'PM' && $hh != 12);
$hh = sprintf "%02d", $hh;
# for date times that don't use leading zeroes, use this regex instead:
# (\d{1,2}/\d{1,2}/\d{4} )(\d{1,2})(:\d\d:\d\d) (?:AM|PM)
s%(\d\d/\d\d/\d{4} )(\d\d)(:\d\d:\d\d) (?:AM|PM)%$1$hh$3%;
}
print;
}
That's very fussy - but also converts possibly multiple timestamps per line.
Note that the transformation for AM/PM to 24-hour is not trivial.
12:01 AM --> 00:01
12:01 PM --> 12:01
01:30 AM --> 01:30
01:30 PM --> 13:30
Now tested:
perl ampm-24hr.pl <<!
12/24/2005 12:01:00 AM
09/22/1999 12:00:00 PM
12/12/2005 01:15:00 PM
01/01/2009 01:56:45 AM
12/30/2009 10:00:00 PM
12/30/2009 10:00:00 AM
!
12/24/2005 00:01:00
09/22/1999 12:00:00
12/12/2005 13:15:00
01/01/2009 01:56:45
12/30/2009 22:00:00
12/30/2009 10:00:00
Added:
In What is a Simple Way to Convert Between an AM/PM Time and 24 hour Time in JavaScript, an alternative algorithm is provided for the conversion:
$hh = ($1 % 12) + (($2 eq 'AM') ? 0 : 12);
Just one test...probably neater.
It is a 1-line thing in python:
time.strftime('%H:%M:%S', time.strptime(x, '%I:%M %p'))
Example:
>>> time.strftime('%H:%M:%S', time.strptime('08:01 AM', '%I:%M %p'))
'08:01:00'
>>> time.strftime('%H:%M:%S', time.strptime('12:01 AM', '%I:%M %p'))
'00:01:00'
Use Pythons datetime module someway like this:
import datetime
infile = open('input.txt')
outfile = open('output.txt', 'w')
for line in infile.readlines():
d = datetime.strptime(line, "input format string")
outfile.write(d.strftime("output format string")
Untested code with no error checking. Also it reads the entire input file in memory before starting.
(I know there is plenty of room for improvements like with statement...I make this a community wiki entry if anyone likes to add something)
To just convert the hour field, in python:
def to12(hour24):
return (hour24 % 12) if (hour24 % 12) > 0 else 12
def IsPM(hour24):
return hour24 > 11
def to24(hour12, isPm):
return (hour12 % 12) + (12 if isPm else 0)
def IsPmString(pm):
return "PM" if pm else "AM"
def TestTo12():
for x in range(24):
print x, to12(x), IsPmString(IsPM(x))
def TestTo24():
for pm in [False, True]:
print 12, IsPmString(pm), to24(12, pm)
for x in range(1, 12):
print x, IsPmString(pm), to24(x, pm)
This might be too simple thinking, but why not import it into excel, select the entire column and change the date format, then re-export as a tab delimited file? (I didn't test this, but it somehow sounds logical to me :)
Here i have converted 24 Hour system to 12 Hour system.
Try to use this method for your problem.
DateFormat fmt = new SimpleDateFormat("yyyyMMddHHssmm");
try {
Date date =fmt.parse("20090310232344");
System.out.println(date.toString());
fmt = new SimpleDateFormat("dd-MMMM-yyyy hh:mm:ss a ");
String dateInString = fmt.format(date);
System.out.println(dateInString);
} catch (Exception e) {
System.out.println(e.getMessage());
}
RESULT:
Tue Mar 10 23:44:23 IST 2009
10-March-2009 11:44:23 PM
In Python: Converting 12hr time to 24hr time
import re
time1=input().strip().split(':')
m=re.search('(..)(..)',time1[2])
sec=m.group(1)
tz=m.group(2)
if(tz='PM'):
time[0]=int(time1[0])+12
if(time1[0]=24):
time1[0]-=12
time[2]=sec
else:
if(int(time1[0])=12):
time1[0]-=12
time[2]=sec
print(time1[0]+':'+time1[1]+':'+time1[2])
Since you have multiple languages, I'll suggest the following algorithm.
1 Check the timestamp for the existence of the "PM" string.
2a If PM does not exist, simply convert the timestamp to the datetime object and proceed.
2b If PM does exist, convert the timestamp to the datetime object, add 12 hours, and proceed.

Resources