Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions scripts/badges/badge_notification_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import logging
import re
import time
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path

from github import Github
Expand Down Expand Up @@ -435,14 +435,14 @@ def record_notification(self, repo_url: str, issue_url: str, resource_name: str
"repo_url": repo_url,
"issue_url": issue_url,
"resource_name": resource_name,
"timestamp": datetime.now().isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}
self.history.append(entry)
self._save_history()

def get_notification_count(self, repo_url: str, time_window_hours: int = 24) -> int:
"""Get count of recent notifications for a repository"""
cutoff = datetime.now().timestamp() - (time_window_hours * 3600)
cutoff = datetime.now(timezone.utc).timestamp() - (time_window_hours * 3600)
count = 0

for entry in self.history:
Expand Down
4 changes: 2 additions & 2 deletions scripts/readme/generators/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import os
import shutil
from abc import ABC, abstractmethod
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path

import yaml # type: ignore[import-untyped]
Expand Down Expand Up @@ -70,7 +70,7 @@ def create_backup(file_path: str, keep_latest: int = 1) -> str | None:
if not os.path.exists(file_path):
return None

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
backup_dir = os.path.join(REPO_ROOT, ".myob", "backups")
os.makedirs(backup_dir, exist_ok=True)

Expand Down
10 changes: 5 additions & 5 deletions scripts/readme/generators/flat.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from __future__ import annotations

import os
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from pathlib import Path

from scripts.readme.generators.base import ReadmeGenerator, load_template
Expand Down Expand Up @@ -139,20 +139,20 @@ def sort_resources(self, resources: list[dict]) -> list[dict]:
)
return [r for _, r in with_dates]
if self.sort_type == "releases":
cutoff = datetime.now() - timedelta(days=self.DAYS_THRESHOLD)
cutoff = datetime.now(timezone.utc) - timedelta(days=self.DAYS_THRESHOLD)
recent = []
for row in resources:
release_date_str = row.get("Latest Release", "")
if not release_date_str:
continue
try:
release_date = datetime.strptime(release_date_str, "%Y-%m-%d:%H-%M-%S")
release_date = datetime.strptime(release_date_str, "%Y-%m-%d:%H-%M-%S").replace(tzinfo=timezone.utc)
except ValueError:
continue
if release_date >= cutoff:
row["_parsed_release_date"] = release_date
recent.append(row)
recent.sort(key=lambda x: x.get("_parsed_release_date", datetime.min), reverse=True)
recent.sort(key=lambda x: x.get("_parsed_release_date", datetime.min.replace(tzinfo=timezone.utc)), reverse=True)
return recent
return resources

Expand Down Expand Up @@ -213,7 +213,7 @@ def generate(self, output_path: str | None = None) -> tuple[int, str | None]:
)
resources_table = generate_flat_resources_table(sorted_resources, self.sort_type)

generated_date = datetime.now().strftime("%Y-%m-%d")
generated_date = datetime.now(timezone.utc).strftime("%Y-%m-%d")
_, cat_display, _ = self._category_info
_, _, sort_desc = self._sort_info

Expand Down
4 changes: 2 additions & 2 deletions scripts/readme/helpers/readme_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from __future__ import annotations

import re
from datetime import datetime
from datetime import datetime, timezone


def extract_github_owner_repo(url: str) -> tuple[str, str] | None:
Expand Down Expand Up @@ -172,7 +172,7 @@ def parse_resource_date(date_string: str | None) -> datetime | None:

for fmt in date_formats:
try:
return datetime.strptime(date_string, fmt)
return datetime.strptime(date_string, fmt).replace(tzinfo=timezone.utc)
except ValueError:
continue

Expand Down
4 changes: 2 additions & 2 deletions scripts/readme/markup/awesome.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone

from scripts.readme.helpers.readme_paths import asset_path_token
from scripts.readme.helpers.readme_utils import (
Expand Down Expand Up @@ -109,7 +109,7 @@ def generate_weekly_section(csv_data: list[dict]) -> str:
resources_sorted_by_date.sort(key=lambda x: x[0], reverse=True)

latest_additions: list[dict[str, str]] = []
cutoff_date = datetime.now() - timedelta(days=7)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=7)
for dated_resource in resources_sorted_by_date:
if dated_resource[0] >= cutoff_date or len(latest_additions) < 3:
latest_additions.append(dated_resource[1])
Expand Down
4 changes: 2 additions & 2 deletions scripts/readme/markup/minimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone

from scripts.readme.helpers.readme_utils import (
generate_subcategory_anchor,
Expand Down Expand Up @@ -129,7 +129,7 @@ def generate_weekly_section(csv_data: list[dict]) -> str:
resources_sorted_by_date.sort(key=lambda x: x[0], reverse=True)

latest_additions: list[dict[str, str]] = []
cutoff_date = datetime.now() - timedelta(days=7)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=7)
for dated_resource in resources_sorted_by_date:
if dated_resource[0] >= cutoff_date or len(latest_additions) < 3:
latest_additions.append(dated_resource[1])
Expand Down
4 changes: 2 additions & 2 deletions scripts/readme/markup/visual.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from pathlib import Path

from scripts.readme.helpers.readme_assets import (
Expand Down Expand Up @@ -116,7 +116,7 @@ def generate_weekly_section(
resources_sorted_by_date.sort(key=lambda x: x[0], reverse=True)

latest_additions: list[dict] = []
cutoff_date = datetime.now() - timedelta(days=7)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=7)
for dated_resource in resources_sorted_by_date:
if dated_resource[0] >= cutoff_date or len(latest_additions) < 3:
latest_additions.append(dated_resource[1])
Expand Down
4 changes: 2 additions & 2 deletions scripts/resources/create_resource_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import re
import subprocess
import sys
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path

from scripts.utils.repo_root import find_repo_root
Expand All @@ -36,7 +36,7 @@ def run_command(cmd: list[str], check: bool = True) -> subprocess.CompletedProce

def create_unique_branch_name(base_name: str) -> str:
"""Create a unique branch name with timestamp."""
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
timestamp = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
return f"{base_name}-{timestamp}"


Expand Down
6 changes: 3 additions & 3 deletions scripts/resources/download_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import random
import re
import time
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -291,7 +291,7 @@ def process_resources(
"""
Process and download resources from the CSV file.
"""
start_time = datetime.now()
start_time = datetime.now(timezone.utc)
print(f"Starting download at: {start_time.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Archive directory (all resources): {output_dir}")
print(f"Hosted directory (open-source only): {hosted_dir}")
Expand Down Expand Up @@ -450,7 +450,7 @@ def process_resources(
time.sleep(random.uniform(1, 2))

# Summary
end_time = datetime.now()
end_time = datetime.now(timezone.utc)
duration = end_time - start_time

print(f"\n{'=' * 60}")
Expand Down
4 changes: 2 additions & 2 deletions scripts/resources/resource_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import csv
import os
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path

from scripts.utils.repo_root import find_repo_root
Expand All @@ -31,7 +31,7 @@ def append_to_csv(data: dict[str, str]) -> bool:
print("Error reading CSV header: missing header row")
return False

now = datetime.now().strftime("%Y-%m-%d:%H-%M-%S")
now = datetime.now(timezone.utc).strftime("%Y-%m-%d:%H-%M-%S")
value_map = {
"ID": data.get("id", ""),
"Display Name": data.get("display_name", ""),
Expand Down
4 changes: 2 additions & 2 deletions scripts/validation/validate_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,7 @@ def validate_links(csv_file, max_links=None, ignore_overrides=False, verbose=Fal

# Update timestamp if not locked
if "last_checked" not in locked_fields:
row[LAST_CHECKED_HEADER_NAME] = datetime.now().strftime("%Y-%m-%d:%H-%M-%S")
row[LAST_CHECKED_HEADER_NAME] = datetime.now(UTC).strftime("%Y-%m-%d:%H-%M-%S")

Comment on lines 842 to 845
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file now uses datetime.now(UTC) (with UTC imported from datetime) rather than datetime.now(timezone.utc). Functionally both are UTC-aware, but it diverges from the PR description’s stated standard (timezone.utc). Consider either switching these calls to timezone.utc for consistency across the PR, or updating the PR description to explicitly allow UTC as the standardized approach.

Copilot uses AI. Check for mistakes.
# Track broken links
if not is_active and "active" not in locked_fields:
Expand Down Expand Up @@ -961,7 +961,7 @@ def validate_links(csv_file, max_links=None, ignore_overrides=False, verbose=Fal
"locked_fields": locked_field_count,
"broken_links": broken_links,
"newly_broken_links": newly_broken_links,
"timestamp": datetime.now().strftime("%Y-%m-%d:%H-%M-%S"),
"timestamp": datetime.now(UTC).strftime("%Y-%m-%d:%H-%M-%S"),
}


Expand Down
4 changes: 2 additions & 2 deletions scripts/validation/validate_single_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"""

import sys
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -93,7 +93,7 @@ def validate_single_resource(
# Set active status
is_valid = len(errors) == 0
enriched_data["active"] = "TRUE" if is_valid else "FALSE"
enriched_data["last_checked"] = datetime.now().strftime("%Y-%m-%d:%H-%M-%S")
enriched_data["last_checked"] = datetime.now(timezone.utc).strftime("%Y-%m-%d:%H-%M-%S")

return is_valid, enriched_data, errors

Expand Down
8 changes: 4 additions & 4 deletions tests/test_flat_list_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import csv
import sys
from dataclasses import dataclass
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from pathlib import Path

import pytest
Expand Down Expand Up @@ -418,7 +418,7 @@ class TestReleasesSort:

def test_releases_filter_recent(self, tmp_path: Path) -> None:
"""Test that releases sort only includes recent releases."""
now = datetime.now()
now = datetime.now(timezone.utc)
recent = (now - timedelta(days=10)).strftime("%Y-%m-%d:%H-%M-%S")
old = (now - timedelta(days=60)).strftime("%Y-%m-%d:%H-%M-%S")

Expand Down Expand Up @@ -463,7 +463,7 @@ def test_releases_filter_recent(self, tmp_path: Path) -> None:

def test_releases_sort_order(self, tmp_path: Path) -> None:
"""Test that releases are sorted by date (most recent first)."""
now = datetime.now()
now = datetime.now(timezone.utc)
day5 = (now - timedelta(days=5)).strftime("%Y-%m-%d:%H-%M-%S")
day10 = (now - timedelta(days=10)).strftime("%Y-%m-%d:%H-%M-%S")
day15 = (now - timedelta(days=15)).strftime("%Y-%m-%d:%H-%M-%S")
Expand Down Expand Up @@ -523,7 +523,7 @@ def test_releases_sort_order(self, tmp_path: Path) -> None:

def test_releases_table_format(self, tmp_path: Path) -> None:
"""Test releases table has correct columns."""
now = datetime.now()
now = datetime.now(timezone.utc)
recent = (now - timedelta(days=5)).strftime("%Y-%m-%d:%H-%M-%S")

rows = [
Expand Down
16 changes: 8 additions & 8 deletions tests/test_generate_readme.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import os
import sys
from datetime import datetime
from datetime import datetime, timezone
from typing import Any

import pytest
Expand Down Expand Up @@ -37,19 +37,19 @@ class TestParseResourceDate:
def test_parse_date_only_format(self) -> None:
"""Test parsing YYYY-MM-DD format."""
result = parse_resource_date("2025-08-07")
expected = datetime(2025, 8, 7)
expected = datetime(2025, 8, 7, tzinfo=timezone.utc)
assert result == expected

def test_parse_date_with_timestamp_format(self) -> None:
"""Test parsing YYYY-MM-DD:HH-MM-SS format."""
result = parse_resource_date("2025-08-07:18-26-57")
expected = datetime(2025, 8, 7, 18, 26, 57)
expected = datetime(2025, 8, 7, 18, 26, 57, tzinfo=timezone.utc)
assert result == expected

def test_parse_with_whitespace(self) -> None:
"""Test parsing with leading/trailing whitespace."""
result = parse_resource_date(" 2025-08-07 ")
expected = datetime(2025, 8, 7)
expected = datetime(2025, 8, 7, tzinfo=timezone.utc)
assert result == expected

def test_parse_empty_string(self) -> None:
Expand Down Expand Up @@ -78,10 +78,10 @@ def test_parse_invalid_format(self, invalid_date: str) -> None:
@pytest.mark.parametrize(
"date_string, expected",
[
("2025-08-05:11-48-39", datetime(2025, 8, 5, 11, 48, 39)),
("2025-07-29:18-37-05", datetime(2025, 7, 29, 18, 37, 5)),
("2025-08-07:00-00-00", datetime(2025, 8, 7, 0, 0, 0)),
("2025-12-31:23-59-59", datetime(2025, 12, 31, 23, 59, 59)),
("2025-08-05:11-48-39", datetime(2025, 8, 5, 11, 48, 39, tzinfo=timezone.utc)),
("2025-07-29:18-37-05", datetime(2025, 7, 29, 18, 37, 5, tzinfo=timezone.utc)),
("2025-08-07:00-00-00", datetime(2025, 8, 7, 0, 0, 0, tzinfo=timezone.utc)),
("2025-12-31:23-59-59", datetime(2025, 12, 31, 23, 59, 59, tzinfo=timezone.utc)),
],
)
def test_parse_various_timestamps(self, date_string: str, expected: datetime) -> None:
Expand Down
12 changes: 6 additions & 6 deletions tests/test_resource_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import sys
import tempfile
from collections.abc import Generator
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from pathlib import Path

import pytest
Expand Down Expand Up @@ -174,9 +174,9 @@ def test_append_to_csv_date_fields(
set_csv_path(monkeypatch, temp_csv)

# Capture the current time window
before_time = datetime.now()
before_time = datetime.now(timezone.utc)
result = append_to_csv(sample_resource_data)
after_time = datetime.now()
after_time = datetime.now(timezone.utc)

assert result is True

Expand All @@ -186,9 +186,9 @@ def test_append_to_csv_date_fields(
next(reader) # Skip header
data_row = next(reader)

# Parse the date fields
date_added = datetime.strptime(data_row[9], "%Y-%m-%d:%H-%M-%S")
last_checked = datetime.strptime(data_row[11], "%Y-%m-%d:%H-%M-%S")
# Parse the date fields (UTC-aware to match datetime.now(timezone.utc))
date_added = datetime.strptime(data_row[9], "%Y-%m-%d:%H-%M-%S").replace(tzinfo=timezone.utc)
last_checked = datetime.strptime(data_row[11], "%Y-%m-%d:%H-%M-%S").replace(tzinfo=timezone.utc)

# Verify dates are within the expected time window (account for second precision)
# The strptime loses microseconds, so we need to compare at second precision
Expand Down
Loading