If Date doesn't exist, get the next valid date - python

I am using Python's datetime lib to parse a date and create a datetime object from it.
datetime.datetime.strptime(request.GET['date'], '%d-%m-%Y').date()
This works as long as a valid date is passed. I could use a try and except case to handle invalid dates, but would like to return the next valid date, as this is a Django view where a redirect would make sense.
How could I solve this?

Related

How to validate date input between two dates in Python

I am trying to validate user input of date of birth. I have used datetime to validate that it's a valid existing date, however I am trying to make it so you can only enter dates between 1/1/1900 and the current date. I am using .today(), however I am very confused by the importing of datetime and date, and can't seem to get it working.
I also want to zero pad the dates so everything entered is in the format dd/mm/yyyy, either by forcing them to enter it like that, or by converting it to that format afterwads
Any help would be grately appreciated :)

checking when a command was last used

I have a discord bot which has a command that requires a cooldown of a week. I considered using something like #commands.cooldown, but the issue is that if the bot goes offline, that cooldown resets itself. So, a member could simply watch for when the bot goes down and try to exploit it after it returns.
Since I can't keep the bot running 24x7x365, the solution I came up with was to record the date a user last used the command in a database, and when they use the command next, to check if seven days have passed.
For example's sake, this is what the command would look like:
#bot.command()
async def datetest(ctx,date):
today = datetime.date.today()
print(today)
someday = datetime.date.strptime(date,"%y-%m-%d")
diff = someday - today
await ctx.send(diff + "days.")
In this example, I'm using "date" as a parameter to just test if the command returns the difference of days.
(in the actual command, rather than take a date argument, it'll get a date stored in the DB)
However, the issue I'm facing is that:
someday = datetime.date.strptime(date,"%y-%m-%d")
doesn't run. What am I doing wrong here?
1: To format a date it's strftime 'f' for 'format' not strptime, 'parse'. strptime is used to turn a string object into a datetime object.
2: If you are working with the object you don't need to also pass that object to the methods of that class. i.e. you don't need to pass date to the object method 'strftime'
This is because, as with all object methods, it's done internally using the implicit 'self' parameter.
3: To get the actual date object you need to call a method of the datetime class which produces that. e.g. datetime.now()
Your code line should simply read something like:
import datetime.datetime as datetime
# or from datetime import datetime
someday = datetime.now().date().strftime("%y-%m-%d")
or
import datetime
someday = datetime.datetime.now().date().strftime("%y-%m-%d")
(Reading your post not sure what your intent is, so adding this for completeness)
Going the other way, getting a value from your database and using that to generate a datetime.
I don't know what database interface you are using so this is a general answer, as for many Python DB interfaces this is not necessary as the date field select() call will return a type for that field that is a datetime object.
# Paraphrasing a DB interface
dt_col = db.select("select max(date) from lastrun_dates;").execute()
# returns ["2022-10-3",]
date = datetime.datetime.strptime(dt_col[0], "%Y-m-%d")
# note the uppercase 'Y' for a 4 digit date
However, don't do this!
I don't recommend saving dates/times in a DB (or anywhere else for that matter) as a string as it has a DB schema, geographical, localle and daylight saving interpretation, which results in many ways of creating future issues. Instead it is recommended to use the UTC datetime from the epoch as an integer or float.
datetime.datetime.utcnow().timestamp()
# or
datetime.datetime.utcnow().toordinal()
Ok, so I figured out the issue after digging deeper into how datetime subtractions work.
One is that I needed to use someday = datetime.datetime.strptime().
Two is that I needed to use %Y instead of %y to match the time format passed into the date parameter (yyyy-mm-dd). Console pointed this out after a few tests.
Third is that I needed to extract the number of days out of the timedelta answer, because in the end, I'm trying to see how many days passed from the time the command was last used.
So, the new code looks like:
someday = datetime.datetime.strptime(date, "%Y-%m-%d")
diff = someday - today
print(diff.days)

How to get the value of a DateTimeField in peewee

class Test(Model):
time = DateTimeField()
# ...
row = Test.select()[0]
test.time
This returns a string that looks like this: 2017-01-23 01:01:39+01:00. How can I get it as a datetime object instead? Do I have to parse it manually?
Also I would be interested if there is any documentation on how to use the DateTimeField. The official documentation doesn't have anything on it.
Are you using SQLite? If so, SQLite doesn't have a dedicated datetime type, so datetimes are stored as strings in the DB. What peewee will do is recognize certain datetime formats coming out of the DB and convert them to datetime objects. What you need to do is ensure that either:
When you create/save your object, that you assign a datetime object to the field.
When reading back pre-existing data, that the data is in a recognized format.
The formats peewee supports out-of-the-box for datetime field are:
YYYY-mm-dd HH:MM:SS.ffffff
YYYY-mm-dd HH:MM:SS
YYYY-mm-dd
It looks like your has zone info. I'd suggest converting to UTC and dropping the zone info. That should fix it.
Have you tried adding a default like this?
time = DateTimeField(default=datetime.datetime.now())
Or when adding an entry add it as a datetime.datetime object directly:
test = Test(....., time=datetime.datetime.strptime("2018-3-15", '%Y-%m-%d'))
In the second case you don't need to specify anything in the class definition...

Detect missing date in string using dateutil in python

I have a string which contains a timestamp. This timestamp may or may not contain the date it was recorded. If it does not I need to retrieve it from another source. For example:
if the string is
str='11:42:27.619' #It does not contain a date, just the time
when I use dateutil.parser.parse(str), it will return me a datetime object with today's date. How can I detect when there is no date? So I can get it from somewhere else?
I can not just test if it is today's date because the timestamp may be from today and I should use the date provided in the timestamp if it exists.
Thank you
What I would do is first check the string's length, if it contains it should be larger, then I would proceed as you mention.

How to convert a CharField to Datetime Field in Python(Django)?

I have a CharField in my model as well as my database. I want to convert this CharField column to real datetime Django format. I have this insert query like
test.objects.create(voice=m.voice, size=m.size, start_time=get_time.get('min_time'),)
I would like to create a function to solve it, but not sure how to do it. Please help.
I think directly change the character field into datetime field is hard. Your need to do it one by one.
Create a new datetime column e.g. start_datetime
Create a script to convert the start_time from string into datetime object.
Edit all code that depend on start_time
Delete the start_time column
This is the example conversion from string to datetime code.
import time
for obj in Test.objects.all():
obj.start_datetime = time.strptime(obj.start_time, "%d %b %y")
obj.save()
You might want to read this python time library.

Categories