Datetime Module and Timedelta - python-3.x

I need to add onehour to the currenttime and subtract it with the minutes, e
For example:current time = 7:31,addedhour = 7:31 + 1 hour = 8:31,required time = 8:31 - 31 = 8:00
Any help or a workaround will be greatly appreciated.
from datetime import datetime, timedelta
import time
addedtime = (datetime.now() + timedelta(hours=1)).strftime('%H:%M')
requiredtime = addedtime - timedelta(now.minutes).strftime('%H:%M')

You're setting addedtime to a string rather than a datetime, then getting into trouble because you're trying to subtract a timedelta from that string:
>>> addedtime = (datetime.now() + timedelta(hours=1)).strftime('%H:%M')
>>> addedtime
'23:30'
>>> addedtime - timedelta(minutes=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'str' and 'datetime.timedelta'
Instead, keep them as timepoints for as long as you need to manipulate them as timepoints, converting them to a string when you need the final result:
>>> time1 = datetime.now()
>>> time1
datetime.datetime(2019, 10, 17, 22, 23, 55, 860195)
>>> time2 = time1 + timedelta(hours=1)
>>> time2
datetime.datetime(2019, 10, 17, 23, 23, 55, 860195)
>>> time3 = time2 - timedelta(minutes=time2.minute)
>>> time3
datetime.datetime(2019, 10, 17, 23, 0, 55, 860195)
>>> time3.strftime("%H:%M")
'23:00'
Of course, you can also do it as a single operation since you can both add one hour and subtract some minutes with a single timedelta:
>>> final = (time1 + timedelta(hours=1, minutes=-time1.minute)).strftime("%H:%M")
>>> final
'23:00'

Why not explore one of Python's many amazing datetime libraries ...
pip install parsedatetime
import parsedatetime as pdt
from datetime import datetime
if __name__ == '__main__':
cal = pdt.Calendar()
dt, result = cal.parse("10 minutes before an hour from now")
print(datetime(*dt[:6]))

Related

TypeError: cannot convert the series to <class 'int'> in to_date

As the error says
Traceback (most recent call last):
File "E:\fakepath\pythonCSV\main.py", line 84, in <module>
print(to_date(df['start_time']))
File "E:\fakepath\pythonCSV\main.py", line 75, in to_date
return datetime.strftime(datetime.fromtimestamp(int(x)/1000).strftime("%d-%b-%Y"), "%d-%b-%Y")
File "C:\Users\%username%\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\series.py", line 141, in wrapper
raise TypeError(f"cannot convert the series to {converter}")
TypeError: cannot convert the series to <class 'int'>
And my code is:
import pandas as pd
import glob
from datetime import datetime, timedelta
from pymongo import MongoClient
client = MongoClient()
col = client['right']['abcde']
listFileNames = (glob.glob(r"C:\Users\%username%\Desktop\Book1.csv"))
# print(len(listFileNames))
cols = ["start_time", "end_time", "source_Ip", "source_Mac", "destination_Ip", "destination_Mac"]
def get_merged_data_frame(list_file_names, p_index_col=False, p_header=None, columns=None):
if columns is None:
columns = cols
if len(list_file_names) == 1:
return pd.read_csv(list_file_names[0], index_col=p_index_col, header=p_header, low_memory=False,
names=columns,
usecols=[6, 7, 8, 9, 10, 11])
else:
df_from_each_file = (pd.read_csv(f, index_col=p_index_col, header=p_header, low_memory=False, names=columns,
usecols=[6, 7, 8, 9, 10, 11])
for f in list_file_names)
concatenated_df = pd.concat(df_from_each_file, ignore_index=True)
return concatenated_df
def to_date(x):
return datetime.strftime(datetime.fromtimestamp(int(x)/1000).strftime("%d-%b-%Y"), "%d-%b-%Y")
df = get_merged_data_frame(listFileNames)
print(df)
df['start_data'] = df['start_time'].apply(to_date)
print(to_date(df['start_time']))
print(type(df))
print(df)
data = df.to_dict(orient='records')
print(data)
col.insert_many(data)
I have tried many solutions, I have tried but I don't where I have put is it right?
Many of the solution says to use .astype(int) or .astype(float)
df['start_data'] = df['start_time'].astype(int)
This df['start_time'] looks like this
0 1617213592022005000
1 1617213592064079000
Name: start_time, Length: 3960, dtype: int64
But it seems to be wrong...
Thanks for Any Answers...
You can try for a string representation (like your function to_date)
df['start_data'] = pd.to_datetime(df['start_time'], unit='ns') \
.dt.strftime("%d-%b-%Y")
>>> df
start_time start_data
0 1617213592022005000 31-Mar-2021
1 1617213592064079000 31-Mar-2021

Python strptime cannot understand timezone offset

I have a very simple timestamp I need to parse:
10/2/2020 3:19:42 PM (UTC-7)
But using python 3.6, when I try to parse this, I get the following:
>>> datetime.strptime('10/2/2020 3:19:42 PM (UTC-7)', '%m/%d/%Y %I:%M:%S %p (%Z%z)')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "_strptime.py", line 565, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "_strptime.py", line 362, in _strptime
(data_string, format))
ValueError: time data '10/2/2020 3:19:42 PM (UTC-7)' does not match format '%m/%d/%Y %I:%M:%S %p (%Z%z)'
I have tried dateutil.parser, as well as several variations of the format string. The piece that's tripping up strptime is the (UTC-7) portion.
Is the string format wrong? How can I parse this string and receive the timezone information as well? Any help is appreciated.
Edit: If the string is (UTC-0700) then the parsing works. But I cannot control how the timestamps are being formatted, is there a way to parse them in their current format (UTC-7)?
Ah, it turned out to be quite silly:
>>> import dateutil
>>> dateutil.parser.parse(dt, fuzzy=True)
datetime.datetime(2020, 10, 2, 15, 19, 42, tzinfo=tzoffset(None, 25200))
Should have used fuzzy logic before. :-)
EDIT: The above does NOT work (thanks to #wim for pointing it out) - Fuzzy flag is ignoring the sign of the offset string.
Here is code that works:
>>> from datetime import datetime
>>> import re
>>> dt = '10/2/2020 3:19:42 PM (UTC-7)'
>>> sign, offset = re.search('\(UTC([+-])(\d+)\)', dt).groups()
>>> offset = f"0{offset}00" if len(offset) == 1 else f"{offset}00"
>>> dt = re.sub(r'\(UTC.\d+\)', f'(UTC{sign}{offset})', dt)
>>> datetime.strptime(dt, '%m/%d/%Y %I:%M:%S %p (%Z%z)')
datetime.datetime(2020, 10, 2, 15, 19, 42, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200), 'UTC'))

Why time.mktime returns different result on windows and linux for same input?

time.mktime behaves differently on windows and linux.
For a datetime value '0001-01-01 00:00:00' , on windows it throws exception "OverflowError: mktime argument out of range" while on Linux it does not throw any exception and returns an incorrect (-ve) value.
on windows -
>>> from dateutil.parser import parse
>>> dt = parse('0001-01-01 00:00:00')
>>> dt
datetime.datetime(1, 1, 1, 0, 0)
>>> time.mktime(dt.timetuple())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: mktime argument out of range
On Linux
>>> from dateutil.parser import parse
>>> dt = parse('0001-01-01 00:00:00')
>>> dt
datetime.datetime(1, 1, 1, 0, 0)
>>> time.mktime(dt.timetuple())
-62135596800.0
any pointer as to why same function is behaving differently on windows and Linux is appreciated.
The underlying C libraries for mktime used by the Python implementations for Windows and Linux are different.
As the documentation points out:
The earliest date for which it (mktime) can generate a time is
platform-dependent.

AMZN stock data retrieval with YahooDailyReader

Up until 30 minutes ago I was executing the following code without problems:
import pandas_datareader.data as web
import datetime
start = datetime.datetime(2012,1,1)
end = datetime.datetime(2015,12,31)
AAPL = web.get_data_yahoo('AAPL', start, end)
AMZN = web.get_data_yahoo('AMZN', start, end)
Instead now I get:
Traceback (most recent call last):
File "/Users/me/opt/anaconda3/lib/python3.7/site-packages/pandas_datareader/yahoo/daily.py", line 157, in _read_one_data
data = j["context"]["dispatcher"]["stores"]["HistoricalPriceStore"]
KeyError: 'HistoricalPriceStore'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/me/opt/anaconda3/lib/python3.7/site-packages/pandas_datareader/data.py", line 82, in get_data_yahoo
return YahooDailyReader(*args, **kwargs).read()
File "/Users/me/opt/anaconda3/lib/python3.7/site-packages/pandas_datareader/base.py", line 251, in read
df = self._read_one_data(self.url, params=self._get_params(self.symbols))
File "/Users/me/opt/anaconda3/lib/python3.7/site-packages/pandas_datareader/yahoo/daily.py", line 160, in _read_one_data
raise RemoteDataError(msg.format(symbol, self.__class__.__name__))
pandas_datareader._utils.RemoteDataError: No data fetched for symbol AMZN using YahooDailyReader
How can I fix this?
Is there a work around to get the AMZN data as DataFrame from another source (different from Yahoo_Daily_Reader)?
Python version 3.4.7
How about this solution?
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.optimize as sco
import datetime as dt
import math
from datetime import datetime, timedelta
from pandas_datareader import data as wb
from sklearn.cluster import KMeans
np.random.seed(777)
start = '2019-4-30'
end = '2019-10-31'
# N = 90
# start = datetime.now() - timedelta(days=N)
# end = dt.datetime.today()
tickers = ['MMM',
'ABT',
'AAPL',
'AMAT',
'APTV',
'ADM',
'ARNC',
'AMZN']
thelen = len(tickers)
price_data = []
for ticker in tickers:
prices = wb.DataReader(ticker, start = start, end = end, data_source='yahoo')[['Adj Close']]
price_data.append(prices.assign(ticker=ticker)[['ticker', 'Adj Close']])
df = pd.concat(price_data)
df.dtypes
df.head()
df.shape
pd.set_option('display.max_columns', 500)
df = df.reset_index()
df = df.set_index('Date')
table = df.pivot(columns='ticker')
# By specifying col[1] in below list comprehension
# You can select the stock names under multi-level column
table.columns = [col[1] for col in table.columns]
table.head()
plt.figure(figsize=(14, 7))
for c in table.columns.values:
plt.plot(table.index, table[c], lw=3, alpha=0.8,label=c)
plt.legend(loc='upper left', fontsize=12)
plt.ylabel('price in $')

Cannot convert from an iterable of Python `datetime` objects to an array of Numpy `datetime64` objects using `fromiter()`. Bug?

I'm using Python 3.6.2.
I've learnt from this question how to convert between the standard datetime type to np.datetime64 type, as follows.
dt = datetime.now()
print(dt)
print(np.datetime64(dt))
Output:
2017-12-19 17:20:12.743969
2017-12-19T17:20:12.743969
But I can't convert an iterable of standard datetime objects into a Numpy array. The following code ...
np.fromiter([dt], dtype=np.datetime64)
... gives the following error.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-46e4618bda89> in <module>()
----> 1 np.fromiter([dt], dtype=np.datetime64)
TypeError: Cannot cast datetime.datetime object from metadata [us] to according to the rule 'same_kind'
However, using np.asarray() works.
np.asarray([dt])
Output:
array([datetime.datetime(2017, 12, 19, 17, 20, 12, 743969)], dtype=object)
Might this be a bug with either np.fromiter() or np.datetime64?
It may just be a matter of setting the datetime units:
In [368]: dt = datetime.now()
In [369]: dt
Out[369]: datetime.datetime(2017, 12, 19, 12, 48, 45, 143287)
Default action for np.array (don't really need fromiter with a list) is to create an object dtype array:
In [370]: np.array([dt,dt])
Out[370]:
array([datetime.datetime(2017, 12, 19, 12, 48, 45, 143287),
datetime.datetime(2017, 12, 19, 12, 48, 45, 143287)], dtype=object)
Looks like plain 'datetime64' produces days:
In [371]: np.array([dt,dt], dtype='datetime64')
Out[371]: array(['2017-12-19', '2017-12-19'], dtype='datetime64[D]')
and specifying the units:
In [373]: np.array([dt,dt], dtype='datetime64[m]')
Out[373]: array(['2017-12-19T12:48', '2017-12-19T12:48'], dtype='datetime64[m]')
This also works with fromiter.
In [374]: np.fromiter([dt,dt], dtype='datetime64[m]')
Out[374]: array(['2017-12-19T12:48', '2017-12-19T12:48'], dtype='datetime64[m]')
In [384]: x= np.fromiter([dt,dt], dtype='M8[us]')
In [385]: x
Out[385]: array(['2017-12-19T12:48:45.143287', '2017-12-19T12:48:45.143287'], dtype='datetime64[us]')
I've learned to use the string name of the datetime64, which allows me to specify the units, rather than the most generic np.datetime64.

Resources