{"id":"dates-formatting","slug":"formatting","title":"Formatting and reading dates","text":"A printed datetime looks like `2026-03-14 09:05:00`, which isn't how people usually write dates. The method **`strftime`** (string format time) turns a datetime into text in any format you like. You describe the format with codes that start with `%`:\n\n```python\nfrom datetime import datetime\n\nmoment = datetime(2026, 3, 14, 9, 5)\nprint(moment.strftime(\"%d.%m.%Y\"))\nprint(moment.strftime(\"%m/%d/%Y %H:%M\"))\nprint(moment.strftime(\"%A %d %B %Y\"))\n```\n\n```output\n14.03.2026\n03/14/2026 09:05\nSaturday 14 March 2026\n```\n\nEverything in the format that isn't a code (the dots, slashes, spaces and any words) is copied into the result as it is. The most useful codes:\n\n| Code | Means | For the moment above |\n| --- | --- | --- |\n| `%d` | day of the month, two digits | `14` |\n| `%m` | month, two digits | `03` |\n| `%Y` | year, four digits | `2026` |\n| `%H` | hour, 00 to 23 | `09` |\n| `%M` | minutes | `05` |\n| `%S` | seconds | `00` |\n| `%A` | name of the weekday | `Saturday` |\n| `%B` | name of the month | `March` |\n\nThe full list is in the documentation of the `datetime` module.\n\n### Small m, capital M\n\nThe classic mistake: `%m` is the month, `%M` the minutes. Mix them up and there's no error, just a wrong date:\n\n```python\nfrom datetime import datetime\n\nmoment = datetime(2026, 3, 14, 9, 5)\nprint(moment.strftime(\"%d.%M.%Y\"))\n```\n\n```output\n14.05.2026\n```\n\nPython can't know you meant the month, so check the output of date formatting carefully.\n\n### From text to a datetime\n\n**`strptime`** (string parse time) works the other way round: it reads a date written as text in a format you describe, and makes a datetime of it. You call it on the type itself, `datetime.strptime(text, format)`:\n\n```python\nfrom datetime import datetime\n\ntext = input(\"Date (dd.mm.yyyy): \")\nday = datetime.strptime(text, \"%d.%m.%Y\")\nprint(day)\nprint(day.strftime(\"%A\"))\n```\n\n```input\n24.12.2026\n```\n\n```output\nDate (dd.mm.yyyy): 24.12.2026\n2026-12-24 00:00:00\nThursday\n```\n\nWhen reading, a single-digit day or month is fine too: `5.1.2026` reads as 5 January. But if the text doesn't match the format, or the date doesn't exist, `strptime` raises a `ValueError`, such as `ValueError: time data '2026-12-24' does not match format '%d.%m.%Y'`. Catch it with `try` and `except ValueError`, just like a failed `int(...)`.\n","task":"Fill in the two format strings so the program prints the moment as day/month/year on the first line and as hours and minutes on the second:\n\n```\n04/07/2026\n18:30\n```\n","kind":"fill","seed":"from datetime import datetime\n\nlaunch = datetime(2026, 7, 4, 18, 30)\nprint(launch.strftime(\"[[%d/%m/%Y]]\"))\nprint(launch.strftime(\"[[%H:%M]]\"))\n","solution":"from datetime import datetime\n\nlaunch = datetime(2026, 7, 4, 18, 30)\nprint(launch.strftime(\"%d/%m/%Y\"))\nprint(launch.strftime(\"%H:%M\"))\n","hints":["Day, month and year are `%d`, `%m` and `%Y`, and the slashes between them are copied as they are.","Hours are `%H` and minutes are a capital `%M`, with a colon between them."],"tests":[{"name":"Output","stdin":"","expect":"04/07/2026\n18:30","hidden":false}],"require":[],"forbid":[],"more":[{"task":"Write a function `weekday_of(text)` that gets a date as text in the form year-month-day, such as `\"2026-10-15\"`, and returns the name of its weekday, such as `\"Thursday\"`. Read the text with `strptime` and get the name with `strftime`.\n","kind":"code","seed":"from datetime import datetime\n\n\ndef weekday_of(text):\n    pass\n\n\nif __name__ == \"__main__\":\n    print(weekday_of(\"2026-10-15\"))\n","solution":"from datetime import datetime\n\n\ndef weekday_of(text):\n    day = datetime.strptime(text, \"%Y-%m-%d\")\n    return day.strftime(\"%A\")\n\n\nif __name__ == \"__main__\":\n    print(weekday_of(\"2026-10-15\"))\n","hints":["The format of the text is year, month and day separated by hyphens: `\"%Y-%m-%d\"`.","`datetime.strptime(text, \"%Y-%m-%d\")` gives a datetime. The code for the weekday's name is `%A`."],"tests":[{"name":"weekday_of(\"2026-10-15\")","stdin":"","call":"weekday_of(\"2026-10-15\")\n","expect":"'Thursday'","hidden":false,"returns":true},{"name":"weekday_of(\"2000-01-01\")","stdin":"","call":"weekday_of(\"2000-01-01\")\n","expect":"'Saturday'","hidden":true,"returns":true},{"name":"weekday_of(\"1969-07-20\")","stdin":"","call":"weekday_of(\"1969-07-20\")\n","expect":"'Sunday'","hidden":true,"returns":true},{"name":"weekday_of(\"2028-02-29\")","stdin":"","call":"weekday_of(\"2028-02-29\")\n","expect":"'Tuesday'","hidden":true,"returns":true}],"require":[],"forbid":[]},{"task":"A plant needs water every three days. Write a program that asks for the first watering day (as day.month.year) and the number of waterings, and prints each watering day with its weekday, in the format of the example:\n\n```\nFirst watering (dd.mm.yyyy): 27.10.2026\nHow many times: 4\nTuesday 27.10.2026\nFriday 30.10.2026\nMonday 02.11.2026\nThursday 05.11.2026\n```\n","kind":"code","seed":"from datetime import datetime, timedelta\n","solution":"from datetime import datetime, timedelta\n\nfirst = input(\"First watering (dd.mm.yyyy): \")\ntimes = int(input(\"How many times: \"))\nday = datetime.strptime(first, \"%d.%m.%Y\")\nfor i in range(times):\n    print(day.strftime(\"%A %d.%m.%Y\"))\n    day += timedelta(days=3)\n","hints":["Read the first day with `datetime.strptime(text, \"%d.%m.%Y\")`.","In a loop that runs as many times as asked, print the day with `strftime(\"%A %d.%m.%Y\")`.","After printing, move the day three days ahead: `day += timedelta(days=3)`."],"tests":[{"name":"Test 1","stdin":"27.10.2026\n4\n","expect":"First watering (dd.mm.yyyy): 27.10.2026\nHow many times: 4\nTuesday 27.10.2026\nFriday 30.10.2026\nMonday 02.11.2026\nThursday 05.11.2026","hidden":false},{"name":"Test 2","stdin":"30.12.2026\n3\n","expect":"First watering (dd.mm.yyyy): 30.12.2026\nHow many times: 3\nWednesday 30.12.2026\nSaturday 02.01.2027\nTuesday 05.01.2027","hidden":true},{"name":"Test 3","stdin":"24.2.2028\n5\n","expect":"First watering (dd.mm.yyyy): 24.2.2028\nHow many times: 5\nThursday 24.02.2028\nSunday 27.02.2028\nWednesday 01.03.2028\nSaturday 04.03.2028\nTuesday 07.03.2028","hidden":true}],"require":[],"forbid":[]}]}