Is it possible to write date values using pywin32 to Excel without the time? Even though the datetime object I create has no time nor UTC associated to it, when writing the value to Excel it still adds an hour component which is related to UTC. How can I solve this simple problem?
import win32com.client
from datetime import datetime
excel = win32com.client.Dispatch('Excel.Application')
excel.Visible = True
wb = excel.Workbooks.Add()
ws = wb.Sheets['Sheet1']
# Writes '01/01/2019 03:00:00' instead of '01/01/2019'
ws.Cells(1, 1).Value = datetime(2019, 1, 1)
If you just want the date with no time of day, you can call datatime.date() to get it. Unfortunately the value must be converted to a string because the win32com.client won't accept a datetime.date object directly.
# Writes '1/1/2019'
ws.Cells(1, 1).Value = str(datetime(2019, 1, 1).date())
Update:
You can workaround the cell having a text entry by assigning an Excel formula to the cell instead. Doing this will allow you to use the cell more easily in conjunction with other formulas and its other capabilities (such as sorting, charting, etc).
# Writes 1/1/2019
ws.Cells(1, 1).Formula = datetime(2019, 1, 1).strftime('=DATE(%Y,%m,%d)')
Related
Question about formatting data when writing to an Excel doc as I am a bit newer to using Openpyxl.
I have an excel sheet that I am writing data to where one of the columns is a column that holds the current date in 'mm/dd/yyyy' format. Currently when writing to the Excel doc, my code reformats the date to 'yyyy-mm-dd' format, and the excel doc does not recognize the data as 'Date' type, but as 'General' data type.
Here is my Python code to write the date to the sheet.
from openpyxl import Workbook
from openpyxl import load_workbook
from date time import date
workbookName = "Excel workbook.xlsm"
wb = Workbook()
wb = load_workbook(workbookName, data_only=True, keep_vba=True)
ws = wb["Sheet1"]
rowCount = 2000
insertRow = rowCount + 7
origDate = date.today()
dateString = datetime.datetime.strftime(origDate, '%m/%d/%Y')
insertDate = datetime.datetime.strptime(dateString, '%m/%d/%Y').date()
dateCell = ws.cell(row = insertRow, column = 1)
dateCell.value = insertDate
wb.save("Excel workbook.xlsm")
So for example, if I ran this code using today's date of 03/19/2021, the cell would look like 2021-03-18 with General type.
Not sure what I am missing, but I want the inserted cell to have 'Date' type in 'mm/dd/yyyy' format. Any pointers?
I think this can be done simply with:
dateCell.value = origDate
dateCell.number_format = 'mm/dd/yyyy'
Note that there's no such thing as a date data type in Excel. A date is just a formatted number. "Date" (and "General" for that matter) are just formatting; the underlying value of the cell is separate and unchanged.
Though if you really want the cell to show as having a "Date" format and not "Custom", perhaps:
dateCell.number_format = 'mm/dd/yyyy;#'
I have a data set where one column is a captured time as a UNIX epoch. I'd like to mangle that with openpyxl into a specific format: in my case I want MM/DD MM:SS where "June 14 2020 03:05:07 PM" would display as 06/14 15:05.
define a NamedStyle that represents the output format you want.
use iter_cols (any other iterator) to loop over the cells you want to format.
create a python datetime object from the value in that cell
openpyxl has a library to convert UNIX datetimes to excel datetimes (excel uses some nonstandard format, of course...)
apply the desired style to each cell.
# ws is an existing openpyxl Worksheet instance
custom_datetime = openpyxl.styles.NamedStyle(name='datetime', number_format='MM/DD HH:MM')
for col in ws.iter_cols(min_row=2, min_col=1, max_col=1):
for cell in col:
dt = datetime.datetime.fromtimestamp(cell.value)
cell.value = openpyxl.utils.datetime.to_excel(dt)
cell.style = custom_datetime
I am trying to read duration field from Excel file, but instead of timedelta type I get datetime type. So when duration value is more than 24 hours, python openpyxl reads that field not correctly. Is there a right way to read duration field with Python openpyxl?
import openpyxl
workbook = openpyxl.load_workbook('./files/file.xlsx')
worksheet = workbook.active
cell = worksheet.cell(row=2, column=9)
print(cell.value)
Cell (row=2, column=9) value in excel file is 38:12:40, but printed output:
1900-01-01 14:12:40
Cell format code in excel file - [HH]:MM:SS
I think this solution will work for you, maybe you need to adjust the format but the type is timedelta
cell = worksheet.cell(row=1, column=1)
print(cell.value) #1900-01-01 14:12:40
s = cell.value-datetime.datetime(1899,12,30)
print(s) #2 days, 14:12:40
print(type(s)) #<class 'datetime.timedelta'>
The problem is that Excel have a custom type and when you put that format, it will convert it for that one starting in 1900
I have a script that goes and collects data. I am running into the TypeError: Timestamp subtraction must have the same timezones or no timezones error. I have looked at other postings on this error, but had trouble finding a solution for me.
How can I bypass this error. Once the data is collected, I don't manipulate it and I don't quite understand why I cannot save this dataframe into an excel document. Can anyone offer help?
import pandas as pd
import numpy as np
import os
import datetime
import pvlib
from pvlib.forecast import GFS, NAM
#directories and filepaths
barnwell_dir = r'D:\Saurabh\Production Forecasting\Machine Learning\Sites\Barnwell'
barnwell_training = r'8760_barnwell.xlsx'
#constants
writer = pd.ExcelWriter('test' + '_PythonExport.xlsx', engine='xlsxwriter')
time_zone = 'Etc/GMT+5'
barnwell_list = [r'8760_barnwell.xlsx', 33.2376, -81.3510]
def get_gfs_processed_data1():
start = pd.Timestamp(datetime.date.today(), tz=time_zone) #used for testing last week
end = start + pd.Timedelta(days=6)
gfs = GFS(resolution='quarter')
#get processed data for lat/long point
forecasted_data = gfs.get_processed_data(barnwell_list[1], barnwell_list[2], start, end)
forecasted_data.to_excel(writer, sheet_name='Sheet1')
get_gfs_processed_data1()
When I run your sample code I get the following warning from XlsxWriter at the end of the stacktrace:
"Excel doesn't support timezones in datetimes. "
TypeError: Excel doesn't support timezones in datetimes.
Set the tzinfo in the datetime/time object to None or use the
'remove_timezone' Workbook() option
I think that is reasonably self-explanatory. To strip the timezones from the timestamps pass the remove_timezone option as recommended:
writer = pd.ExcelWriter('test' + '_PythonExport.xlsx',
engine='xlsxwriter',
options={'remove_timezone': True})
When I make this change the sample runs and produces an xlsx file. Note, the remove_timezone option requires XlsxWriter >= 0.9.5.
You can delete timezone from all your datetime columns like that:
for col in df.select_dtypes(['datetimetz']).columns:
df[col] = df[col].dt.tz_convert(None)
df.to_excel('test' + '_PythonExport.xlsx')
after that you save excel without any problem
Note:
To select Pandas datetimetz dtypes, use 'datetimetz' (new in 0.20.0)
or 'datetime64[ns, tz]'
In an Excel cell I call function fff(DATE(2001,1,1)). To receive the date argument, I use (xlwings 0.10.0) the following code:
#xw.func
#xw.arg('req_date', dates=datetime.date) # I also tried datetime.datetime
def fff(req_date):
print req_date
which prints just a number, not datetime object. I solved the problem by calling
req_date = datetime.datetime(1899, 12, 30)
+ datetime.timedelta(days=req_date)
but I wonder what did I do wrong with the xlwings way?!
xlwings only performs the automatic transformation into a datetime object if the cell in Excel is formatted as a Date. That is, if you put =DATE(2001,1,1) into one cell and then in a different cell write =fff('A1'), it will work as you expect (assuming that the date formula is in A1).