0

Hi, I am trying to write a simple script that reads a file for two time stamps and then finds the delta. However, I can't get passed converting the time strings to datetime objects. I haven't done any coding since college and I everything I've read says this code should work. I am getting nowhere.

I am sure there are much more efficient ways to do this but right now I just want it to work.

I removed some of the code not related to the problem to make it less confusing.

from datetime import datetime

# Open file
f = open('Carolina_PMs.txt', 'r')
# Read and ignore header lines
header1 = f.readline()
# Loop over file to read lines and extract times/labor hours
for line in f:
    line = line.strip()
    # Split text in file into columns
    columns = line.split()
    # Split certain columns from above into more columns based on " symbol to get labor i.e. 0.5 hours
    splitStart = columns[8].split('"')
    splitEnd = columns[10].split('"')
    # Extract start and end times as strings, then add AM/PM
    extractStartTime = columns[7]
    extractEndTime = columns[9]
    startTime = extractStartTime + " " + splitStart[0]
    endTime = extractEndTime + " " + splitEnd[0]
    # Convert strings to datetime objects
    start = datetime.strptime(startTime, '%I:%M%p')
    end = datetime.strptime(endTime, '%I:%M%p')

f.close()

The strings stored in startTime and endTime look like this:

print(startTime, endTime)
01:11 PM 01:41 PM

And here is the error I get:

Traceback (most recent call last):
  File "C:/Users/intermed/PycharmProjects/Clarify/Clarify.py", line 24, in <module>
    start = datetime.strptime(startTime, '%I:%M%p')
  File "C:\Users\intermed\AppData\Local\Programs\Python\Python36\lib\_strptime.py", line 565, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "C:\Users\intermed\AppData\Local\Programs\Python\Python36\lib\_strptime.py", line 362, in _strptime
    (data_string, format))
ValueError: time data '01:11 PM' does not match format '%I:%M%p'

Edited by long5001

3
Contributors
10
Replies
65
Views
8 Months
Discussion Span
Last Post by long5001
Featured Replies
  • Hi, Until someone who knows Python gets here... > ValueError: time data '01:11 PM' does not match format '%I:%M%p' Perhaps it's because `01:11 PM` has a space and `%I:%M%p` doesn't. Maybe try `%I:%M %p`? Because from the [official page](https://docs.python.org/3/library/datetime.html#datetime.datetime.__format__): > `dt.strftime("%A, %d. %B %Y %I:%M%p")` 'Tuesday, 21. November 2006 04:30PM' Read More

  • I don't know if I can answer, but it would help others as well if you could post an example of a line that you're trying to parse. In the [documentation page ](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) regarding `strptime` it states that `%p` is locale dependent. > Locale’s equivalent of either AM or PM. … Read More

  • You can edit within the hour, after that it's locked. The only other guess I had was that the splitting had gone wrong, but since you've printed those variables that's probably not it. If you change `columns = line.split()` (which splits on space) to `columns = line.split('|')` you would have … Read More

  • You can convert a datetime string to a datetime value as long as you properly match the [format of the string](https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior). For example import datetime t1 = "02/11/2017 10:43 AM" t2 = "02/27/2017 01:11 PM" d1 = datetime.datetime.strptime(t1, "%m/%d/%Y %H:%M %p") d2 = datetime.datetime.strptime(t2, "%m/%d/%Y %H:%M %p") dsec = (d2 … Read More

  • By the way, if you are just working with time strings you get >>> datetime.datetime.strptime("01:23 PM","%H:%M %p") datetime.datetime(1900, 1, 1, 1, 23) It defaults the date to `1900-01-01` which shouldn't be a problem if you are just interested in differences. You also might want to do an abs in case … Read More

1

Hi,

Until someone who knows Python gets here...

ValueError: time data '01:11 PM' does not match format '%I:%M%p'

Perhaps it's because 01:11 PM has a space and %I:%M%p doesn't. Maybe try %I:%M %p?

Because from the official page:

dt.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'

0

Thanks for the response Traevel! I tried that and I tried removing the space I inserted farther up - the code executes but the AM/PM on the timestamp is left out and :00 seconds is added on erroneously.

1

I don't know if I can answer, but it would help others as well if you could post an example of a line that you're trying to parse.

In the documentation page regarding strptime it states that %p is locale dependent.

Locale’s equivalent of either AM or PM.
AM, PM (en_US);
am, pm (de_DE)

Other than that I have no new ideas, sorry.

0

Thanks for the suggestion. I can't seem to edit the main post anymore, so here is one line of the raw text I am reading from:

"SCHEDULED PM"|"Trident Medical Center"|"186721"|"401321175"|"12577131"|"PM-Preventive Maintenance"|"48"|"02/11/2017 10:43 AM"|"02/27/2017 01:11 PM"|"19"|"02/27/2017 01:41 PM"|"0.50"|"TIME"|"L"|""|""|"0"|""|"Syringe Module - Next Scheduled Date: 02/11/2018"|"PM CMPLT BY OEM/VENDOR/DEPOT-Performed a full PM and Basic function check with visual inspection. No Problems found, returning to service. Used Alaris PM Kit."|"0"|"Internal"|"VEND2201"

Edited by long5001

1

You can edit within the hour, after that it's locked.

The only other guess I had was that the splitting had gone wrong, but since you've printed those variables that's probably not it. If you change columns = line.split() (which splits on space) to columns = line.split('|') you would have all the columns in the proper place, but you've already worked that bit out by adjusting and recombining the columns.

1

You can convert a datetime string to a datetime value as long as you properly match the format of the string. For example

import datetime

t1 = "02/11/2017 10:43 AM"
t2 = "02/27/2017 01:11 PM"

d1 = datetime.datetime.strptime(t1, "%m/%d/%Y %H:%M %p")
d2 = datetime.datetime.strptime(t2, "%m/%d/%Y %H:%M %p")

dsec = (d2 - d1).total_seconds()
dmin = dsec / 60

print(t1,t2)
print(d1,d2)
print(dsec)
print(dmin)

results in

02/11/2017 10:43 AM 02/27/2017 01:11 PM
2017-02-11 10:43:00 2017-02-27 01:11:00
1348080.0
22468.0
1

By the way, if you are just working with time strings you get

>>> datetime.datetime.strptime("01:23 PM","%H:%M %p")
datetime.datetime(1900, 1, 1, 1, 23)

It defaults the date to 1900-01-01 which shouldn't be a problem if you are just interested in differences. You also might want to do an abs in case t2 < t1.

Edited by Reverend Jim

0

Ok, I am getting somewhere now. Thank you both for your help.

What if I also want to compare this delta to an integer? For example: the difference between the start time and end time is 00:35:00 and the engineer put that he spent 30 minutes on the job. How do I compare the time object delta vs the stated time? I tried converting that to a time object but since it's just 0.50 in the raw text it wouldn't accept it.

1

Either

if (int(dmin) - 30)

or

dmin = int(dsec / 60)
if (dmin = 30)

as for 0.50, I don't know what that represents. What are the units? Is that half a minute, half an hour or half a day?

0

I think I figured it out! I cleaned it up a little bit, but I'm sure it can still be optimized.

Here is what I ended up with:

import datetime
import math

# Open file
f = open('Pensacola_PMs_test.txt', 'r')
# Read and ignore header lines
header1 = f.readline()
# Loop over file to read lines and extract times/labor hours
for line in f:
    line = line.strip()
    # Split text in file into columns
    columns = line.split("|")
    # Further split columns into more columns
    c = columns[8].split('"')
    c1 = c[1].split()
    e = columns[10].split('"')
    e1 = e[1].split()
    # Extract start and end times as strings, then add AM/PM
    extractStartTime = c1[1]
    extractEndTime = e1[1]
    startTime = extractStartTime + " " + c1[2]
    endTime = extractEndTime + " " + e1[2]
    # Convert strings to datetime
    start = datetime.datetime.strptime(startTime, "%I:%M %p")
    end = datetime.datetime.strptime(endTime, "%I:%M %p")
    # Extract labor percentage i.e. 0.5 hours
    labor = columns[11].split('"')
    l = labor[1]
    # Get difference in start and end times
    delta = end - start
    # Convert timedelta to float
    d_float = delta.total_seconds()
    # Convert float to int for comparison with stated labor; divide seconds by 60 to get total minutes
    d_minutes = int(d_float / 60)
    # Convert string to float
    laborFloat = float(l)
    # Convert float percentage to actual minutes
    laborMinutes = laborFloat * 60
    # Convert float to int
    laborTime = int(math.floor(laborMinutes))
    # Compare elapsed time to stated time and check for tolerances.
    if d_minutes < laborTime:
        print("Elapsed time is less than stated time")
    elif d_minutes >= laborTime and d_minutes <= (d_minutes + laborTime) + 5:
        print("Ok")
    else:
        print("Time needs adjustment")

f.close()

I'm also going to add a counter to the loop that will print out the line number with the results.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.