Skip to content

Commit

Permalink
Explicitly use utc tz and respect external format reqs
Browse files Browse the repository at this point in the history
  • Loading branch information
hbruch committed Sep 14, 2023
1 parent e037309 commit 59a0599
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
27 changes: 18 additions & 9 deletions x2gbfs/providers/deer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import re
from datetime import datetime
from datetime import datetime, timezone
from typing import Any, Dict, Generator, Optional, Tuple

from x2gbfs.gbfs.base_provider import BaseProvider
Expand Down Expand Up @@ -274,6 +274,18 @@ def load_vehicles(self, default_last_reported: int) -> Tuple[Dict, Dict]:

return gbfs_vehicle_types_map, gbfs_vehicles_map

def _utcnow(self):
return datetime.now(timezone.utc)

def _timestamp_to_isoformat(self, timestamp):
"""
Returns timestamp in isoformat.
As gbfs-validator currently can't handle numeric +00:00 timezone information, we replace +00:00 by Z
It's validation expressio is ^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})([A-Z])$
See also https://github.com/MobilityData/gbfs-json-schema/issues/95
"""
return timestamp.isoformat().replace('+00:00', 'Z')

def _update_booking_state(self, gbfs_vehicles_map: Dict) -> Dict:
"""
For every vehicle in gbfs_vehicles_map, this function
Expand All @@ -282,21 +294,18 @@ def _update_booking_state(self, gbfs_vehicles_map: Dict) -> Dict:
If no booking for a vehicle id exists, is_reserved is false and no available_until
information.
"""
timestamp = datetime.now()
timestamp_iso = timestamp.isoformat()
timestamp = self._utcnow()

next_bookings = self._next_booking_per_vehicle(timestamp)
for vehicle_id, vehicle in gbfs_vehicles_map.items():
if vehicle_id not in next_bookings:
# No booking => available forever and not reserved
continue
next_booking_start = next_bookings[vehicle_id]['startDate']
if next_booking_start > timestamp_iso:
next_booking_start = datetime.fromisoformat(next_bookings[vehicle_id]['startDate'])
if next_booking_start > timestamp:
# Next booking starts in the future, set available_until, currently not reserved
# Note: fleetsters timestamp has ms information which would be flagged by GBFS validator, so we parse and reformat in isoformat
gbfs_formatted_start_time = (
datetime.fromisoformat(next_booking_start).isoformat().replace('+00:00', 'Z')
)
gbfs_formatted_start_time = self._timestamp_to_isoformat(next_booking_start)

vehicle['available_until'] = gbfs_formatted_start_time
else:
vehicle['is_reserved'] = True
Expand Down
14 changes: 11 additions & 3 deletions x2gbfs/providers/fleetster.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from datetime import datetime
from typing import Dict, Generator, Optional

import requests
Expand Down Expand Up @@ -32,9 +33,16 @@ def all_vehicles(self) -> Generator[Dict, None, None]:
for vehicle in vehicles:
yield vehicle

def all_bookings_ending_after(self, timestamp):
enddate = timestamp.isoformat()
return self._get_with_authorization(f'{self.api_url}/bookings?endDate%5B%24gte%5D={enddate}Z')
def all_bookings_ending_after(self, utctimestamp: datetime):
enddate = self._timestamp_to_isoformat(utctimestamp)
return self._get_with_authorization(f'{self.api_url}/bookings?endDate%5B%24gte%5D={enddate}')

def _timestamp_to_isoformat(self, utctimestamp: datetime):
"""
Returns timestamp in isoformat.
As fleetster currently can't handle numeric timezone information, we replace +00:00 by Z
"""
return utctimestamp.isoformat().replace('+00:00', 'Z')

def _login(self) -> str:
if self.token is None:
Expand Down

0 comments on commit 59a0599

Please sign in to comment.