How to resolve VariantTimeToSystemTime error while reading/converting dates? - python

def count_messages_in_folder(folder, message_count, sent_dates):
for item in folder.Items:
message_count += 1
try:
sent_date = item.SentOn
if sent_date is not None and sent_date != 0:
sent_date = sent_date.strftime('%Y-%m-%d %H:%M:%S')
try:
date = datetime.datetime.strptime(sent_date, '%Y-%m-%d %H:%M:%S')
if (date.year >= 1998 or date.year <= datetime.datetime.now().year) and (date.month >= 1 or date.month <= 12) and (date.day >= 1 or date.day <= 31):
sent_dates.append(date)
except ValueError:
pass
except ValueError:
pass
for subfolder in folder.Folders:
message_count, sent_dates = count_messages_in_folder(subfolder, message_count, sent_dates)
return message_count, sent_dates
This is a snippet of my script where I read a PST file (Outlook container that contains messages) using the win32com library. I have no issues calculating the total message count per PST file. However, I do run into the following error while trying to parse the sent date of each message and appending them to a list. My goal is to take sent dates from all messages in a PST file, add it to a list (sent_dates), and then find the min and max of the datetime objects in that list in another function.
error: (0, 'VariantTimeToSystemTime', 'No error message is available')
item.SentOn when initially read has the following type and format:
<class 'pywintypes.datetime'> 2001-08-30 03:48:50+00:00
I then convert it to a string in '%Y-%m-%d %H:%M:%S' format using strftime.
Finally, I convert the date string to datetime object using strptime (so I can find the min and max dates later):
<class 'datetime.datetime'> 2001-08-30 03:48:50
I noticed that some dates in the PST had wrong year/month/day (e.g., "3547" or "1980" as year). I added the if condition to check for year, month, day, but I still get the error.
I'd really appreciate any help in figuring this out.

Related

How to write a python function that returns the number of days between two dates

I am new to functions and I am trying to write a function that returns the number of days between two dates:
My attempt:
import datetime
from dateutil.parser import parse
def get_x_days_ago (date_from, current_date = None):
td = current_date - parse(date_from)
if current_date is None:
current_date = datetime.datetime.today()
else:
current_date = datetime.datetime.strptime(date_from, "%Y-%m-%d")
return td.days
print(get_x_days_ago(date_from="2021-04-10", current_date="2021-04-11"))
Expected outcome in days:
1
So there seem to be multiple issues, and as I said in the comments, a good idea would be to separate the parsing and the logic.
def get_x_days_ago(date_from, current_date = None):
if current_date is None:
current_date = datetime.datetime.today()
return (current_date - date_from).days
# Some other code, depending on where you are getting the dates from.
# Using the correct data types as the input to the get_x_days_ago (datetime.date in this case) will avoid
# polluting the actual logic with the parsing/formatting.
# If it's a web framework, convert to dates in the View, if it's CLI, convert in the CLI handling code
date_from = parse('April 11th 2020')
date_to = None # or parse('April 10th 2020')
days = get_x_days_ago(date_from, date_to)
print(days)
The error you get is from this line (as you should see in the traceback)
td = current_date - parse(date_from)
Since current_date="2021-04-11" (string), but date_from is parsed parse(date_from), you are trying to subtract date from the str.
P.S. If you have neither web nor cli, you can put this parsing code into def main, or any other point in code where you first get the initial strings representing the dates.
It looks like you're already aware that you can subtract a datetime from a datetime. I think, perhaps, you're really looking for this:
https://stackoverflow.com/a/23581184/2649560

Python - Convert February 29 dates to date time objects

I need to convert dates in string format to date time object but I keep getting a value error for 29th February dates. Here is my code.
from datetime import datetime
def try_parsing_date(text):
for fmt in ('%Y-%m-%d', '%d.%m.%Y', '%m/%d/%Y', '%d/%m/%Y', '%d-%b-%y', '%d/%m/%y', '%m/%d/%y', '%m/%d/%Y'):
try:
return datetime.strptime(text, fmt)
except ValueError:
pass
raise ValueError(text)
df['Dateofbirth'] = df.apply(lambda row: try_parsing_date(row['Dateofbirth']), axis=1)
The error I get is ValueError: ('2/29/57', 'occurred at index 82445').
What is the best way to resolve this issue?
This is not a Python problem. 1957 wasn't a leap and 2/29/57 never existed. If someone claims that as his date of birth, he's lying. So you could as well put any date into your list - or nan.
Error message I obtained was more specific and usefull:
from datetime import datetime
datetime.strptime('1957-02-29', '%Y-%m-%d')
ValueError: day is out of range for month
BTW there is a lot of misleading web sites about history informing 'what happend' on 29 Feb '57 :-)

Python dateutil date conversion

I'm trying to see if a list of dates are valid dates. I'm using the dateutil library, but I'm getting weird results. For example, when I try the following:
import dateutil.parser as parser
x = '10/84'
date = (parser.parse(x))
print(date.isoformat())
I get the result 1984-10-12T00:00:00 which is wrong. Does anyone know why this 12 gets added to the date?
The parse() method parses the string and updates a default datetime object, using the parsed information. If the default is not passed into this function, it uses first second of today.
This means that the 12 in your result, is today (when you're running the code), only the year and the month are updated from parsing the string.
If you need to parse the date string but you're not sure if it's a valid date value, then you may use a try ... except block to catch parse errors.
import dateutil.parser as parser
x = '10/84'
try:
date = (parser.parse(x))
print(date.isoformat())
except ValueError as err:
pass # handle the error
12 is the current date . dateutil takes components from current date/time to account for missing date or year in the date (it does not do this for the month, only date or year). Like another example would be a date like - Janauary 20 - this would get parsed as 2015/01/12 taking the 2015 year from the current datetime.
Sadly I have not yet found any options or such to stop this behavior.
I believe the best option for you would be to come up with a list of the valid datetime formats that you are expecting , and then manually try datetime.datetime.strptime on them , excepting ValueError . Example -
def isdate(dt, fmt):
try:
datetime.datetime.strptime(dt, fmt)
return True
except ValueError:
return False
validformats = [...]
dates =[...]
for x in dates:
if any(isdate(x,fmt) for fmt in validformats):
print(x, 'is valid date')

Need Assistance with This Simple Python Code

Here is my code & this is my error : AttributeError: type object 'datetime.datetime' has no attribute 'strptime
#Trying to calculate how many days until a project is due for
import datetime
project = input('When is your project due for Please specify mm/dd/yyyy ')
deadline = datetime.datetime.strptime(project, '%m/%d/Y').date()
days = project - deadline
print(days)
print(days.days)
Thank You in advance #KOH
Looks like you need something like this:
import datetime
project = input('When is your project due for. Please specify mm/dd/yyyy ')
deadline = datetime.datetime.strptime(project, '%m/%d/%Y').date()
delta = deadline - datetime.datetime.now().date()
print(delta.days)
Using Python3 there is no errors with datetime:
>>> datetime.datetime.strptime("08/11/2015", "%m/%d/%Y").date()
datetime.date(2015, 8, 11)
I'm not sure why you were getting that AttributeError, but I guess we resolved it in the comments. You were also getting an error because your formatting string was missing a %. And once you fix that, you would get an error saying you can't subtract a date from a str.
Even with all the errors fixed, what the code is doing isn't what you're trying to do. It looks like you're trying to subtract the user-provided date from itself, but I'm guessing you want to subtract today's date from the user-provided date, in order to get the number of days until the user-provided date.
Here's the fixed code, with some formatting and other changes thrown in.
from datetime import datetime
deadline_str = input('When is your project due? Specify mm/dd/yyyy: ')
deadline = datetime.strptime(deadline_str, '%m/%d/%Y').date()
days_till_deadline = (deadline - datetime.today().date()).days
print("{0} days till the project is due.".format(days_till_deadline))
So this is the code written by me and it works...
#todays date programme
import datetime
currentDate = datetime.date.today()
#currentDate is date which is converted to string with variable current in the format dd/mm/yyyy
current = datetime.datetime.strftime(currentDate, '%d/%m/%Y')
#input statements
userInput = input('Please enter your project deadline (dd/mm/yyyy)\n')
print()
##prints...
print("Today's Date is "+current)
print()
print("Your project deadline is " + userInput)
#userInput is a string which is converted to date with variable Input
Input = datetime.datetime.strptime(userInput, "%d/%m/%Y").date()
##Calculating remaining days
remainingDays = Input - currentDate
remainingDays = remainingDays.days
print()
print('The days remaining for deadline are '+str(remainingDays)+' days')
I guess it's something like this.
Because here we had to import the date time first cos we working with the date.
Then we had to get the current date in order to be able to get the project deadline.
import datetime
current_date = datetime.datetime.now()
user = input('Enter the days left for your project: ')
deadline = datetime.datetime.strptime(user, '%d%m%Y').date()
days_left = deadline - current_date.date()
print(days_left.days)

python dateutil relativedelta value out of range error

i am trying to get two dates, yesterday's and tomorrow's based on a given date which i then pass on to Django's Queryset filter function:
nxtday = relativedelta(day=+1) + date
yesterday = relativedelta(day=-1) + date
events = events.filter(start_datetime__gte=yesterday, end_datetime__lte=nxtday)
The point here is to get the events for the day as you've already probably deduced. Problem is i keep getting this error:
ValueError: day is out of range for month
Switching to timedelta objects raises issues later with dateutil's rrule:
TypeError: can't compare offset-naive and offset-aware datetimes
I am fond of dateutil module so i am just curious why it didn't work. Example date passed: 2014-02-26. Any ideas?
Passing -1 for the day parameter is requesting the -1 day of the month, which is why it complains about an out of range value.
For relative delta the day parameter is for absolute dates, and the days parameter is for relative dates. docs
nxtday = relativedelta(days=1) + date
yesterday = relativedelta(days=-1) + date

Categories

Resources