Compare only time part in datetime - Python - python

I want to compare only time part in datetime. I have different dates with only time field to compare. Since dates are different and only time part i want to consider So i think creating two datetime object will not help.
my string as
start="22:00:00"
End="03:00:00"
Tocompare="23:30:00"
Above are strings when i convert them with datetime as
dt=datetime.strptime(start,"%H:%M:%S")
it gives
1900-01-01 22:00:00
which is default date in python.
So i need to avoid all this and want only time part. I simply need to check does my Tocompare falls between start and End

Just call the .time() method of the datetime objects to get their hours, minutes, seconds and microseconds.
dt = datetime.strptime(start,"%H:%M:%S").time()

Compare their times using datetime.time().

import datetime
start = datetime.datetime.strptime(start, '%H:%M:%S')
start = datetime.time(start.hour, start.minute,start.second)
tocompare = datetime.datetime.strptime(tocompare, '%H:%M:%S')
tocompare = datetime.time(tocompare.hour, tocompare.minute, tocompare.second)
start > tocompare # False

Related

How to remove date from datetime object

I have a method that converts a string to a datetime object using strptime("%I:%M %p"), I only want the hours in 24 and minutes without any dates, because I will get the difference between this time and another time. The problem is that when I try to get the difference with total_seconds(), it gets difference in negative because the date in the strptime is "1900-01-01". Does any one have any ideas how to solve this?
My Code:
fTime = datetime.strptime(time, "%I:%M %p")
if 0 < (fTime - datetime.now()).total_seconds() <= 3600:
return True
You can take one of two approaches: strip the date out of now, or add the current date to fTime. The first approach makes little sense, since you can't compare time objects like that anyway.
To convert fTime to a proper datetime, datetime.combine it with date.today():
fDate = datetime.combine(date.today(), fTime.time())
return 0 < (fDate - datetime.now()).total_seconds() <= 3600
Alternatively, you can replace the date portion:
today = date.today()
fDate = fTime.replace(year=today.year, month=today.month, day=today.day)
Personally, I would go with combine because it's less awkward code.

strptime() error - Time from sensor with more than 24 hours (e.g. 24:01:53)

I am using datetime.strptime() to convert a string containing time and date from a sensor into a datetime object.
The code sometimes fails. Minimal example:
datetime.strptime('1/9/2021 24:01:53', '%d/%m/%Y %H:%M:%S')
Output error:
ValueError: time data '1/9/2021 24:01:53' does not match format '%d/%m/%Y %H:%M:%S'
I am guessing this has to do with the fact that the time is more than 23:59:59 - which seems to me a non-realistic time (I would think that 1/9/2021 24:01:53 could potentially be 2/9/2021 00:01:53 - a time format which I have never seen).
Is this a non-standard way of representing time or possibly a hardware/software issue with the sensor acquisition system? If it is a different way of representing time, how can I convert it to a standard datetime object?
Kind regards,
D.F.
If the hour exceeds 23 in a variable representing time, a good option is to create a timedelta from it, which you can then add to a datetime object. For given example that might look like
from datetime import datetime, timedelta
def custom_todatetime(s):
"""
split date/time string formatted as 'DD/MM/YYYY hh:mm:ss' into date and time parts.
parse date part to datetime and add time part as timedelta.
"""
parts = s.split(' ')
seconds = sum(int(x) * 60 ** i for i, x in enumerate(reversed(parts[1].split(':'))))
return datetime.strptime(parts[0], "%d/%m/%Y") + timedelta(seconds=seconds)
s = '1/9/2021 24:01:53'
print(custom_todatetime(s))
# 2021-09-02 00:01:53
Note: conversion of hh:mm:ss to seconds taken from here - give a +1 there if helpful.

How to add a certain time to a datetime?

I want to add hours to a datetime and use:
date = date_object + datetime.timedelta(hours=6)
Now I want to add a time:
time='-7:00' (string) plus 4 hours.
I tried hours=time+4 but this doesn't work. I think I have to int the string like int(time) but this doesn't work either.
Better you parse your time like below and access datetime attributes for getting time components from the parsed datetime object
input_time = datetime.strptime(yourtimestring,'yourtimeformat')
input_seconds = input_time.second # for seconds
input_minutes = input_time.minute # for minutes
input_hours = input_time.hour # for hours
# Usage: input_time = datetime.strptime("07:00","%M:%S")
Rest you have datetime.timedelta method to compose the duration.
new_time = initial_datetime + datetime.timedelta(hours=input_hours,minutes=input_minutes,seconds=input_seconds)
See docs strptime
and datetime format
You need to convert to a datetime object in order to add timedelta to your current time, then return it back to just the time portion.
Using date.today() just uses the arbitrary current date and sets the time to the time you supply. This allows you to add over days and reset the clock to 00:00.
dt.time() prints out the result you were looking for.
from datetime import date, datetime, time, timedelta
dt = datetime.combine(date.today(), time(7, 00)) + timedelta(hours=4)
print dt.time()
Edit:
To get from a string time='7:00' to what you could split on the colon and then reference each.
this_time = this_time.split(':') # make it a list split at :
this_hour = this_time[0]
this_min = this_time[1]
Edit 2:
To put it all back together then:
from datetime import date, datetime, time, timedelta
this_time = '7:00'
this_time = this_time.split(':') # make it a list split at :
this_hour = int(this_time[0])
this_min = int(this_time[1])
dt = datetime.combine(date.today(), time(this_hour, this_min)) + timedelta(hours=4)
print dt.time()
If you already have a full date to use, as mentioned in the comments, you should convert it to a datetime using strptime. I think another answer walks through how to use it so I'm not going to put an example.

Python: convert 'days since 1990' to datetime object

I have a time series that I have pulled from a netCDF file and I'm trying to convert them to a datetime format. The format of the time series is in 'days since 1990-01-01 00:00:00 +10' (+10 being GMT: +10)
time = nc_data.variables['time'][:]
time_idx = 0 # first timestamp
print time[time_idx]
9465.0
My desired output is a datetime object like so (also GMT +10):
"2015-12-01 00:00:00"
I have tried converting this using the time module without much success although I believe I may be using wrong (I'm still a novice in python and programming).
import time
time_datetime = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(time[time_idx]*24*60*60))
Any advice appreciated,
Cheers!
The datetime module's timedelta is probably what you're looking for.
For example:
from datetime import date, timedelta
days = 9465 # This may work for floats in general, but using integers
# is more precise (e.g. days = int(9465.0))
start = date(1990,1,1) # This is the "days since" part
delta = timedelta(days) # Create a time delta object from the number of days
offset = start + delta # Add the specified number of days to 1990
print(offset) # >>> 2015-12-01
print(type(offset)) # >>> <class 'datetime.date'>
You can then use and/or manipulate the offset object, or convert it to a string representation however you see fit.
You can use the same format as for this date object as you do for your time_datetime:
print(offset.strftime('%Y-%m-%d %H:%M:%S'))
Output:
2015-12-01 00:00:00
Instead of using a date object, you could use a datetime object instead if, for example, you were later going to add hours/minutes/seconds/timezone offsets to it.
The code would stay the same as above with the exception of two lines:
# Here, you're importing datetime instead of date
from datetime import datetime, timedelta
# Here, you're creating a datetime object instead of a date object
start = datetime(1990,1,1) # This is the "days since" part
Note: Although you don't state it, but the other answer suggests you might be looking for timezone aware datetimes. If that's the case, dateutil is the way to go in Python 2 as the other answer suggests. In Python 3, you'd want to use the datetime module's tzinfo.
netCDF num2date is the correct function to use here:
import netCDF4
ncfile = netCDF4.Dataset('./foo.nc', 'r')
time = ncfile.variables['time'] # do not cast to numpy array yet
time_convert = netCDF4.num2date(time[:], time.units, time.calendar)
This will convert number of days since 1900-01-01 (i.e. the units of time) to python datetime objects. If time does not have a calendar attribute, you'll need to specify the calendar, or use the default of standard.
We can do this in a couple steps. First, we are going to use the dateutil library to handle our work. It will make some of this easier.
The first step is to get a datetime object from your string (1990-01-01 00:00:00 +10). We'll do that with the following code:
from datetime import datetime
from dateutil.relativedelta import relativedelta
import dateutil.parser
days_since = '1990-01-01 00:00:00 +10'
days_since_dt = dateutil.parser.parse(days_since)
Now, our days_since_dt will look like this:
datetime.datetime(1990, 1, 1, 0, 0, tzinfo=tzoffset(None, 36000))
We'll use that in our next step, of determining the new date. We'll use relativedelta in dateutils to handle this math.
new_date = days_since_dt + relativedelta(days=9465.0)
This will result in your value in new_date having a value of:
datetime.datetime(2015, 12, 1, 0, 0, tzinfo=tzoffset(None, 36000))
This method ensures that the answer you receive continues to be in GMT+10.

How to convert dateutil.relativedelta object to datetime.timedelta object?

How can I convert a dateutil.relativedelta object to a datetime.timedelta object?
e.g.,
# pip install python-dateutil
from dateutil.relativedelta import relativedelta
from datetime import timedelta
rel_delta = relativedelta(months=-2)
# How can I convert rel_delta to a timedelta object so that I can call total_seconds() ?
time_delta = ???(rel_delta)
time_delta.total_seconds() # call the timedelta.total_seconds() method
You can't, for one huge reason: They don't store the same information. datetime.timedelta only stores days, seconds, and milliseconds, whereas dateutil.relativedelta stores every single time component fed to it.
That dateutil.relativedelta does so is important for storing things such as a difference of 1 month, but since the length of a month can vary this means that there is no way at all to express the same thing in datetime.timedelta.
In case someone is looking to convert a relativedelta to a timedelta from a specific date, simply add and subtract the known time:
utcnow = datetime.utcnow()
rel_delta = relativedelta(months=-2)
time_delta = utcnow + rel_delta - utcnow # e.g, datetime.timedelta(days=-62)
As a commenter points out, the resulting timedelta value will differ based on what month it is.
Depending on why you want to call total_seconds, it may be possible to refactor your code to avoid the conversion altogether. For example, consider a check on whether or not a user is over 18 years old:
datetime.date.today() - user['dateOfBirth'] < datetime.timedelta(days=365*18)
This check is not a good idea, because the timedelta object does not account for things like leap years. It's tempting to rewrite as:
datetime.date.today() - user['dateOfBirth'] < dateutil.relativedelta.relativedelta(years=18)
which would require comparing a timedelta (LHS) to a relativedelta (RHS), or converting one to the other. However, you can refactor the check to avoid this conversion altogether:
user['dateOfBirth'] + dateutil.relativedelta.relativedelta(years=18) > datetime.date.today()

Categories