Convert QDate to seconds - pyqt4

I take date from QDateTimeEdit and convert it to seconds like this:
import time
from datetime import datetime
date = self.__ui.dateTimeEdit.date().toString("dd/MM/yy")
dateString = str(date)
seconds = time.mktime(datetime.strptime(dateString, "%d/%m/%y").timetuple())
This works well, but since it looks to long to me, my question is: Is it possible to convert self.__ui.dateTimeEdit.date() directly, without those string conversions?
EDIT1
Unfortunately toMSecsSinceEpoch() as falsetru suggested, doesn't work for me.
AttributeError: 'QDateTime' object has no attribute 'toMSecsSinceEpoch'
I'm using PyQt 4.7.1 for Python 2.6
EDIT2 based on jonrsharpe's answer I've escaped string conversions:
date = self.__ui.dateTimeEdit.date().toPyDate()
seconds = time.mktime(date.timetuple())
result is the same.
EDIT3 even shorter solution based on falsetru's comment:
self.__ui.dateTimeEdit.dateTime().toTime_t()

Use QDateTime.toMSecsSinceEpoch:
>>> import PyQt4.QtCore
>>> d = PyQt4.QtCore.QDateTime(2014, 2, 20, 17, 10, 30)
>>> d.toMSecsSinceEpoch() / 1000
1392883830L
UPDATE
Alternative using QDateTime.toTime_t:
>>> d = PyQt4.QtCore.QDateTime(2014, 2, 20, 17, 10, 30)
>>> d.toTime_t()
1392883830L

The QDate you get from
self.__ui.dateTimeEdit.date()
has another method toPyDate that will save you the round trip through a string.

Related

What is the simplest way to convert str (eg: 28/01/2023 13:17:58) to datetime(2023/01/28 13:17:58) format in python?

I have tried multiple ways like splitting each value and the rearranging. and the code seems too lengthy can someone help me to write it in a shorter way.
time = "28/01/2023 13:17:58"
I split it to
lis = [28,01,2023]
lis2 = [13,17,58]
then rearranged it to
t = 28/01/2023 13:17:58
can someone tell me how I can use datetime to simplify this?
date = "28/01/2023 13:17:58"
datetime.datetime.strptime(date, '%d/%m/%Y %H:%M:%S')
Output = datetime.datetime(2023, 1, 28, 13, 17, 58)
from datetime import datetime
time = "28/01/2023 13:17:58"
datetime_obj = datetime.strptime(time, "%d/%m/%Y %H:%M:%S")
print(datetime_obj) # 2023-01-28 13:17:58

using python `eval()` with a method

My ultimate goal is to get the day, month and year of two days, today and yesterday in a nested for loop.
Below I am importing stuff and defining today and yesterday
import datetime as dt
from datetime import timedelta
today = dt.date.today()
yesterday = today - timedelta(1)
Now I am defining a dictionary to map the format of each year, month and day
d_day_format = {'year': '%y',
'month': '%m',
'day': '%d'}
So now I want to create the following variables: today_year (20), today_month (12), today_day (31), yesterday_year (20), yesterday_month (12) and yesterday_day (30)
I am using eval() to get the values of the variables from strings, as shown in the loop below
for d in 'today yesterday'.split():
for k in d_day_format.keys():
globals()[f"{d}_{k}"] = eval(d).eval(k).format(f"{d_day_format[k]}")
the first part of the variable assignment eval(d) works, though it appears I cannot use eval() for methods:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~/installed/python/demuxDelayer/demuxDelayer_v2.py in <module>
1 for d in 'today yesterday'.split():
2 for k in d_day_format.keys():
----> 3 globals()[f"{d}_{k}"] = eval(d).eval(k).format(f"{d_day_format[k]}")
AttributeError: 'datetime.date' object has no attribute 'eval'
Does anyone know how to fix this?
Python’s eval() allows you to evaluate arbitrary Python expressions from a string-based or compiled-code-based input. This function can be handy when you’re trying to dynamically evaluate Python expressions from any input that comes as a string or a compiled code object. In this case, you are overly complicating the problem. This is how I would accomplish what you want.
import datetime as dt
from datetime import timedelta
today = dt.date.today()
yesterday = today + timedelta(days=-1) #Note changed from your original
cntl_dict={'year':'year%100', 'month':'month', 'day':'day'}
inrecord = {'today':today, 'yesterday':yesterday}
for k, v in inrecord.items():
for l, w in cntl_dict.items():
print(f'{k}-{l}: {eval(f"{k}.{w}")}')
Yields:
today_year': 20
today_month': 12
today_day': 31
yesterday_year': 20
yesterday_month': 12
yesterday_day': 30

How to differentiate between a dateutil parsed date and a datetime with 0 for all time values

As far as I can tell there is no way to distinguish the difference between these two date strings ('2020-10-07', '2020-10-07T00:00:00') once they are parsed by dateutil. I really would like to be able to tell the difference between a standalone date and a date with a timestamp of zero.
import dateutil.parser
import datetime
date_str = '2020-10-07'
time_str = '2020-10-07T00:00:00'
s = dateutil.parser.parse(date_str)
e = dateutil.parser.parse(time_str)
The ultimate goal is to set the time to the beginning of the day in the end of the day when it is a standalone date but leave the date alone when there is a time included. Get close with something like this but it still can't differentiate from this one case. If do you know of any good solution to this that would be really helpful.
if s == e and s.time() == datetime.time.min:
e = datetime.datetime.combine(e, datetime.time.max)
Post is somewhat useful but it's outdated and I'm not even sure that it would work for my use case. Finding if a python datetime has no time information
Here's a function which uses a simple try/except to test if the input can be parsed to a date (i.e. has no time information) or a datetime object (i.e. has time information). If the input format is different from ISO format, you could also implement specific strptime directives.
from datetime import date, time, datetime
def hasTime(s):
"""
Parameters
----------
s : string
ISO 8601 formatted date / datetime string.
Returns
-------
tuple, (bool, datetime.datetime).
boolean will be True if input specifies a time, otherwise False.
"""
try:
return False, datetime.combine(date.fromisoformat(t), time.min)
except ValueError:
return True, datetime.fromisoformat(t)
# do nothing else here; will raise an error if input can't be parsed
for t in ('2020-10-07', '2020-10-07T00:00:00', 'not-a-date'):
print(t, hasTime(t))
# output:
# >>> 2020-10-07 (False, datetime.datetime(2020, 10, 7, 0, 0))
# >>> 2020-10-07T00:00:00 (True, datetime.datetime(2020, 10, 7, 0, 0))
# >>> ValueError: Invalid isoformat string: 'not-a-date'

adding ten days to datetime

I want to add 10 days to s so I try the following
import datetime
s= '01/11/2018'
add = s + datetime.timedelta(days = 10)
But I get an error
TypeError: must be str, not datetime.timedelta
so I try
add = s + str(datetime.timedelta(days = 10))
And I get
'01/11/201810 days, 0:00:00'
But this is not what I am looking for.
I would like the following output where 10 days are added to s
'01/21/2018'
I have also looked Adding 5 days to a date in Python but this doesnt seem to work for me
How do I get my desired output?
Your s is a string, not a datetime. Python knows how to add a string to a string and a datetime to a timedelta, but is pretty confused about you wanting to add a string and a timedelta.
datetime.datetime.strptime('01/11/2018', '%m/%d/%Y') + datetime.timedelta(days = 10)

Sort by datetime in python3

Looking for help on how to sort a python3 dictonary by a datetime object (as shown below, a value in the dictionary) using the timestamp below.
datetime: "2018-05-08T14:06:54-04:00"
Any help would be appreciated, spent a bit of time on this and know that to create the object I can do:
format = "%Y-%m-%dT%H:%M:%S"
# Make strptime obj from string minus the crap at the end
strpTime = datetime.datetime.strptime(ts[:-6], format)
# Create string of the pieces I want from obj
convertedTime = strpTime.strftime("%B %d %Y, %-I:%m %p")
But I'm unsure how to go about comparing that to the other values where it accounts for both day and time correctly, and cleanly.
Again, any nudges in the right direction would be greatly appreciated!
Thanks ahead of time.
Datetime instances support the usual ordering operators (< etc), so you should order in the datetime domain directly, not with strings.
Use a callable to convert your strings to timezone-aware datetime instances:
from datetime import datetime
def key(s):
fmt = "%Y-%m-%dT%H:%M:%S%z"
s = ''.join(s.rsplit(':', 1)) # remove colon from offset
return datetime.strptime(s, fmt)
This key func can be used to correctly sort values:
>>> data = {'s1': "2018-05-08T14:06:54-04:00", 's2': "2018-05-08T14:05:54-04:00"}
>>> sorted(data.values(), key=key)
['2018-05-08T14:05:54-04:00', '2018-05-08T14:06:54-04:00']
>>> sorted(data.items(), key=lambda item: key(item[1]))
[('s2', '2018-05-08T14:05:54-04:00'), ('s1', '2018-05-08T14:06:54-04:00')]

Resources