Python Forum

Full Version: Modifying a date format
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I have some QIF data in a file, and the 'Date" record needs modifying. The Dates are of the format

D4/7'2004

and they need to be changed to

D04/07/2004

f = open("ANCU.qif","r")
lines = f.readlines()

for line in lines:
    first_char = line[0]

    if(first_char == "D"):
        print("Found a date record")
        print(first_char)
        new_line = line.replace("'","/")
        parts = new_line.split("/",2)
        print(parts)
        new = "/".join(parts)
        print(new)
    else:
        print("Nope")
        print(first_char)

# closing the file
f.close()
is producing ..

Quote:Found a date record
D
['D6', '30', '2005\n']
D6/30/2005

Nope
C
Nope
T
Nope
P
Nope
L
Nope
^
Found a date record
D
['D7', '7', '2005\n']
D7/7/2005

Nope
C
Nope
M
Nope
T
Nope
P
Nope
L
Nope
^

so the code is nearly there. The dates are in MM/DD/YYYY format. The rules for the code need to be if the MM or DD is a length of one char, then add the leading zero. Also I assume the \n is a carriage return or line feed to indicate a record separation.

I also need to write a new file with only the date records modified, so that needs to be added in wherever the print statements are, or similar.
You could use datetime.

https://docs.python.org/3/library/dateti...e-behavior
from datetime import datetime

lines = (
    "D4/7'2004\n",
    "D4/17'2004\n",
    "not a date\n",
    "D11/7'2005\n",
    "D11/17'2004\n",
)

for line in lines:
    if line[0] == "D":
        line = line.strip()[1:]  # Get rid of D and trailing whitespace
        date = datetime.strptime(line, "%m/%d'%Y")  # Convert to DateTime
        line = "D"+date.strftime('%m/%d/%Y')  # Convert back to string
        print(line)
Output:
D04/07/2004 D04/17/2004 D11/07/2005 D11/17/2004
Or you could use re.split() and a string formatter. This example uses f"string style formatting.
import re

lines = (
    "D4/7'2004\n",
    "D4/17'2004\n",
    "not a date\n",
    "D11/7'2005\n",
    "D11/17'2004\n",
)

for line in lines:
    if line[0] == "D":
        line = line.strip()[1:] # Remove D and trailing whitespace
        d, m, y = re.split("/|'", line)  # Split into month, day and year
        line = f"D{m:>02}/{d:>02}/{y}"  # Pad month and day with leading 0 if needed
        print(line)
Output:
D07/04/2004 D17/04/2004 D07/11/2005 D17/11/2004
Is this the kind of thing you're looking for?

date_list = ['D4', '7', '2004\n']  # a data sample

for index, item in enumerate(date_list):
    if index == 0:
        month = item.lstrip("D")
        month = "D" + str(f"{int(month):02d}")
    elif index == 1:
        day = str(f"{int(item):02d}")
    else:
        year = item.rstrip("\n")

date = f"{month}/{day}/{year}"
print(date)
Output:
D04/07/2004
(Oct-27-2022, 08:53 PM)deanhystad Wrote: [ -> ]You could use datetime.

Thank you, both solutions worked perfectly. I only had to make a small mod to the second solution ..

d, m, y = re.split("/|'", line)  # Split into month, day and year
to

m, d, y = re.split("/|'", line)  # Split into month, day and year
another solution using built-in date methods:
import datetime

def convert_date(orig):
    massaged_date = orig.replace("'", "/")[1:]
    return datetime.datetime.strftime(datetime.datetime.strptime(massaged_date, "%m/%d/%Y"), "%m/%d/%Y")

def testit():
    orig_date = "D4/7'2004"
    finaldate = f"D{convert_date(orig_date)}"
    print(f"{finaldate}")

testit()
results of test:
Output:
D04/07/2004
(Oct-27-2022, 08:59 PM)rob101 Wrote: [ -> ]Is this the kind of thing you're looking for?

Thank you. I tried to incorporate the code you supplied and have it process the file

from datetime import datetime

f = open("ANCU.qif","r")
lines = f.readlines()

for line in lines:

    for index, item in enumerate(line):
        if index == 0:
            month = item.lstrip("D")
            month = "D" + str(f"{int(month):02d}")
        elif index == 1:
            day = str(f"{int(item):02d}")
        else:
            year = item.rstrip("\n")

date = f"{month}/{day}/{year}"
print(date)

# closing the file
f.close()
Output:
python3 search_replace_2.py Traceback (most recent call last): File "/home/********/VirtualBox VMs/search_replace_2.py", line 12, in <module> month = "D" + str(f"{int(month):02d}") ValueError: invalid literal for int() with base 10: '!'
but obviously a string data type problem.
(Oct-27-2022, 09:57 PM)Larz60+ Wrote: [ -> ]another solution using built-in date methods:

Thank you. I included this to parse through the file, and the output looks just fine.

import datetime

def convert_date(orig):
    massaged_date = orig.replace("'", "/")[1:]
    return datetime.datetime.strftime(datetime.datetime.strptime(massaged_date, "%m/%d/%Y"), "%m/%d/%Y")

def testit(orig_date):
    finaldate = f"D{convert_date(orig_date)}"
    print(f"{finaldate}")


f = open("ANCU.qif","r")
lines = f.readlines()

for line in lines:

    if line[0] == "D":
        date_record = line.strip()
        testit(date_record)
    else:
        line = line.strip()
        print(line)

# closing the file
f.close()
I'm not that familiar with the scope of variables in Python, so assumed I have to call the variable a different name (.i.e var date_record) to the name it is defined as in the function testit().
You don't need testit.
try this (as I cannot test):
import datetime
 
def convert_date(orig):
    massaged_date = orig.replace("'", "/")[1:]
    return f"D{datetime.datetime.strftime(datetime.datetime.strptime(massaged_date, "%m/%d/%Y"), "%m/%d/%Y")}"

def clean_file(filename):
    with open(filename,"r") as f: 
        line = f.readline().strip()
 
        if line[0] == "D":
            convert_date(line)
        else:
            print(line)

clean_file("ANCU.qif")
line 11 could also read:
if line.startswith("D"):
(Oct-28-2022, 03:42 AM)jehoshua Wrote: [ -> ]Thank you. I tried to incorporate the code you supplied and have it process the file...

You're welcome.

The code I posted is designed to iterate over the list object that is returned by lines = f.readlines(), but you've introduced another for loop, which unpacks said list, which is why if fails.

There are other solutions here which may very well work for you, but if not, I'm sure I could modify my script; indeed, I'm sure you could also do that, if needed.



To add...

As I had 10 mins spare, I've come up with a possible solution:

def format_date(date):
    for index, item in enumerate(date):
        if index == 0:
            month = item.lstrip("D")
            month = "D" + str(f"{int(month):02d}")
        elif index == 1:
            day = str(f"{int(item):02d}")
        else:
            year = item.rstrip("\n")

    return f"{month}/{day}/{year}"


lines = ['D7', '7', '2005\n']  # a data sample

for line in lines:
    if line[0] == 'D':
        date = format_date(lines)
    continue

print(date)
import datetime


input_format = "D%d/%m'%Y"
output_format = "%d/%m/%Y"

datetime.datetime.strptime("D4/7'2004", input_format).strftime(output_format)
Pages: 1 2