Subtract Time from Datetime Field in Django/Python - python

This question seems obvious and easy but I am getting my head stretched out here. Problem is I have datetime field in model and I want to subtract time from another attribute.
here is my code I have tried so far.
#property
def boarding_time(self):
print('---------------------------')
time = self.schedule.travel_date_time.time()
print()
time_added = self.schedule.bus_company_route.routeboardingpoint_set.get(
point=self.boarding_point
).time_added
time1 = timedelta(hours=time.hour, minutes=time.minute, seconds=time.second)
time2 = timedelta(hours=time_added.hour, minutes=time_added.minute, seconds=time_added.second)
return (time1-time2)
I am actually trying to find the time delay the vehicle reaches to certain destination. Suppose vehicle was supposed to move at 8 am but the vehicle departed from bus park at 8:15 am and passenger waiting will have 15 min added to their location but I am getting error as
'datetime.timedelta' object has no attribute 'isoformat'

Im not sure if this answers your question but you can try:
from datetime import datetime, date
datetime.combine(date.today(), exit) - datetime.combine(date.today(), enter)
combine builds a datetime, that can be subtracted. Your can google about it for more...
https://docs.python.org/3/library/datetime.html

At a high level, the adjusted boarding time is derived from taking scheduled boarding time and adding to it the amount of time that lapsed between the scheduled departure time and the actual departure time from the previous destination.
Here is a simplified example that hopefully illustrates the key concepts to help you piece together a solution for your more complex problem:
from datetime import datetime, timedelta
scheduled_boarding_time = datetime.fromisoformat("2021-01-12T10:00")
departure_delay_in_minutes = 15
adjusted_boarding_time = scheduled_boarding_time + timedelta(minutes=delay_in_minutes)
print(adjusted_boarding_time.isoformat())
2021-01-12T10:15:00

The solution to your question lies in the way you handle the time stamp format. You have your date time in AM/PM for this you have to format you date accordingly. Here is something what you can do instead of what you are doing right now
from datetime import datetime
time = '2021/1/13 8:15 am' #your date format
time_added = '2021/1/13 8:45 am' #your date format
format = '%Y/%m/%d %H:%M %p' #will format your date for further computation
time = datetime.strptime(time, format)
time
o/p
datetime.datetime(2021, 1, 13, 8, 15)
time_added = datetime.strptime(time_added, format)
time_added
o/p
datetime.datetime(2021, 1, 13, 8, 45)
time2 = time_added-time1 # this will give you time difference in seconds
divmod(time2.total_seconds(), 60)[0] #use this to get difference in minutes
o/p
30.0
This same you return in your function and it will solve your problem

Related

How to Split a substract of a date in python

My code is the following:
date = datetime.datetime.now()- datetime.datetime.now()
print date
h, m , s = str(date).split(':')
When I print h the result is:
-1 day, 23
How do I get only the hour (the 23) from the substract using datetime?
Thanks.
If you subtract the current date from a past date, you would get a negative timedelta value.
You can get the seconds with td.seconds and corresponding hour value via just dividing by 3600.
from datetime import datetime
import time
date1 = datetime.now()
time.sleep(3)
date2 = datetime.now()
# timedelta object
td = date2 - date1
print(td.days, td.seconds // 3600, td.seconds)
# 0 0 3
You're not too far off but you should just ask your question as opposed to a question with a "real scenario" later as those are often two very different questions. That way you get an answer to your actual question.
All that said, rather than going through a lot of hoop-jumping with splitting the datetime object, assigning it to a variable which you then later use look for what you need in, it's better to just know what DateTime can do since that can be such a common part of your coding. You would also do well to look at timedelta (which is part of datetime) and if you use pandas, timestamp.
from datetime import datetime
date = datetime.now()
print(date)
print(date.hour)
I can get you the hour of datetime.datetime.now()
You could try indexing a list of a string of datetime.datetime.now():
print(list(str(datetime.datetime.now()))[11] + list(str(datetime.datetime.now()))[12])
Output (in my case when tested):
09
Hope I am of help!

Calculating time difference in python

I want to make a code in python to find out the duration an employee had worked by taking two inputs.
input1 will be the time when the employee arrived at work, in hh:mm format.
input2 will be the time when the employee left work, in hh:mm format.
I want to calculate the duration an employee worked in hh:mm format when I subtract input1 from input2.
Please help in making this code.
There is no timedelta attribute for time objects.
You can use a datetime object first, then do:
difference = datetime1 - datetime2
The, finally, do:
print(difference.strftime('%H:%M')
Alternatively, if you are only allowed to use time input/object, you can do:
import datetime
# Time in example
a = datetime.time(9, 30)
# Time out example
b = datetime.time(17, 45)
hours = abs(int(b.strftime('%H')) - int(a.strftime('%H')))
minutes = abs(int(b.strftime('%M')) - int(a.strftime('%M')))
time_difference = datetime.time(hours, minutes)
print(time_difference)

Python: Convertion of seconds from an initial date to datetime

I have measurements taken from 1st January 1993. They were recorded in second elapsed from that date. I would like to have them in date time.
I know in MatLab the function would be
time = datenum(1993,01,01,00,00, time)
However, I struggle to find an equivalent function in Python.
I have tried:
datetime.fromordinal(time) doesn't work because 'module object has no attribute fromordinal'?
datetime.datetime(time) doesn't work (I have a matrix because there are many scans done)
https://docs.python.org/3/library/datetime.html
You will first have to create a datetime object for Jan 1st 1993 and then add the number of seconds to that date. The code below should help you get started.
from datetime import datetime, timedelta
original_date = datetime.strptime('01-01-1993', '%d-%m-%Y')
original_date + timedelta(seconds= 10000)
output: datetime.datetime(1993, 1, 1, 2, 46, 40)
Let us say you have list of timevalues in seconds starting from 1993-01-01 00:00.
Easiest would be:
datevec=[datetime.datetime(1993,1,1,0)+datetime.timedelta(seconds=val) for val in timevector]
It is like UNIX time, but with a different start.
You can compute the offset once:
>>> import datetime as dt
>>> dt.datetime(1993,1,1).timestamp()
725842800.0
and use it in your program:
OFFSET = 725842800.0
mydate = dt.datetime.fromtimestamp(OFFSET + seconds_from_1993)

Determine date and time from a fixed date given seconds elapsed since fixed date in python

I need to determine a date given the seconds elapsed since said date.
I have the date in the format of YYYY-MM-DD hh:mm:ss and I am aware that it can be converted to a datetime.datetime() object as a good starting point but how can I use a date time object as a reference point and accurately derive the date by extrapolating a given number of seconds?
You can use the method timedelta of the datetime module like this:
import datetime
start_date = datetime.datetime(2017, 10, 19, 15, 0, 0)
new_date = start_date + datetime.timedelta(seconds=5*86400)
## adds 5 days = 5*86400 seconds
print(new_date)
Give the output
2017-10-24 15:00:00

How to compute the time difference between two time zones in python?

How can I compute the time differential between two time zones in Python? That is, I don't want to compare TZ-aware datetime objects and get a timedelta; I want to compare two TimeZone objects and get an offset_hours. Nothing in the datetime library handles this, and neither does pytz.
Here is a solution using the Python library Pytz which solves the issue of ambiguous times at the end of daylight saving time.
from pytz import timezone
import pandas as pd
def tz_diff(date, tz1, tz2):
'''
Returns the difference in hours between timezone1 and timezone2
for a given date.
'''
date = pd.to_datetime(date)
return (tz1.localize(date) -
tz2.localize(date).astimezone(tz1))\
.seconds/3600
The examples below calculate the difference in hours between UTC and Australia time for the first of January and first of June respectively. Notice how daylight savings are taken into consideration.
utc = timezone('UTC')
aus = timezone('Australia/Sydney')
tz_diff('2017-01-01', utc, aus)
# 11.0
tz_diff('2017-06-01', utc, aus)
# 10.0
Thanks
The first thing you have to know is that the offset between two time zones depends not only on the time zones in question, but on the date you're asking about. For example, the dates on which Daylight Savings Time began and ended changed in the US in 2007. While fundamental time zone logistics change only infrequently in any single location, the rate of change globally is impossible to ignore. Therefore, you have to incorporate the date in question into your function.
Having completed the necessary preface, the actual function isn't too hard to write if you take advantage of the pendulum library. It should look something like this:
import pendulum
def tz_diff(home, away, on=None):
"""
Return the difference in hours between the away time zone and home.
`home` and `away` may be any values which pendulum parses as timezones.
However, recommended use is to specify the full formal name.
See https://gist.github.com/pamelafox/986163
As not all time zones are separated by an integer number of hours, this
function returns a float.
As time zones are political entities, their definitions can change over time.
This is complicated by the fact that daylight savings time does not start
and end on the same days uniformly across the globe. This means that there are
certain days of the year when the returned value between `Europe/Berlin` and
`America/New_York` is _not_ `6.0`.
By default, this function always assumes that you want the current
definition. If you prefer to specify, set `on` to the date of your choice.
It should be a `Pendulum` object.
This function returns the number of hours which must be added to the home time
in order to get the away time. For example,
```python
>>> tz_diff('Europe/Berlin', 'America/New_York')
-6.0
>>> tz_diff('Europe/Berlin', 'Asia/Kabul')
2.5
```
"""
if on is None:
on = pendulum.today()
diff = (on.set(tz=home) - on.set(tz=away)).total_hours()
# what about the diff from Tokyo to Honolulu? Right now the result is -19.0
# it should be 5.0; Honolulu is naturally east of Tokyo, just not so around
# the date line
if abs(diff) > 12.0:
if diff < 0.0:
diff += 24.0
else:
diff -= 24.0
return diff
As stated in the documentation, you may not get a stable result for this between any two given locations as you sweep across the days of the year. However, implementing a variant which chooses the median result over the days of the current year is an exercise left for the reader.
Here's another solution:
from datetime import datetime
from pytz import timezone
from dateutil.relativedelta import relativedelta
utcnow = timezone('utc').localize(datetime.utcnow()) # generic time
here = utcnow.astimezone(timezone('US/Eastern')).replace(tzinfo=None)
there = utcnow.astimezone(timezone('Asia/Ho_Chi_Minh')).replace(tzinfo=None)
offset = relativedelta(here, there)
offset.hours
Here what we're doing is converting a time to two different time zones. Then, we remove the time zone information so that when you calculate the difference between the two using relativedelta, we trick it into thinking that these are two different moments in time instead of the same moment in different time zones.
The above result will return -11, however this amount can change throughout the year since US/Eastern observes DST and Asia/Ho_Chi_Minh does not.
I created two functions to deal with timezone.
import datetime
import pytz
def diff_hours_tz(from_tz_name, to_tz_name, negative=False):
"""
Returns difference hours between timezones
res = diff_hours_tz("UTC", "Europe/Paris") : 2
"""
from_tz = pytz.timezone(from_tz_name)
to_tz = pytz.timezone(to_tz_name)
utc_dt = datetime.datetime.now(datetime.timezone.utc)
dt_from = dt_to = datetime.datetime.utcnow()
dt_from = from_tz.localize(dt_from)
dt_to = to_tz.localize(dt_to)
from_d = dt_from - utc_dt
if from_d.days < 0:
return diff_hours_tz(to_tz_name, from_tz_name, True)
dt_delta = dt_from - dt_to
negative_int = -1 if negative else 1
return int(dt_delta.seconds/3600)*negative_int
def dt_tz_to_tz(dt, from_tz_name, to_tz_name):
"""
Apply difference hours between timezones to a datetime object
dt_new = dt_tz_to_tz(datetime.datetime.now(), "UTC", "Europe/Paris")
"""
hours = diff_hours_tz(from_tz_name, to_tz_name)
return dt+datetime.timedelta(hours=hours)
# Usage example
res = diff_hours_tz("Europe/Paris", "America/New_York")
# Result : -6
res = diff_hours_tz("UTC", "Europe/Paris")
# Result : 2
now = datetime.datetime.now()
# Result : 2019-06-18 15:10:31.720105
dt_new = dt_tz_to_tz(now, "UTC", "Europe/Paris")
# Result : 2019-06-18 17:10:31.720105
dt_new = dt_tz_to_tz(now, "Europe/Paris", "America/New_York")
# Result : 2019-06-18 09:10:31.720105
dt_new = dt_tz_to_tz(now, "America/New_York", "Europe/Paris")
# Result : 2019-06-18 21:10:31.720105
I hope it will help !
Here is a code snippet to get the difference between UTC and US/Eastern, but it should work for any two timezones.
# The following algorithm will work no matter what is the local timezone of the server,
# but for the purposes of this discussion, let's assume that the local timezone is UTC.
local_timestamp = datetime.now()
# Assume that utc_timestamp == 2019-01-01 12:00.
utc_timestamp = pytz.utc.localize(local_timestamp)
# If it was 12:00 in New York, it would be 20:00 in UTC. So us_eastern_timestamp is a UTC
# timestamp with the value of 2019-01-01 20:00.
us_eastern_timestamp = timezone("US/Eastern").localize(local_timestamp).astimezone(pytz.utc)
# delta is a Python timedelta object representing the interval between the two timestamps,
# which, in our example, is -8 hours.
delta = utc_timestamp - us_eastern_timestamp
# In the last line, we convert the timedelta into an integer representing the number of
# hours.
print round(delta.total_seconds() / 60.0 / 60.0)
(tz_from.localize(date) - tz_to.localize(date)).seconds/3600.0
Where tz_from and tz_to are the starting and ending timezones. You must specify a particular date.
from datetime import datetime
from zoneinfo import ZoneInfo
dt = datetime.now() # 2020-09-13
tz0, tz1 = "Europe/Berlin", "US/Eastern" # +2 vs. -4 hours rel. to UTC
utcoff0, utcoff1 = dt.astimezone(ZoneInfo(tz0)).utcoffset(), dt.astimezone(ZoneInfo(tz1)).utcoffset()
print(f"hours offset between {tz0} -> {tz1} timezones: {(utcoff1-utcoff0).total_seconds()/3600}")
>>> hours offset between Europe/Berlin -> US/Eastern timezones: -6.0
a way to do this with Python 3.9's standard library.

Categories

Resources