[{"data":1,"prerenderedAt":1583},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-dates-in-excel-cells-with-python":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-dates-in-excel-cells-with-python":1576},{"id":4,"title":5,"body":6,"description":1568,"extension":1569,"meta":1570,"navigation":140,"path":1571,"seo":1572,"stem":1574,"__hash__":1575},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-dates-in-excel-cells-with-python\u002Findex.md","Format Dates in Excel Cells with Python",{"type":7,"value":8,"toc":1549},"minimark",[9,37,42,67,81,85,99,328,337,341,366,543,560,564,570,792,796,809,992,1020,1024,1042,1266,1278,1282,1389,1393,1408,1412,1417,1428,1432,1446,1450,1457,1461,1480,1484,1502,1506,1520,1524,1545],[10,11,12,13,17,18,22,23,26,27,30,31,36],"p",{},"Excel stores a date as a number — a serial count of days from a base date — and displays it through a format. If you write a ",[14,15,16],"em",{},"string"," like ",[19,20,21],"code",{},"\"2024-03-09\"",", Excel keeps text and cannot reformat it, sort it as a date, or do date math on it. The fix is to write a real Python ",[19,24,25],{},"date","\u002F",[19,28,29],{},"datetime"," so Excel stores a true serial, then set the display code. This guide, part of ",[32,33,35],"a",{"href":34},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002F","Applying Number and Date Formats in Excel",", is fully runnable.",[38,39,41],"h2",{"id":40},"prerequisites-and-install","Prerequisites and install",[43,44,49],"pre",{"className":45,"code":46,"language":47,"meta":48,"style":48},"language-bash shiki shiki-themes github-light github-dark","pip install openpyxl\n","bash","",[19,50,51],{"__ignoreMap":48},[52,53,56,60,64],"span",{"class":54,"line":55},"line",1,[52,57,59],{"class":58},"sScJk","pip",[52,61,63],{"class":62},"sZZnC"," install",[52,65,66],{"class":62}," openpyxl\n",[10,68,69,70,73,74,76,77,80],{},"For the pandas section: ",[19,71,72],{},"pip install pandas openpyxl",". The standard-library ",[19,75,29],{}," module is all you need for the core examples. ",[19,78,79],{},"openpyxl"," does not require Excel.",[38,82,84],{"id":83},"step-1-write-a-real-date-so-excel-stores-a-serial","Step 1: Write a real date so Excel stores a serial",[10,86,87,88,91,92,95,96,98],{},"Assign a ",[19,89,90],{},"datetime.date"," or ",[19,93,94],{},"datetime.datetime"," object directly. ",[19,97,79],{}," converts it to Excel's serial number and applies a default date format, which you then override with your own code.",[43,100,104],{"className":101,"code":102,"language":103,"meta":48,"style":48},"language-python shiki shiki-themes github-light github-dark","from datetime import date, datetime\nfrom openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nws.append([\"Event\", \"When\"])\nws.append([\"Invoice issued\", date(2024, 3, 9)])\nws.append([\"Logged at\", datetime(2024, 3, 9, 14, 30)])\n\nws[\"B2\"].number_format = \"yyyy-mm-dd\"        # 2024-03-09\nws[\"B3\"].number_format = \"yyyy-mm-dd hh:mm\"  # 2024-03-09 14:30\n\nwb.save(\"dates_basic.xlsx\")\nprint(\"B2 is a real date:\", ws[\"B2\"].value)  # datetime.date(2024, 3, 9)\n","python",[19,105,106,122,135,142,154,165,183,211,244,249,270,288,293,305],{"__ignoreMap":48},[52,107,108,112,116,119],{"class":54,"line":55},[52,109,111],{"class":110},"szBVR","from",[52,113,115],{"class":114},"sVt8B"," datetime ",[52,117,118],{"class":110},"import",[52,120,121],{"class":114}," date, datetime\n",[52,123,125,127,130,132],{"class":54,"line":124},2,[52,126,111],{"class":110},[52,128,129],{"class":114}," openpyxl ",[52,131,118],{"class":110},[52,133,134],{"class":114}," Workbook\n",[52,136,138],{"class":54,"line":137},3,[52,139,141],{"emptyLinePlaceholder":140},true,"\n",[52,143,145,148,151],{"class":54,"line":144},4,[52,146,147],{"class":114},"wb ",[52,149,150],{"class":110},"=",[52,152,153],{"class":114}," Workbook()\n",[52,155,157,160,162],{"class":54,"line":156},5,[52,158,159],{"class":114},"ws ",[52,161,150],{"class":110},[52,163,164],{"class":114}," wb.active\n",[52,166,168,171,174,177,180],{"class":54,"line":167},6,[52,169,170],{"class":114},"ws.append([",[52,172,173],{"class":62},"\"Event\"",[52,175,176],{"class":114},", ",[52,178,179],{"class":62},"\"When\"",[52,181,182],{"class":114},"])\n",[52,184,186,188,191,194,198,200,203,205,208],{"class":54,"line":185},7,[52,187,170],{"class":114},[52,189,190],{"class":62},"\"Invoice issued\"",[52,192,193],{"class":114},", date(",[52,195,197],{"class":196},"sj4cs","2024",[52,199,176],{"class":114},[52,201,202],{"class":196},"3",[52,204,176],{"class":114},[52,206,207],{"class":196},"9",[52,209,210],{"class":114},")])\n",[52,212,214,216,219,222,224,226,228,230,232,234,237,239,242],{"class":54,"line":213},8,[52,215,170],{"class":114},[52,217,218],{"class":62},"\"Logged at\"",[52,220,221],{"class":114},", datetime(",[52,223,197],{"class":196},[52,225,176],{"class":114},[52,227,202],{"class":196},[52,229,176],{"class":114},[52,231,207],{"class":196},[52,233,176],{"class":114},[52,235,236],{"class":196},"14",[52,238,176],{"class":114},[52,240,241],{"class":196},"30",[52,243,210],{"class":114},[52,245,247],{"class":54,"line":246},9,[52,248,141],{"emptyLinePlaceholder":140},[52,250,252,255,258,261,263,266],{"class":54,"line":251},10,[52,253,254],{"class":114},"ws[",[52,256,257],{"class":62},"\"B2\"",[52,259,260],{"class":114},"].number_format ",[52,262,150],{"class":110},[52,264,265],{"class":62}," \"yyyy-mm-dd\"",[52,267,269],{"class":268},"sJ8bj","        # 2024-03-09\n",[52,271,273,275,278,280,282,285],{"class":54,"line":272},11,[52,274,254],{"class":114},[52,276,277],{"class":62},"\"B3\"",[52,279,260],{"class":114},[52,281,150],{"class":110},[52,283,284],{"class":62}," \"yyyy-mm-dd hh:mm\"",[52,286,287],{"class":268},"  # 2024-03-09 14:30\n",[52,289,291],{"class":54,"line":290},12,[52,292,141],{"emptyLinePlaceholder":140},[52,294,296,299,302],{"class":54,"line":295},13,[52,297,298],{"class":114},"wb.save(",[52,300,301],{"class":62},"\"dates_basic.xlsx\"",[52,303,304],{"class":114},")\n",[52,306,308,311,314,317,320,322,325],{"class":54,"line":307},14,[52,309,310],{"class":196},"print",[52,312,313],{"class":114},"(",[52,315,316],{"class":62},"\"B2 is a real date:\"",[52,318,319],{"class":114},", ws[",[52,321,257],{"class":62},[52,323,324],{"class":114},"].value)  ",[52,326,327],{"class":268},"# datetime.date(2024, 3, 9)\n",[10,329,330,333,334,336],{},[19,331,332],{},"ws[\"B2\"].value"," round-trips as a ",[19,335,25],{}," object, proving Excel holds a serial, not text.",[38,338,340],{"id":339},"step-2-choose-a-display-layout","Step 2: Choose a display layout",[10,342,343,344,26,347,350,351,26,354,357,358,361,362,365],{},"The same stored date can render many ways. Pick a code and assign it. ",[19,345,346],{},"m",[19,348,349],{},"d"," are unpadded, ",[19,352,353],{},"mm",[19,355,356],{},"dd"," are zero-padded, ",[19,359,360],{},"mmm"," is the short month name, and ",[19,363,364],{},"yyyy"," is the four-digit year.",[43,367,369],{"className":101,"code":368,"language":103,"meta":48,"style":48},"from datetime import date\nfrom openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nd = date(2024, 3, 9)\nfor row, code in enumerate([\"yyyy-mm-dd\", \"mmm d, yyyy\", \"dd\u002Fmm\u002Fyyyy\", \"d mmmm yyyy\"], start=1):\n    ws.cell(row=row, column=1, value=d).number_format = code\n\nwb.save(\"dates_layouts.xlsx\")\nprint(\"Same date serial, four display codes\")\n",[19,370,371,382,392,396,404,412,434,484,519,523,532],{"__ignoreMap":48},[52,372,373,375,377,379],{"class":54,"line":55},[52,374,111],{"class":110},[52,376,115],{"class":114},[52,378,118],{"class":110},[52,380,381],{"class":114}," date\n",[52,383,384,386,388,390],{"class":54,"line":124},[52,385,111],{"class":110},[52,387,129],{"class":114},[52,389,118],{"class":110},[52,391,134],{"class":114},[52,393,394],{"class":54,"line":137},[52,395,141],{"emptyLinePlaceholder":140},[52,397,398,400,402],{"class":54,"line":144},[52,399,147],{"class":114},[52,401,150],{"class":110},[52,403,153],{"class":114},[52,405,406,408,410],{"class":54,"line":156},[52,407,159],{"class":114},[52,409,150],{"class":110},[52,411,164],{"class":114},[52,413,414,417,419,422,424,426,428,430,432],{"class":54,"line":167},[52,415,416],{"class":114},"d ",[52,418,150],{"class":110},[52,420,421],{"class":114}," date(",[52,423,197],{"class":196},[52,425,176],{"class":114},[52,427,202],{"class":196},[52,429,176],{"class":114},[52,431,207],{"class":196},[52,433,304],{"class":114},[52,435,436,439,442,445,448,451,454,456,459,461,464,466,469,472,476,478,481],{"class":54,"line":185},[52,437,438],{"class":110},"for",[52,440,441],{"class":114}," row, code ",[52,443,444],{"class":110},"in",[52,446,447],{"class":196}," enumerate",[52,449,450],{"class":114},"([",[52,452,453],{"class":62},"\"yyyy-mm-dd\"",[52,455,176],{"class":114},[52,457,458],{"class":62},"\"mmm d, yyyy\"",[52,460,176],{"class":114},[52,462,463],{"class":62},"\"dd\u002Fmm\u002Fyyyy\"",[52,465,176],{"class":114},[52,467,468],{"class":62},"\"d mmmm yyyy\"",[52,470,471],{"class":114},"], ",[52,473,475],{"class":474},"s4XuR","start",[52,477,150],{"class":110},[52,479,480],{"class":196},"1",[52,482,483],{"class":114},"):\n",[52,485,486,489,492,494,497,500,502,504,506,509,511,514,516],{"class":54,"line":213},[52,487,488],{"class":114},"    ws.cell(",[52,490,491],{"class":474},"row",[52,493,150],{"class":110},[52,495,496],{"class":114},"row, ",[52,498,499],{"class":474},"column",[52,501,150],{"class":110},[52,503,480],{"class":196},[52,505,176],{"class":114},[52,507,508],{"class":474},"value",[52,510,150],{"class":110},[52,512,513],{"class":114},"d).number_format ",[52,515,150],{"class":110},[52,517,518],{"class":114}," code\n",[52,520,521],{"class":54,"line":246},[52,522,141],{"emptyLinePlaceholder":140},[52,524,525,527,530],{"class":54,"line":251},[52,526,298],{"class":114},[52,528,529],{"class":62},"\"dates_layouts.xlsx\"",[52,531,304],{"class":114},[52,533,534,536,538,541],{"class":54,"line":272},[52,535,310],{"class":196},[52,537,313],{"class":114},[52,539,540],{"class":62},"\"Same date serial, four display codes\"",[52,542,304],{"class":114},[10,544,545,546,176,549,176,552,555,556,559],{},"This writes ",[19,547,548],{},"2024-03-09",[19,550,551],{},"Mar 9, 2024",[19,553,554],{},"09\u002F03\u002F2024",", and ",[19,557,558],{},"9 March 2024"," — all from the identical stored value.",[38,561,563],{"id":562},"step-3-format-a-date-column-across-rows","Step 3: Format a date column across rows",[10,565,566,567,569],{},"Loop the date column and set one code on each data cell, skipping the header. Because every cell holds a real ",[19,568,25],{},", the format simply changes presentation.",[43,571,573],{"className":101,"code":572,"language":103,"meta":48,"style":48},"from datetime import date\nfrom openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nws.append([\"Invoice\", \"Due\"])\nfor n, d in [(\"INV-001\", date(2024, 1, 31)),\n             (\"INV-002\", date(2024, 2, 29)),\n             (\"INV-003\", date(2024, 3, 15))]:\n    ws.append([n, d])\n\nfor cell in ws[\"B\"][1:]:               # column B, skip header\n    cell.number_format = \"mmm d, yyyy\"\n\nwb.save(\"dates_column.xlsx\")\nprint(\"Formatted\", ws.max_row - 1, \"due dates\")\n",[19,574,575,585,595,599,607,615,629,660,684,707,712,716,742,752,756,766],{"__ignoreMap":48},[52,576,577,579,581,583],{"class":54,"line":55},[52,578,111],{"class":110},[52,580,115],{"class":114},[52,582,118],{"class":110},[52,584,381],{"class":114},[52,586,587,589,591,593],{"class":54,"line":124},[52,588,111],{"class":110},[52,590,129],{"class":114},[52,592,118],{"class":110},[52,594,134],{"class":114},[52,596,597],{"class":54,"line":137},[52,598,141],{"emptyLinePlaceholder":140},[52,600,601,603,605],{"class":54,"line":144},[52,602,147],{"class":114},[52,604,150],{"class":110},[52,606,153],{"class":114},[52,608,609,611,613],{"class":54,"line":156},[52,610,159],{"class":114},[52,612,150],{"class":110},[52,614,164],{"class":114},[52,616,617,619,622,624,627],{"class":54,"line":167},[52,618,170],{"class":114},[52,620,621],{"class":62},"\"Invoice\"",[52,623,176],{"class":114},[52,625,626],{"class":62},"\"Due\"",[52,628,182],{"class":114},[52,630,631,633,636,638,641,644,646,648,650,652,654,657],{"class":54,"line":185},[52,632,438],{"class":110},[52,634,635],{"class":114}," n, d ",[52,637,444],{"class":110},[52,639,640],{"class":114}," [(",[52,642,643],{"class":62},"\"INV-001\"",[52,645,193],{"class":114},[52,647,197],{"class":196},[52,649,176],{"class":114},[52,651,480],{"class":196},[52,653,176],{"class":114},[52,655,656],{"class":196},"31",[52,658,659],{"class":114},")),\n",[52,661,662,665,668,670,672,674,677,679,682],{"class":54,"line":213},[52,663,664],{"class":114},"             (",[52,666,667],{"class":62},"\"INV-002\"",[52,669,193],{"class":114},[52,671,197],{"class":196},[52,673,176],{"class":114},[52,675,676],{"class":196},"2",[52,678,176],{"class":114},[52,680,681],{"class":196},"29",[52,683,659],{"class":114},[52,685,686,688,691,693,695,697,699,701,704],{"class":54,"line":246},[52,687,664],{"class":114},[52,689,690],{"class":62},"\"INV-003\"",[52,692,193],{"class":114},[52,694,197],{"class":196},[52,696,176],{"class":114},[52,698,202],{"class":196},[52,700,176],{"class":114},[52,702,703],{"class":196},"15",[52,705,706],{"class":114},"))]:\n",[52,708,709],{"class":54,"line":251},[52,710,711],{"class":114},"    ws.append([n, d])\n",[52,713,714],{"class":54,"line":272},[52,715,141],{"emptyLinePlaceholder":140},[52,717,718,720,723,725,728,731,734,736,739],{"class":54,"line":290},[52,719,438],{"class":110},[52,721,722],{"class":114}," cell ",[52,724,444],{"class":110},[52,726,727],{"class":114}," ws[",[52,729,730],{"class":62},"\"B\"",[52,732,733],{"class":114},"][",[52,735,480],{"class":196},[52,737,738],{"class":114},":]:               ",[52,740,741],{"class":268},"# column B, skip header\n",[52,743,744,747,749],{"class":54,"line":295},[52,745,746],{"class":114},"    cell.number_format ",[52,748,150],{"class":110},[52,750,751],{"class":62}," \"mmm d, yyyy\"\n",[52,753,754],{"class":54,"line":307},[52,755,141],{"emptyLinePlaceholder":140},[52,757,759,761,764],{"class":54,"line":758},15,[52,760,298],{"class":114},[52,762,763],{"class":62},"\"dates_column.xlsx\"",[52,765,304],{"class":114},[52,767,769,771,773,776,779,782,785,787,790],{"class":54,"line":768},16,[52,770,310],{"class":196},[52,772,313],{"class":114},[52,774,775],{"class":62},"\"Formatted\"",[52,777,778],{"class":114},", ws.max_row ",[52,780,781],{"class":110},"-",[52,783,784],{"class":196}," 1",[52,786,176],{"class":114},[52,788,789],{"class":62},"\"due dates\"",[52,791,304],{"class":114},[38,793,795],{"id":794},"why-a-string-date-cannot-be-reformatted","Why a string date cannot be reformatted",[10,797,798,799,801,802,805,806,808],{},"If a cell holds the text ",[19,800,21],{},", applying a date ",[19,803,804],{},"number_format"," does nothing — there is no serial to reformat. Excel treats text as text. Detect and fix this by parsing the string back into a ",[19,807,25],{}," before writing.",[43,810,812],{"className":101,"code":811,"language":103,"meta":48,"style":48},"from datetime import datetime\nfrom openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\n\nws[\"A1\"] = \"2024-03-09\"                          # text — a date format would be ignored\nws[\"A2\"] = datetime.strptime(\"2024-03-09\", \"%Y-%m-%d\").date()  # real date\nws[\"A2\"].number_format = \"mmm d, yyyy\"\n\nprint(\"A1 type:\", type(ws[\"A1\"].value).__name__)  # str\nprint(\"A2 type:\", type(ws[\"A2\"].value).__name__)  # date\nwb.save(\"dates_text_vs_real.xlsx\")\n",[19,813,814,825,835,839,847,855,859,877,910,922,926,957,983],{"__ignoreMap":48},[52,815,816,818,820,822],{"class":54,"line":55},[52,817,111],{"class":110},[52,819,115],{"class":114},[52,821,118],{"class":110},[52,823,824],{"class":114}," datetime\n",[52,826,827,829,831,833],{"class":54,"line":124},[52,828,111],{"class":110},[52,830,129],{"class":114},[52,832,118],{"class":110},[52,834,134],{"class":114},[52,836,837],{"class":54,"line":137},[52,838,141],{"emptyLinePlaceholder":140},[52,840,841,843,845],{"class":54,"line":144},[52,842,147],{"class":114},[52,844,150],{"class":110},[52,846,153],{"class":114},[52,848,849,851,853],{"class":54,"line":156},[52,850,159],{"class":114},[52,852,150],{"class":110},[52,854,164],{"class":114},[52,856,857],{"class":54,"line":167},[52,858,141],{"emptyLinePlaceholder":140},[52,860,861,863,866,869,871,874],{"class":54,"line":185},[52,862,254],{"class":114},[52,864,865],{"class":62},"\"A1\"",[52,867,868],{"class":114},"] ",[52,870,150],{"class":110},[52,872,873],{"class":62}," \"2024-03-09\"",[52,875,876],{"class":268},"                          # text — a date format would be ignored\n",[52,878,879,881,884,886,888,891,893,895,898,901,904,907],{"class":54,"line":213},[52,880,254],{"class":114},[52,882,883],{"class":62},"\"A2\"",[52,885,868],{"class":114},[52,887,150],{"class":110},[52,889,890],{"class":114}," datetime.strptime(",[52,892,21],{"class":62},[52,894,176],{"class":114},[52,896,897],{"class":62},"\"%Y-%m-",[52,899,900],{"class":196},"%d",[52,902,903],{"class":62},"\"",[52,905,906],{"class":114},").date()  ",[52,908,909],{"class":268},"# real date\n",[52,911,912,914,916,918,920],{"class":54,"line":246},[52,913,254],{"class":114},[52,915,883],{"class":62},[52,917,260],{"class":114},[52,919,150],{"class":110},[52,921,751],{"class":62},[52,923,924],{"class":54,"line":251},[52,925,141],{"emptyLinePlaceholder":140},[52,927,928,930,932,935,937,940,943,945,948,951,954],{"class":54,"line":272},[52,929,310],{"class":196},[52,931,313],{"class":114},[52,933,934],{"class":62},"\"A1 type:\"",[52,936,176],{"class":114},[52,938,939],{"class":196},"type",[52,941,942],{"class":114},"(ws[",[52,944,865],{"class":62},[52,946,947],{"class":114},"].value).",[52,949,950],{"class":196},"__name__",[52,952,953],{"class":114},")  ",[52,955,956],{"class":268},"# str\n",[52,958,959,961,963,966,968,970,972,974,976,978,980],{"class":54,"line":290},[52,960,310],{"class":196},[52,962,313],{"class":114},[52,964,965],{"class":62},"\"A2 type:\"",[52,967,176],{"class":114},[52,969,939],{"class":196},[52,971,942],{"class":114},[52,973,883],{"class":62},[52,975,947],{"class":114},[52,977,950],{"class":196},[52,979,953],{"class":114},[52,981,982],{"class":268},"# date\n",[52,984,985,987,990],{"class":54,"line":295},[52,986,298],{"class":114},[52,988,989],{"class":62},"\"dates_text_vs_real.xlsx\"",[52,991,304],{"class":114},[10,993,994,997,998,1001,1002,1005,1006,1008,1009,1011,1012,1015,1016,1019],{},[19,995,996],{},"A1"," stays a ",[19,999,1000],{},"str","; ",[19,1003,1004],{},"A2"," is a real ",[19,1007,25],{}," that now displays as ",[19,1010,551],{},". Always parse incoming string dates with ",[19,1013,1014],{},"datetime.strptime"," (or ",[19,1017,1018],{},"pandas.to_datetime",") before writing.",[38,1021,1023],{"id":1022},"handling-pandas-datetime-columns-on-export","Handling pandas datetime columns on export",[10,1025,1026,1027,1030,1031,1034,1035,1037,1038,1041],{},"pandas writes proper datetime cells when the column dtype is ",[19,1028,1029],{},"datetime64",", so the values arrive as real serials. But ",[19,1032,1033],{},"to_excel"," applies a default format; reopen with ",[19,1036,79],{}," to set your own. If your column is still strings, convert it with ",[19,1039,1040],{},"pd.to_datetime"," first.",[43,1043,1045],{"className":101,"code":1044,"language":103,"meta":48,"style":48},"import pandas as pd\nfrom openpyxl import load_workbook\n\ndf = pd.DataFrame({\n    \"Invoice\": [\"INV-001\", \"INV-002\"],\n    \"Due\": [\"2024-01-31\", \"2024-02-29\"],     # strings on purpose\n})\ndf[\"Due\"] = pd.to_datetime(df[\"Due\"])         # convert to real datetimes\ndf.to_excel(\"pandas_dates.xlsx\", index=False, sheet_name=\"Invoices\")\n\nwb = load_workbook(\"pandas_dates.xlsx\")\nws = wb[\"Invoices\"]\nfor cell in ws[\"B\"][1:]:                       # Due is column B\n    cell.number_format = \"dd\u002Fmm\u002Fyyyy\"\n\nwb.save(\"pandas_dates.xlsx\")\nprint(\"Converted, exported, and reformatted the Due column\")\n",[19,1046,1047,1060,1071,1075,1085,1102,1123,1128,1150,1180,1184,1197,1211,1233,1242,1246,1254],{"__ignoreMap":48},[52,1048,1049,1051,1054,1057],{"class":54,"line":55},[52,1050,118],{"class":110},[52,1052,1053],{"class":114}," pandas ",[52,1055,1056],{"class":110},"as",[52,1058,1059],{"class":114}," pd\n",[52,1061,1062,1064,1066,1068],{"class":54,"line":124},[52,1063,111],{"class":110},[52,1065,129],{"class":114},[52,1067,118],{"class":110},[52,1069,1070],{"class":114}," load_workbook\n",[52,1072,1073],{"class":54,"line":137},[52,1074,141],{"emptyLinePlaceholder":140},[52,1076,1077,1080,1082],{"class":54,"line":144},[52,1078,1079],{"class":114},"df ",[52,1081,150],{"class":110},[52,1083,1084],{"class":114}," pd.DataFrame({\n",[52,1086,1087,1090,1093,1095,1097,1099],{"class":54,"line":156},[52,1088,1089],{"class":62},"    \"Invoice\"",[52,1091,1092],{"class":114},": [",[52,1094,643],{"class":62},[52,1096,176],{"class":114},[52,1098,667],{"class":62},[52,1100,1101],{"class":114},"],\n",[52,1103,1104,1107,1109,1112,1114,1117,1120],{"class":54,"line":167},[52,1105,1106],{"class":62},"    \"Due\"",[52,1108,1092],{"class":114},[52,1110,1111],{"class":62},"\"2024-01-31\"",[52,1113,176],{"class":114},[52,1115,1116],{"class":62},"\"2024-02-29\"",[52,1118,1119],{"class":114},"],     ",[52,1121,1122],{"class":268},"# strings on purpose\n",[52,1124,1125],{"class":54,"line":185},[52,1126,1127],{"class":114},"})\n",[52,1129,1130,1133,1135,1137,1139,1142,1144,1147],{"class":54,"line":213},[52,1131,1132],{"class":114},"df[",[52,1134,626],{"class":62},[52,1136,868],{"class":114},[52,1138,150],{"class":110},[52,1140,1141],{"class":114}," pd.to_datetime(df[",[52,1143,626],{"class":62},[52,1145,1146],{"class":114},"])         ",[52,1148,1149],{"class":268},"# convert to real datetimes\n",[52,1151,1152,1155,1158,1160,1163,1165,1168,1170,1173,1175,1178],{"class":54,"line":246},[52,1153,1154],{"class":114},"df.to_excel(",[52,1156,1157],{"class":62},"\"pandas_dates.xlsx\"",[52,1159,176],{"class":114},[52,1161,1162],{"class":474},"index",[52,1164,150],{"class":110},[52,1166,1167],{"class":196},"False",[52,1169,176],{"class":114},[52,1171,1172],{"class":474},"sheet_name",[52,1174,150],{"class":110},[52,1176,1177],{"class":62},"\"Invoices\"",[52,1179,304],{"class":114},[52,1181,1182],{"class":54,"line":251},[52,1183,141],{"emptyLinePlaceholder":140},[52,1185,1186,1188,1190,1193,1195],{"class":54,"line":272},[52,1187,147],{"class":114},[52,1189,150],{"class":110},[52,1191,1192],{"class":114}," load_workbook(",[52,1194,1157],{"class":62},[52,1196,304],{"class":114},[52,1198,1199,1201,1203,1206,1208],{"class":54,"line":290},[52,1200,159],{"class":114},[52,1202,150],{"class":110},[52,1204,1205],{"class":114}," wb[",[52,1207,1177],{"class":62},[52,1209,1210],{"class":114},"]\n",[52,1212,1213,1215,1217,1219,1221,1223,1225,1227,1230],{"class":54,"line":295},[52,1214,438],{"class":110},[52,1216,722],{"class":114},[52,1218,444],{"class":110},[52,1220,727],{"class":114},[52,1222,730],{"class":62},[52,1224,733],{"class":114},[52,1226,480],{"class":196},[52,1228,1229],{"class":114},":]:                       ",[52,1231,1232],{"class":268},"# Due is column B\n",[52,1234,1235,1237,1239],{"class":54,"line":307},[52,1236,746],{"class":114},[52,1238,150],{"class":110},[52,1240,1241],{"class":62}," \"dd\u002Fmm\u002Fyyyy\"\n",[52,1243,1244],{"class":54,"line":758},[52,1245,141],{"emptyLinePlaceholder":140},[52,1247,1248,1250,1252],{"class":54,"line":768},[52,1249,298],{"class":114},[52,1251,1157],{"class":62},[52,1253,304],{"class":114},[52,1255,1257,1259,1261,1264],{"class":54,"line":1256},17,[52,1258,310],{"class":196},[52,1260,313],{"class":114},[52,1262,1263],{"class":62},"\"Converted, exported, and reformatted the Due column\"",[52,1265,304],{"class":114},[10,1267,1268,1269,1272,1273,1277],{},"Exporting with ",[19,1270,1271],{},"index=False"," keeps the date column at B; see ",[32,1274,1276],{"href":1275},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-pandas-dataframe-to-excel-without-index\u002F","Write a Pandas DataFrame to Excel Without the Index",".",[38,1279,1281],{"id":1280},"common-pitfalls","Common pitfalls",[1283,1284,1285,1301],"table",{},[1286,1287,1288],"thead",{},[1289,1290,1291,1295,1298],"tr",{},[1292,1293,1294],"th",{},"Symptom",[1292,1296,1297],{},"Cause",[1292,1299,1300],{},"Fix",[1302,1303,1304,1321,1337,1360,1378],"tbody",{},[1289,1305,1306,1310,1313],{},[1307,1308,1309],"td",{},"Date format ignored",[1307,1311,1312],{},"Cell holds a string, not a date serial",[1307,1314,1315,1316,26,1318,1320],{},"Parse with ",[19,1317,1014],{},[19,1319,1040],{}," before writing",[1289,1322,1323,1326,1329],{},[1307,1324,1325],{},"Cannot sort or filter as dates",[1307,1327,1328],{},"Values are text",[1307,1330,1331,1332,26,1334,1336],{},"Convert to real ",[19,1333,25],{},[19,1335,29],{}," objects",[1289,1338,1339,1342,1350],{},[1307,1340,1341],{},"Time component shows when you want a date",[1307,1343,1344,1345,1347,1348],{},"Wrote a ",[19,1346,29],{},", not a ",[19,1349,25],{},[1307,1351,1352,1353,1356,1357],{},"Use ",[19,1354,1355],{},"dt.date()",", or a date-only code like ",[19,1358,1359],{},"yyyy-mm-dd",[1289,1361,1362,1368,1371],{},[1307,1363,1364,1367],{},[19,1365,1366],{},"ValueError"," writing a tz-aware datetime",[1307,1369,1370],{},"Excel has no timezone concept",[1307,1372,1373,1374,1377],{},"Strip tzinfo: ",[19,1375,1376],{},"dt.replace(tzinfo=None)"," (after converting to your target zone)",[1289,1379,1380,1383,1386],{},[1307,1381,1382],{},"Off-by-one near early-1900 dates",[1307,1384,1385],{},"Excel's 1900 leap-year quirk",[1307,1387,1388],{},"Avoid pre-1900 dates; modern dates are unaffected",[38,1390,1392],{"id":1391},"a-note-on-timezones-and-the-1900-quirk","A note on timezones and the 1900 quirk",[10,1394,1395,1396,1398,1399,1401,1402,1404,1405,1407],{},"Excel dates are timezone-naive: there is no UTC offset stored. Convert a timezone-aware ",[19,1397,29],{}," to your intended zone first, then strip the tzinfo with ",[19,1400,1376],{}," before writing, or ",[19,1403,79],{}," raises a ",[19,1406,1366],{},". Separately, Excel intentionally treats 1900 as a leap year (a legacy bug it keeps for compatibility), so serials before March 1900 can be off by a day. This never affects ordinary modern reporting dates — it is only a concern for historical data reaching back over a century.",[38,1409,1411],{"id":1410},"frequently-asked-questions","Frequently asked questions",[1413,1414,1416],"h3",{"id":1415},"why-does-my-date-format-do-nothing","Why does my date format do nothing?",[10,1418,1419,1420,1422,1423,26,1425,1427],{},"The cell holds a string. A date ",[19,1421,804],{}," only formats a stored date serial. Parse the string into a ",[19,1424,25],{},[19,1426,29],{}," object first, then write it.",[1413,1429,1431],{"id":1430},"how-do-i-store-a-real-date-instead-of-text","How do I store a real date instead of text?",[10,1433,87,1434,91,1436,1438,1439,1441,1442,1445],{},[19,1435,90],{},[19,1437,94],{}," object to the cell. ",[19,1440,79],{}," converts it to Excel's serial number automatically; ",[19,1443,1444],{},"cell.value"," reads back as a date object.",[1413,1447,1449],{"id":1448},"how-do-i-show-a-date-as-ddmmyyyy","How do I show a date as dd\u002Fmm\u002Fyyyy?",[10,1451,1452,1453,1456],{},"Set ",[19,1454,1455],{},"cell.number_format = \"dd\u002Fmm\u002Fyyyy\"",". The format controls layout only; the stored serial is identical regardless of which code you choose.",[1413,1458,1460],{"id":1459},"why-does-my-date-include-a-time-of-0000","Why does my date include a time of 00:00?",[10,1462,1463,1464,1466,1467,1469,1470,1473,1474,1476,1477,1277],{},"You wrote a ",[19,1465,29],{}," with no time, or used a code that includes hours. Use a ",[19,1468,25],{}," object, call ",[19,1471,1472],{},".date()"," on a ",[19,1475,29],{},", or pick a date-only code like ",[19,1478,1479],{},"mmm d, yyyy",[1413,1481,1483],{"id":1482},"how-do-i-format-dates-from-a-pandas-dataframe","How do I format dates from a pandas DataFrame?",[10,1485,1486,1487,1489,1490,1492,1493,1495,1496,1498,1499,1501],{},"Ensure the column is ",[19,1488,1029],{}," (convert with ",[19,1491,1040],{},"), export with ",[19,1494,1033],{},", then reopen with ",[19,1497,79],{}," and set ",[19,1500,804],{}," on the date column.",[38,1503,1505],{"id":1504},"conclusion","Conclusion",[10,1507,1508,1509,26,1511,1513,1514,91,1517,1519],{},"Correct Excel dates are two layers: a real ",[19,1510,25],{},[19,1512,29],{}," value Excel stores as a serial, and a display code on top. Always write objects, never pre-formatted strings — a text date cannot be reformatted, sorted, or computed. Parse incoming strings with ",[19,1515,1516],{},"strptime",[19,1518,1040],{},", strip timezones, and the format codes do the rest.",[38,1521,1523],{"id":1522},"where-to-go-next","Where to go next",[1525,1526,1527,1533,1540],"ul",{},[1528,1529,1530,1532],"li",{},[32,1531,35],{"href":34}," — the parent cluster: separators, percentages, and the format-code reference table.",[1528,1534,1535,1539],{},[32,1536,1538],{"href":1537},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-excel-cells-as-currency-with-python\u002F","Format Excel Cells as Currency with Python"," — the currency companion to this guide.",[1528,1541,1542,1544],{},[32,1543,1276],{"href":1275}," — keep your date column in the right place after export.",[1546,1547,1548],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":48,"searchDepth":124,"depth":124,"links":1550},[1551,1552,1553,1554,1555,1556,1557,1558,1559,1566,1567],{"id":40,"depth":124,"text":41},{"id":83,"depth":124,"text":84},{"id":339,"depth":124,"text":340},{"id":562,"depth":124,"text":563},{"id":794,"depth":124,"text":795},{"id":1022,"depth":124,"text":1023},{"id":1280,"depth":124,"text":1281},{"id":1391,"depth":124,"text":1392},{"id":1410,"depth":124,"text":1411,"children":1560},[1561,1562,1563,1564,1565],{"id":1415,"depth":137,"text":1416},{"id":1430,"depth":137,"text":1431},{"id":1448,"depth":137,"text":1449},{"id":1459,"depth":137,"text":1460},{"id":1482,"depth":137,"text":1483},{"id":1504,"depth":124,"text":1505},{"id":1522,"depth":124,"text":1523},"Format dates in Excel cells with openpyxl: write real datetime objects so Excel stores a date serial, then apply yyyy-mm-dd, mmm d yyyy, or dd\u002Fmm\u002Fyyyy display codes.","md",{},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-dates-in-excel-cells-with-python",{"title":5,"description":1573},"Step-by-step openpyxl date formatting: store real date serials from datetime objects, apply ISO and locale layouts, fix text dates, and format pandas datetime columns.","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-dates-in-excel-cells-with-python\u002Findex","i_2JDIOT4BGciiy-XJLZ95QX4XYQJN_9E2YL2GWOeLA",[1577,1580],{"title":35,"path":1578,"stem":1579,"children":-1},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Findex",{"title":1538,"path":1581,"stem":1582,"children":-1},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-excel-cells-as-currency-with-python","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-excel-cells-as-currency-with-python\u002Findex",1781773161031]