Datetimes in Python - python

I have two dates
'2017-03-10 19:01:27'
'2017-03-11 07:35:55'
I would like to get the difference one day. How can I do this with the time zone in mind?
Because the time zone of these dates is not known to us. I'm new in Python
I have:
from_zone = tz.tzutc()
to_zone = tz.tzlocal()
date_first = datetime.strptime(args[0], time_format)
date_second = datetime.strptime(args[1], time_format)
rep_date_first = date_first.replace(tzinfo=from_zone)
rep_date_second = date_second.replace(tzinfo=from_zone)
timezone_date_first = rep_date_first.astimezone(to_zone)
timezone_date_second = rep_date_second.astimezone(to_zone)
day = timezone_date_first.day - timezone_date_second.day
day return me 0, How to fix it? Please help me

By changing the timezone you're probably adding or subtracting enough hours to your dates that they end up on the same day. You should probably just assume a timezone as you're converting them from strings – or just leave them naive datetime objects.
>>> d1 = '2017-03-10 19:01:27'
>>> d2 = '2017-03-11 07:35:55'
>>> date_first = datetime.strptime(d1, '%Y-%m-%d %H:%M:%S')
>>> date_second = datetime.strptime(d2, '%Y-%m-%d %H:%M:%S')
>>> date_first.day
10
>>> date_second.day - date_first.day
1

arrow module is a big friend to everyone working with dates, you achive a shift very easily.
import arrow
dt = arrow.get('2017-03-10 19:01:27')
dt = dt.replace(tzinfo='Europe/Warsaw')
dt2 = dt.shift(days=-1)
assert dt2.isoformat() == '2017-03-09T19:01:27+01:00'
What you are asking a bit amigous: I would like to get the difference one day and your code is not runnable in isolation (args[0]), but I think you can assume the dates are in the same timezone.

Related

How to correctly generate list of UTC timestamps, by hour, between two datetimes Python?

I'm new to Python. After a couple days researching and trying things out, I've landed on a decent solution for creating a list of timestamps, for each hour, between two dates.
Example:
import datetime
from datetime import datetime, timedelta
timestamp_format = '%Y-%m-%dT%H:%M:%S%z'
earliest_ts_str = '2020-10-01T15:00:00Z'
earliest_ts_obj = datetime.strptime(earliest_ts_str, timestamp_format)
latest_ts_str = '2020-10-02T00:00:00Z'
latest_ts_obj = datetime.strptime(latest_ts_str, timestamp_format)
num_days = latest_ts_obj - earliest_ts_obj
num_hours = int(round(num_days.total_seconds() / 3600,0))
ts_raw = []
for ts in range(num_hours):
ts_raw.append(latest_ts_obj - timedelta(hours = ts + 1))
dates_formatted = [d.strftime('%Y-%m-%dT%H:%M:%SZ') for d in ts_raw]
# Need timestamps in ascending order
dates_formatted.reverse()
dates_formatted
Which results in:
['2020-10-01T00:00:00Z',
'2020-10-01T01:00:00Z',
'2020-10-01T02:00:00Z',
'2020-10-01T03:00:00Z',
'2020-10-01T04:00:00Z',
'2020-10-01T05:00:00Z',
'2020-10-01T06:00:00Z',
'2020-10-01T07:00:00Z',
'2020-10-01T08:00:00Z',
'2020-10-01T09:00:00Z',
'2020-10-01T10:00:00Z',
'2020-10-01T11:00:00Z',
'2020-10-01T12:00:00Z',
'2020-10-01T13:00:00Z',
'2020-10-01T14:00:00Z',
'2020-10-01T15:00:00Z',
'2020-10-01T16:00:00Z',
'2020-10-01T17:00:00Z',
'2020-10-01T18:00:00Z',
'2020-10-01T19:00:00Z',
'2020-10-01T20:00:00Z',
'2020-10-01T21:00:00Z',
'2020-10-01T22:00:00Z',
'2020-10-01T23:00:00Z']
Problem:
If I change earliest_ts_str to include minutes, say earliest_ts_str = '2020-10-01T19:45:00Z', the resulting list does not increment the minute intervals accordingly.
Results:
['2020-10-01T20:00:00Z',
'2020-10-01T21:00:00Z',
'2020-10-01T22:00:00Z',
'2020-10-01T23:00:00Z']
I need it to be:
['2020-10-01T20:45:00Z',
'2020-10-01T21:45:00Z',
'2020-10-01T22:45:00Z',
'2020-10-01T23:45:00Z']
Feels like the problem is in the num_days and num_hours calculation, but I can't see how to fix it.
Ideas?
if you don't mind to use a 3rd party package, have a look at pandas.date_range:
import pandas as pd
earliest, latest = '2020-10-01T15:45:00Z', '2020-10-02T00:00:00Z'
dti = pd.date_range(earliest, latest, freq='H') # just specify hourly frequency...
l = dti.strftime('%Y-%m-%dT%H:%M:%SZ').to_list()
print(l)
# ['2020-10-01T15:45:00Z', '2020-10-01T16:45:00Z', '2020-10-01T17:45:00Z', '2020-10-01T18:45:00Z', '2020-10-01T19:45:00Z', '2020-10-01T20:45:00Z', '2020-10-01T21:45:00Z', '2020-10-01T22:45:00Z', '2020-10-01T23:45:00Z']
import datetime
from datetime import datetime, timedelta
timestamp_format = '%Y-%m-%dT%H:%M:%S%z'
earliest_ts_str = '2020-10-01T00:00:00Z'
ts_obj = datetime.strptime(earliest_ts_str, timestamp_format)
latest_ts_str = '2020-10-02T00:00:00Z'
latest_ts_obj = datetime.strptime(latest_ts_str, timestamp_format)
ts_raw = []
while ts_obj <= latest_ts_obj:
ts_raw.append(ts_obj)
ts_obj += timedelta(hours=1)
dates_formatted = [d.strftime('%Y-%m-%dT%H:%M:%SZ') for d in ts_raw]
print(dates_formatted)
EDIT:
Here is example with Maya
import maya
earliest_ts_str = '2020-10-01T00:00:00Z'
latest_ts_str = '2020-10-02T00:00:00Z'
start = maya.MayaDT.from_iso8601(earliest_ts_str)
end = maya.MayaDT.from_iso8601(latest_ts_str)
# end is not included, so we add 1 second
my_range = maya.intervals(start=start, end=end.add(seconds=1), interval=60*60)
dates_formatted = [d.iso8601() for d in my_range]
print(dates_formatted)
Both output
['2020-10-01T00:00:00Z',
'2020-10-01T01:00:00Z',
... some left out ...
'2020-10-01T23:00:00Z',
'2020-10-02T00:00:00Z']
Just change
num_hours = num_days.days*24 + num_days.seconds//3600
The problem is that num_days only takes integer values, so if it is not a multiple of 24h you will get the floor value (i.e for your example you will get 0). So in order to compute the hours you need to use both, days and seconds.
Also, you can create the list directly in the right order, I am not sure if you are doing it like this for some reason.
ts_raw.append(earliest_ts_obj + timedelta(hours = ts + 1))

How to use ftplib in Python to change directories when directory name matches a date [duplicate]

I need to find "yesterday's" date in this format MMDDYY in Python.
So for instance, today's date would be represented like this:
111009
I can easily do this for today but I have trouble doing it automatically for "yesterday".
Use datetime.timedelta()
>>> from datetime import date, timedelta
>>> yesterday = date.today() - timedelta(days=1)
>>> yesterday.strftime('%m%d%y')
'110909'
from datetime import datetime, timedelta
yesterday = datetime.now() - timedelta(days=1)
yesterday.strftime('%m%d%y')
This should do what you want:
import datetime
yesterday = datetime.datetime.now() - datetime.timedelta(days = 1)
print yesterday.strftime("%m%d%y")
all answers are correct, but I want to mention that time delta accepts negative arguments.
>>> from datetime import date, timedelta
>>> yesterday = date.today() + timedelta(days=-1)
>>> print(yesterday.strftime('%m%d%y')) #for python2 remove parentheses
Could I just make this somewhat more international and format the date according to the international standard and not in the weird month-day-year, that is common in the US?
from datetime import datetime, timedelta
yesterday = datetime.now() - timedelta(days=1)
yesterday.strftime('%Y-%m-%d')
To expand on the answer given by Chris
if you want to store the date in a variable in a specific format, this is the shortest and most effective way as far as I know
>>> from datetime import date, timedelta
>>> yesterday = (date.today() - timedelta(days=1)).strftime('%m%d%y')
>>> yesterday
'020817'
If you want it as an integer (which can be useful)
>>> yesterday = int((date.today() - timedelta(days=1)).strftime('%m%d%y'))
>>> yesterday
20817

Python count start date + days

I am making a program where I input start date to dataStart(example 21.10.2000) and then input int days dateEnd and I convert it to another date (example 3000 = 0008-02-20)... Now I need to count these dates together, but I didn't managed myself how to do that. Here is my code.
from datetime import date
start=str(input("type start date (DD.MM.YYYY)"))
end=int(input("how many days from it?"))
dataStart=start.split(".")
days=int(dataStart[0])
months=int(dataStart[1])
years=int(dataStart[2])
endYears=0
endMonths=0
endDays=0
dateStart = date(years, months, days)
while end>=365:
end-=365
endYears+=1
else:
while end>=30:
end-=30
endMonths+=1
else:
while end>=1:
end-=1
endDays+=1
dateEnd = date(endYears, endMonths, endDays)
For adding days into date, you need to user datetime.timedelta
start=str(input("type start date (DD.MM.YYYY)"))
end=int(input("how many days from it?"))
date = datetime.strptime(start, "%d.%m.%Y")
modified_date = date + timedelta(days=end)
print(datetime.strftime(modified_date, "%d.%m.%Y"))
You may use datetime.timedelta to add certain units of time to your datetime object.
See the answers here for code snippets: Adding 5 days to a date in Python
Alternatively, you may wish to use the third-party dateutil library if you need support for time additions in units larger than weeks. For example:
>>> from datetime import datetime
>>> from dateutil import relativedelta
>>> one_month_later = datetime(2017, 5, 1) + relativedelta.relativedelta(months=1)
>>> one_month_later
>>> datetime.datetime(2017, 6, 1, 0, 0)
It will be easier to convert to datetime using datetime.datetime.strptime and for the part about adding days just use datetime.timedelta.
Below is a small snippet on how to use it:
import datetime
start = "21.10.2000"
end = 8
dateStart = datetime.datetime.strptime(start, "%d.%m.%Y")
dateEnd = dateStart + datetime.timedelta(days=end)
dateEnd.date() # to get the date format of the endDate
If you have any doubts please look at the documentation python3/python2.

Converting datetime to timedelta so they can be added

When subtracting two datetime objects, I understand the result is timedelta object:
import datetime
AcDepart = 1900-01-01 18:00:00
AcArrival = 1900-01-01 07:00:00
ActualHours = AcDepart - AcArrival
I want to then subtract the sum of two other date time objects from ActualHours
These are the two other objects:
HrsEarly = 1900-01-01 02:00:00
HrsLate = 1900-01-01 00:30:00
This is the equation that fails to complete:
UnCalcTime = ActualHours - (HrsEarly + HrsLate)
This is the error:
UnCalcTime = ActualHours - (HrsEarly + HrsLate)
TypeError: unsupported operand type(s) for +: 'datetime.datetime' and 'datetime.datetime'
So, I obviously can't add datetime.datetime. Does anyone know how I could get around this? Can timedelta be added together? If so, how can I convert datetime to timedelta?
Any help would be greatly appreciated as I have been trying to solve this unsuccessfully for a long time.
The best solution is to create your variables as timedelta in the first place.
HrsEarly = datetime.timedelta(hours=2)
HrsLate = datetime.timedelta(minutes=30)
If you can't do that, you can simply subtract your "zero date" from the datetime objects.
>>> HrsEarly
datetime.datetime(1900, 1, 1, 2, 0)
>>> HrsEarly = HrsEarly - datetime.datetime(1900, 1, 1)
>>> HrsEarly
datetime.timedelta(0, 7200)
Convert the string to timedelta
from datetime import datetime
AcDepart = '1900-01-01 18:00:00'
AcDepart_ = datetime.strptime(AcDepart, '%Y-%m-%d %H:%M:%S')
AcArrival = '1900-01-01 07:00:00'
AcArrival_ = datetime.strptime(AcArrival, '%Y-%m-%d %H:%M:%S')
ActualHours = (AcDepart_ - AcArrival_).total_seconds()/3600
print ActualHours
It makes no sense to add two datetime objects: It might seem, in your example, that "2AM on the 1st of January 1900" plus "half past midnight on the 1st of January 1900" should be "half past two on the 1st of January 1900", but in another context the desired result could as easily be "half past two on the 2nd of February 3800", or even (if the UNIX epoch is used as an origin) "half past two on the first of January 1830".
Looking at a different example might make this more obvious: what should be the result of Tuesday + Saturday?
Your HrsEarly and HrsLate variables are presumably meant to store a time difference, and there's an appropriate type for that: datetime.timedelta. Adding two of those together does what you want:
>>> from datetime import timedelta
>>> HrsEarly = timedelta(hours=2)
>>> HrsLate = timedelta(minutes=30)
>>> HrsTotal = (HrsEarly + HrsLate)
>>> str(HrsTotal)
'2:30:00'
How about this method using built-in timestamp function?
import datetime
a = "2017-01-01 14:30:00"
b = datetime.datetime.strptime(a, '%Y-%m-%d %H:%M:%S')
c = b.timestamp()
d = datetime.timedelta(seconds=c)
Runtime environment
  OS: Ubuntu 16.04
  Python 3.6
Create a modules.py and paste the following two functions. Import them wherever you want and use as is.
import datetime
def JsTimestampToPyDatetime(js_date):
"""
converts javascript timestamp to python datetime taking care of
milliseconds and seconds
Args:
js_date(Timestamp, required)
Returns:
Datetime
"""
try:
# handles seconds
date = datetime.datetime.fromtimestamp(int(js_date))
except (ValueError):
# handles miliseconds
date = datetime.datetime.fromtimestamp(int(js_date) / 1000)
return date
# consuming javascript generated timestamps
a = JsTimestampToPyDatetime(1627303810000) # with miliseconds
b = JsTimestampToPyDatetime(1627476610) # with seconds only
def GetDaysInDateTime(min_stamp, max_stamp):
"""
Calculates time difference between two timestamps in days
Args:
min_stamp(Datetime, required): Minimum/start datetime
max_stamp(Datetime, required): Maximum/end datetime
Returns:
Int: Days
"""
days = (max_stamp-min_stamp).days
return int(days)
print(GetDaysInDateTime(a, b))

Python: format datetime efficiently whilst leaving it as a datetime object

I want to be able to format a datetime object, while leaving it as an object. I have worked a way to do it, but it doesn't seem very efficient.
My specific aim is to limit the extra digits on the seconds to 2. This is how I am currently doing it:
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
now_frmt = datetime.datetime.strptime(now, '%Y-%m-%d %H:%M:%S')
Cheers,
JJ
You could do this to subtract off the microseconds:
now = datetime.datetime.now()
now_frmt = now - datetime.timedelta(microseconds=now.microsecond)
To round to the nearest second you can do the following:
now = datetime.datetime.now()
delta = (0 if now.microsecond < 500000 else 1000000) - now.microsecond
now_frmt = now + datetime.timedelta(microseconds=delta)

Categories

Resources