Skip to content

Commit d6855b3

Browse files
authored
Merge pull request #164 from adamspd/use-current-timezome
Let Django handle the timezone
2 parents 175888d + 547d5d7 commit d6855b3

File tree

14 files changed

+26
-64
lines changed

14 files changed

+26
-64
lines changed

SECURITY.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ This project depends on several third-party libraries:
3737
- phonenumbers==8.13.25
3838
- django-phonenumber-field==7.2.0
3939
- babel==2.13.1
40-
- pytz~=2023.3.post1
4140

4241
We strive to keep these dependencies up to date and free from vulnerabilities. If you find a vulnerability in one of
4342
these dependencies, please follow the steps above to report it.

appointment/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
__package_name__ = "django-appointment"
66
__url__ = "https://github.com/adamspd/django-appointment"
77
__package_website__ = "https://django-appt.adamspierredavid.com/"
8-
__version__ = "3.3.9"
8+
__version__ = "3.4.0"
99
__test_version__ = False

appointment/services.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,7 @@ def get_available_slots_for_staff(date, staff_member):
434434
slots = exclude_pending_reschedules(slots, staff_member, date)
435435
appointments = get_appointments_for_date_and_time(date, working_hours_dict['start_time'],
436436
working_hours_dict['end_time'], staff_member)
437-
slots = exclude_booked_slots(appointments, slots, slot_duration)
438-
439-
return [slot.strftime('%I:%M %p') for slot in slots]
437+
return exclude_booked_slots(appointments, slots, slot_duration)
440438

441439

442440
def get_finish_button_text(service) -> str:

appointment/static/js/appointments.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ let isRequestInProgress = false;
1010
const calendar = new FullCalendar.Calendar(calendarEl, {
1111
initialView: 'dayGridMonth',
1212
initialDate: selectedDate,
13+
timeZone: timezone,
1314
headerToolbar: {
1415
left: 'title',
1516
right: 'prev,today,next',

appointment/templates/appointment/appointments.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ <h1 class="page-title">
109109
integrity="sha512-JCQkxdym6GmQ+AFVioDUq8dWaWN6tbKRhRyHvYZPupQ6DxpXzkW106FXS1ORgo/m3gxtt5lHRMqSdm2OfPajtg=="
110110
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
111111
<script>
112-
const timezone = "{{ timezone }}";
112+
const timezone = "{{ timezoneTxt }}";
113113
const locale = "{{ locale }}";
114114
const availableSlotsAjaxURL = "{% url 'appointment:available_slots_ajax' %}";
115115
const requestNextAvailableSlotURLTemplate = "{% url 'appointment:request_next_available_slot' service_id=0 %}";

appointment/tests/test_services.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,9 @@ def test_available_slots(self):
471471
"""Test if available slots are returned correctly."""
472472
# On a Wednesday, the staff member should have slots from 9 AM to 5 PM
473473
slots = get_available_slots_for_staff(self.next_wednesday, self.staff_member1)
474-
expected_slots = [f"{hour:02d}:00 AM" for hour in range(9, 12)] + ["12:00 PM"] + \
475-
[f"{hour:02d}:00 PM" for hour in range(1, 5)]
474+
expected_slots = [
475+
datetime.datetime(self.next_wednesday.year, self.next_wednesday.month, self.next_wednesday.day, hour) for
476+
hour in range(9, 17)]
476477
self.assertEqual(slots, expected_slots)
477478

478479
def test_booked_slots(self):
@@ -490,7 +491,9 @@ def test_booked_slots(self):
490491

491492
# Now, the staff member should not have that slot available
492493
slots = get_available_slots_for_staff(self.next_wednesday, self.staff_member1)
493-
expected_slots = ['09:00 AM', '11:00 AM', '12:00 PM', '01:00 PM', '02:00 PM', '03:00 PM', '04:00 PM']
494+
expected_slots = [
495+
datetime.datetime(self.next_wednesday.year, self.next_wednesday.month, self.next_wednesday.day, hour, 0) for
496+
hour in range(9, 17) if hour != 10]
494497
self.assertEqual(slots, expected_slots)
495498

496499
def test_no_working_hours(self):

appointment/utils/json_context.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
Since: 2.0.0
77
"""
88

9-
import pytz
109
from django.http import JsonResponse
1110
from django.shortcuts import render
1211
from django.urls import reverse
13-
from django.conf import settings
1412

1513
from appointment.settings import APPOINTMENT_ADMIN_BASE_TEMPLATE, APPOINTMENT_BASE_TEMPLATE
1614
from appointment.utils.db_helpers import username_in_user_model
@@ -20,12 +18,11 @@
2018
def convert_appointment_to_json(request, appointments: list) -> list:
2119
"""Convert a queryset of Appointment objects to a JSON serializable format."""
2220
su = request.user.is_superuser
23-
tz = pytz.timezone(settings.TIME_ZONE)
2421
return [{
2522
"id": appt.id,
2623
"client": appt.client.username if username_in_user_model() else "",
27-
"start_time": tz.localize(appt.get_start_time()).isoformat(),
28-
"end_time": tz.localize(appt.get_end_time()).isoformat(),
24+
"start_time": appt.get_start_time().isoformat(),
25+
"end_time": appt.get_end_time().isoformat(),
2926
"client_name": appt.get_client_name(),
3027
"url": appt.get_absolute_url(request),
3128
"background_color": appt.get_background_color(),
@@ -37,7 +34,6 @@ def convert_appointment_to_json(request, appointments: list) -> list:
3734
"staff_id": appt.appointment_request.staff_member.id,
3835
"additional_info": appt.additional_info,
3936
"want_reminder": appt.want_reminder,
40-
"timezone": settings.TIME_ZONE,
4137
} for appt in appointments]
4238

4339

@@ -59,7 +55,6 @@ def get_generic_context(request, admin=True):
5955
return {
6056
'BASE_TEMPLATE': APPOINTMENT_ADMIN_BASE_TEMPLATE if admin else APPOINTMENT_BASE_TEMPLATE,
6157
'user': request.user,
62-
'timezone': settings.TIME_ZONE,
6358
'is_superuser': request.user.is_superuser,
6459
}
6560

appointment/utils/view_helpers.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,3 @@ def generate_random_id() -> str:
3939
:return: The randomly generated UUID as a hex string
4040
"""
4141
return uuid.uuid4().hex
42-
43-
44-
def get_timezone_txt() -> str:
45-
# TODO: To be better implemented in the future
46-
"""Get the current timezone as a string. To be used in the HTML template when the user is choosing the appointment's
47-
time.
48-
49-
:return: The current timezone in a string format.
50-
"""
51-
tmz = settings.TIME_ZONE
52-
timezone_map = {
53-
'UTC': 'Universal Time Coordinated (UTC)',
54-
'US/Eastern': 'Eastern Daylight Time (US & Canada)',
55-
'US/Central': 'Central Time (US & Canada)',
56-
'US/Mountain': 'Mountain Time (US & Canada)',
57-
'US/Pacific': 'Pacific Time (US & Canada)',
58-
'US/Alaska': 'Alaska Time (US & Canada)',
59-
'US/Hawaii': 'Hawaii Time (US & Canada)',
60-
'Europe/Paris': 'Paris Time (Europe)',
61-
'Europe/London': 'London Time (Europe)',
62-
'EDT': 'Eastern Daylight Time (US & Canada)',
63-
}
64-
return timezone_map.get(tmz, 'Universal Time Coordinated (UTC)')

appointment/views.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66
Since: 1.0.0
77
"""
88

9-
from datetime import date, datetime, timedelta
9+
from datetime import date, timedelta
1010

11-
import pytz
12-
from django.conf import settings
1311
from django.contrib import messages
1412
from django.contrib.auth import login
1513
from django.contrib.auth.forms import SetPasswordForm
1614
from django.db.models import Q
1715
from django.http import HttpResponseRedirect
1816
from django.shortcuts import get_object_or_404, redirect, render
1917
from django.urls import reverse
18+
from django.utils import timezone
2019
from django.utils.encoding import force_str
2120
from django.utils.http import urlsafe_base64_decode
21+
from django.utils.timezone import get_current_timezone_name
2222
from django.utils.translation import gettext as _
2323

2424
from appointment.forms import AppointmentForm, AppointmentRequestForm
@@ -38,12 +38,12 @@
3838
send_reschedule_confirmation_email, \
3939
send_thank_you_email
4040
from appointment.utils.session import get_appointment_data_from_session, handle_existing_email
41-
from appointment.utils.view_helpers import get_locale, get_timezone_txt
41+
from appointment.utils.view_helpers import get_locale
4242
from .decorators import require_ajax
4343
from .messages_ import passwd_error, passwd_set_successfully
4444
from .services import get_appointments_and_slots, get_available_slots_for_staff
4545
from .settings import (APPOINTMENT_PAYMENT_URL, APPOINTMENT_THANK_YOU_URL)
46-
from .utils.date_time import convert_str_to_date, convert_str_to_time
46+
from .utils.date_time import convert_str_to_date
4747
from .utils.error_codes import ErrorCode
4848
from .utils.json_context import get_generic_context_with_extra, json_response
4949

@@ -96,11 +96,10 @@ def get_available_slots_ajax(request):
9696

9797
# Check if the selected_date is today and filter out past slots
9898
if selected_date == date.today():
99-
# Get the current time in EDT timezone
100-
current_time_edt = datetime.now(pytz.timezone(settings.TIME_ZONE)).time()
101-
available_slots = [slot for slot in available_slots if convert_str_to_time(slot) > current_time_edt]
99+
current_time = timezone.now().time()
100+
available_slots = [slot for slot in available_slots if slot.time() > current_time]
102101

103-
custom_data['available_slots'] = available_slots
102+
custom_data['available_slots'] = [slot.strftime('%I:%M %p') for slot in available_slots]
104103
if len(available_slots) == 0:
105104
custom_data['error'] = True
106105
message = _('No availability')
@@ -219,7 +218,7 @@ def appointment_request(request, service_id=None, staff_member_id=None):
219218
'available_slots': available_slots,
220219
'date_chosen': date_chosen,
221220
'locale': get_locale(),
222-
'timezoneTxt': get_timezone_txt(),
221+
'timezoneTxt': get_current_timezone_name(),
223222
'label': label
224223
}
225224
context = get_generic_context_with_extra(request, extra_context, admin=False)
@@ -524,10 +523,10 @@ def prepare_reschedule_appointment(request, id_request):
524523
'all_staff_members': all_staff_members,
525524
'page_title': page_title,
526525
'page_description': page_description,
527-
'available_slots': available_slots,
526+
'available_slots': [slot.strftime('%I:%M %p') for slot in available_slots],
528527
'date_chosen': date_chosen,
529528
'locale': get_locale(),
530-
'timezoneTxt': get_timezone_txt(),
529+
'timezoneTxt': get_current_timezone_name(),
531530
'label': label,
532531
'rescheduled_date': ar.date.strftime("%Y-%m-%d"),
533532
'page_header': page_title,

appointments/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110

111111
LANGUAGE_CODE = "en"
112112

113-
TIME_ZONE = 'Europe/Paris'
113+
TIME_ZONE = 'UTC'
114114

115115
USE_I18N = True
116116

0 commit comments

Comments
 (0)