From 30fc037222ef60b6515732d08e5a6151510b6d98 Mon Sep 17 00:00:00 2001 From: Josh Flatt Date: Tue, 9 Dec 2025 00:44:16 -0600 Subject: [PATCH] now dynamically finds timezone --- notebooks/make_df.ipynb | 82 +++++++++++++++++++++++++++++++++++++++-- requirements.txt | 1 + 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/notebooks/make_df.ipynb b/notebooks/make_df.ipynb index 1b7da6e..03cc375 100644 --- a/notebooks/make_df.ipynb +++ b/notebooks/make_df.ipynb @@ -1343,7 +1343,55 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 32, + "id": "07514caa", + "metadata": {}, + "outputs": [], + "source": [ + "import pytz\n", + "from timezonefinder import TimezoneFinder\n", + "from datetime import datetime\n", + "import pandas as pd # Assuming you still use pandas\n", + "\n", + "# Initialize the TimezoneFinder outside the loop for efficiency\n", + "tf = TimezoneFinder()\n", + "\n", + "def get_localized_dt_and_offset(utc_dt, latitude, longitude):\n", + " \"\"\"\n", + " Finds the correct local timezone based on coordinates and converts\n", + " the UTC datetime object to that local time, returning the time string\n", + " and the corresponding offset string.\n", + " \"\"\"\n", + " # 1. Find the IANA Timezone Name\n", + " tz_name = tf.timezone_at(lng=longitude, lat=latitude)\n", + "\n", + " if not tz_name or latitude == 0 or longitude == 0:\n", + " # Fallback if no timezone is found (e.g., open ocean)\n", + " print(f\"⚠️ Warning: No timezone found for {latitude}, {longitude}. Defaulting to UTC.\")\n", + " local_tz = pytz.utc\n", + " else:\n", + " local_tz = pytz.timezone(tz_name)\n", + "\n", + " # 2. Convert from UTC to the determined local timezone\n", + " # The input 'utc_dt' must already be a timezone-aware UTC object (which it is in your current code)\n", + " dt_local = utc_dt.astimezone(local_tz)\n", + "\n", + " # 3. Format the local date string (for DateTimeOriginal, etc.)\n", + " # Must use 'YYYY:MM:DD HH:MM:SS' format\n", + " dt_str = dt_local.strftime(\"%Y:%m:%d %H:%M:%S\")\n", + "\n", + " # 4. Format the time zone offset string (for OffsetTimeOriginal)\n", + " # The '+/-HHMM' string is extracted, and the colon is inserted for EXIF compatibility\n", + " offset_str = dt_local.strftime('%z')\n", + " if len(offset_str) == 5:\n", + " offset_str = offset_str[:3] + \":\" + offset_str[3:] \n", + "\n", + " return dt_str, offset_str" + ] + }, + { + "cell_type": "code", + "execution_count": 33, "id": "e7b8202f", "metadata": {}, "outputs": [], @@ -1380,6 +1428,12 @@ " offset_str = dt_central.strftime('%z')\n", " if len(offset_str) == 5:\n", " offset_str = offset_str[:3] + \":\" + offset_str[3:] # Converts -0500 to -05:00\n", + " \n", + " dt_str, offset_str = get_localized_dt_and_offset(\n", + " utc_dt=dt_utc,\n", + " latitude=row['correct_latitude'],\n", + " longitude=row['correct_longitude']\n", + " )\n", "\n", " if not os.path.exists(image_path):\n", " print(f\"❌ File not found, skipping: {image_path}\")\n", @@ -1447,7 +1501,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 34, "id": "e2736799", "metadata": {}, "outputs": [ @@ -1488,10 +1542,15 @@ "✅ Updated: ../downloads/2022-05-19_15-55-40.jpg\n", "✅ Updated: ../downloads/2022-05-15_06-32-35.jpg\n", "✅ Updated: ../downloads/2022-05-13_21-45-03.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2022-05-08_08-05-24.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2022-05-05_03-18-35.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2022-05-02_15-13-11.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2022-05-02_04-49-16.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2022-05-01_19-44-14.jpg\n", "✅ Updated: ../downloads/2022-04-02_03-25-29.jpg\n", "✅ Updated: ../downloads/2022-04-01_19-48-10.jpg\n", @@ -2020,6 +2079,7 @@ "✅ Updated: ../downloads/2019-04-24_04-49-12.jpg\n", "✅ Updated: ../downloads/2019-04-18_19-01-07.jpg\n", "✅ Updated: ../downloads/2019-04-05_23-27-17.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2019-03-29_03-02-16.jpg\n", "✅ Updated: ../downloads/2019-03-24_02-02-05.jpg\n", "✅ Updated: ../downloads/2019-03-12_15-18-48.jpg\n", @@ -2028,6 +2088,7 @@ "✅ Updated: ../downloads/2019-03-05_16-06-11.jpg\n", "✅ Updated: ../downloads/2019-03-02_03-05-22.jpg\n", "✅ Updated: ../downloads/2019-02-26_14-17-55.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2019-02-23_07-55-33.jpg\n", "✅ Updated: ../downloads/2019-02-20_23-40-54.jpg\n", "✅ Updated: ../downloads/2019-02-17_04-06-41.jpg\n", @@ -2092,16 +2153,27 @@ "✅ Updated: ../downloads/2018-05-19_21-32-15.jpg\n", "✅ Updated: ../downloads/2018-05-14_20-56-54.jpg\n", "✅ Updated: ../downloads/2018-05-12_14-45-54.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-11-03_16-46-57.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-11-02_22-19-51.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-11-01_02-25-10.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-10-29_02-18-17.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-10-29_02-17-58.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-10-29_02-16-08.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-10-29_02-15-24.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-10-22_18-56-44.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-10-13_16-43-21.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-10-13_14-32-47.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-10-13_14-19-28.jpg\n", "✅ Updated: ../downloads/2017-10-10_02-26-11.jpg\n", "✅ Updated: ../downloads/2017-10-09_13-00-32.jpg\n", @@ -2113,9 +2185,13 @@ "✅ Updated: ../downloads/2017-07-22_18-01-44.jpg\n", "✅ Updated: ../downloads/2017-07-21_14-45-29.jpg\n", "✅ Updated: ../downloads/2017-07-21_14-45-29.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-07-14_18-52-13.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-07-14_18-51-57.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-07-14_18-47-55.jpg\n", + "⚠️ Warning: No timezone found for 0.0, 0.0. Defaulting to UTC.\n", "✅ Updated: ../downloads/2017-07-14_18-47-22.jpg\n", "✅ Updated: ../downloads/2017-07-04_16-13-56.jpg\n", "✅ Updated: ../downloads/2017-07-04_16-13-56.jpg\n", @@ -2154,7 +2230,7 @@ "Length: 676, dtype: object" ] }, - "execution_count": 31, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } diff --git a/requirements.txt b/requirements.txt index 56ac553..f494b84 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ pydantic>=2.12.0 tqdm>=4.67.1 pillow piexif +timezonefinder # For development jupyter