3


I have a text file with rows like this..

(datetime.datetime(2017, 1, 1, 4, 16), 0.17799999999999999)
(datetime.datetime(2017, 1, 1, 4, 26), 0.20000000000000001)
(datetime.datetime(2017, 1, 1, 4, 36), 0.17699999999999999)

Ultimately I want to read in the data and plot the date against the value, but I'm currently stuck on just getting the data read.

So far I have

f=open('data.txt', 'r')
for line in f:
    line = line.strip()
    columns = line.rsplit(',',1)                                                                                                                             
    date=columns[0][1:]
    print(date)

Sample output:

datetime.datetime(2017, 1, 1, 4, 36)

But I would like it to print as a date e.g. 20170101 04:36:00 (or similar)
I don't know how to get the datetime object to to get recognized as such, and display as a real date string. If I google it I see loads of info on turning a string to a datetime object but nothing for the other way round.

Many thanks in advance.

Devesh Kumar Singh
  • 20,259
  • 5
  • 21
  • 40
holpot
  • 33
  • 7
  • So your file actually has raw datetetime objects saved as a string like `(datetime.datetime(2017, 1, 1, 4, 16), 0.17799999999999999)` – Devesh Kumar Singh Apr 27 '19 at 11:58
  • Yes that's right. It gets pulled from a database that way. (Im struggling to format these comments!) – holpot Apr 27 '19 at 12:18
  • 2
    Why are you pulling from the database and saving it to a txt file? Instead of pulling these directly and processing them? – Devesh Kumar Singh Apr 27 '19 at 12:20
  • We have to keep database interaction to a minimum, so I was just going to pull all the data in one dump then not have to touch the db again. – holpot Apr 27 '19 at 12:27
  • How are you pulling from data and pushing to txt, you know you can save the datetime object as a string right? – Devesh Kumar Singh Apr 27 '19 at 12:35

5 Answers5

3

The contents of the text file in your example is valid Python syntax, so if you are sure this format is correct, and the data is under your own control, you could just evaluate the lines. (Note that this is a security risk if the data can be manipulated by others, so this may or may not be a good solution depending on your use case.)

import datetime

with open('data.txt', 'r') as file:  # Tip: use context manager to avoid resource leak
    for line in file:
        line = line.strip()
        date = eval(line)[0]  # evaluate line as Python code and get first element
        print(date.strftime('%Y%m%d %H%M'))  # print date/time in preferred format
wovano
  • 4,543
  • 5
  • 22
  • 49
  • I was writing the exactly same answer and wondering why the others were not simply ```eval()``` the string. :-) – accdias Apr 27 '19 at 12:49
0

You can use regex to extract the integers from the datetime part of the string and use these to create a datetime object. You can then manipulate the datetime object as you please to print the desired output:

import re
from datetime import datetime

regex_match = re.match(r'.*?(\d+), (\d+), (\d+), (\d+), (\d+).*', 'datetime.datetime(2017, 1, 1, 4, 36)').groups()
d = datetime(*[int(i) for i in regex_match])

And you can then choose how to print this:

>> d = datetime(2017, 1, 1, 4, 16)
>> print(d.isoformat())
.. 2017-01-01T04:16:00

Or with more control over printing:

>> d.strftime("%Y%m%d %H:%M:%S")
.. '20170101 04:16:00'

So in your code it is:

f=open('data.txt', 'r')
for line in f:
    line = line.strip()
    columns = line.rsplit(',',1)                                                                                                                             
    date=columns[0][1:]
    regex_match = re.match(r'.*?(\d+), (\d+), (\d+), (\d+), (\d+).*', date).groups()
    d = datetime(*[int(i) for i in regex_match])
    print(d.strftime("%Y%m%d %H:%M:%S"))

Once you have the datetime object, you can also use matplotlib (you referenced wanting to plot this) to convert a datetime object to a readable string (ref: Plotting dates on the x-axis with Python's matplotlib):

import matplotlib.pyplot as plt
your_datetime_array = [(datetime.datetime(2017, 1, 1, 4, 16), 0.17799999999999999),
(datetime.datetime(2017, 1, 1, 4, 26), 0.20000000000000001),
(datetime.datetime(2017, 1, 1, 4, 36), 0.17699999999999999)]

x = [tup[0] for tup in your_datetime_array]
y = [tup[1] for tup in your_datetime_array]

plt.xticks(rotation=-45) # rotate them if you want
ax = plt.gca()
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M'))

plt.plot(x, y)
plt.show()

Note that changing the '%Y-%m-%d %H:%M' string will change the format that is plotted.

nick
  • 1,310
  • 8
  • 15
  • Thanks, I gave that a try. Now I get the error AttributeError: 'str' object has no attribute 'strftime' – holpot Apr 27 '19 at 12:20
  • And you definitely have the line: `d = datetime.datetime(*[int(i) for i in regex_match])` before `d.strftime("%Y%m%d %H:%M:%S")`? Note the "d" and not "date" as in your original code. "date" was a string object but "d" is of type datetime. – nick Apr 27 '19 at 12:23
  • I hadn;t the first time but now I have got that all as you suggest. The error is a bit different now. It says AttributeError: type object 'datetime.datetime' has no attribute 'datetime' – holpot Apr 27 '19 at 12:31
  • Have you got: `import datetime` at the top of your file? Also make sure you are not calling any other variable `datetime` – nick Apr 27 '19 at 12:32
  • I say from datetime import datetime – holpot Apr 27 '19 at 12:34
  • Ah great. Then just remove the first `datetime`. So the line becomes: `d = datetime(*[int(i) for i in regex_match])` . I'll update the solution to reflect this – nick Apr 27 '19 at 12:35
  • 1
    I just tried it as you suggested and did 'import datetime' only. And it works! Thank you so much! – holpot Apr 27 '19 at 12:37
0

An alternative to eval or regex could be parse module:

import parse
import datetime as dt

f = open('mytext.txt', 'r')
template = "(datetime.datetime({Y}, {m}, {d}, {H}, {M}), {v})"
for line in f:
    x = parse.parse(template, line).named
    Y, m, d, H, M = int(x["Y"]), int(x["m"]), int(x["d"]), int(x["H"]), int(x["M"])
    ts = dt.datetime(Y, m, d, H, M)
    print(ts.strftime("%Y%m%d %H:%M:00"))
f.close()

Output:

20170101 04:16:00
20170101 04:26:00
20170101 04:36:00
Lante Dellarovere
  • 1,838
  • 2
  • 7
  • 10
-1

You can try this :

import datetime
import dateutil.parser 
date = '2014-12-18T19:00:00-07:00'
 datetime_obj=dateutil.parser.parse(date)                                               
 print (date.strftime("%Y-%m-%d %H:%M:%S"))
  • I'm not sure how this applies to strings that are already in datetime object format. Though not apparently real datetime objects. – holpot Apr 27 '19 at 12:16
-2

Lets's make things simpler.
There are two simple and very useful functions in datetime module viz.

strftime and strptime.

  • strftime is "String Format Time". It means it will convert the DateTime Object into a String.

  • strptime is "String Parse Time". It means it will convert the date string (in some particular format) into a DateTime Object.

Let me give you an example:


from datetime import datetime
d = datetime.now()
d

datetime.datetime(2019, 4, 27, 17, 55, 9, 967025)

Convert Date Time object to String of format "YYYY-mm-dd"

str_format_date = d.strftime("%Y-%m-%d")
str_format_date

'2019-04-27'

Convert String ("YYYY-mm-dd") back to Date Time Object

datetime.strptime(str_format_date, "%Y-%m-%d")

datetime.datetime(2019, 4, 27, 0, 0)

Note: The time has changes because we converted the datetime object to just a date string (lost the time part) and then re-convert that date string back to date time object.

Mohit S
  • 57
  • 1
  • 3