Skip to content

Commit 43c635b

Browse files
kaustavb12xitij2000
authored andcommitted
feat: change studio schedule datetime inputs to user timezone
(cherry picked from commit ed4c7cc) (cherry picked from commit 1c228db)
1 parent 4d801fe commit 43c635b

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

cms/djangoapps/contentstore/views/course.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
from openedx.core.djangoapps.credit.tasks import update_credit_course_requirements
7575
from openedx.core.djangoapps.models.course_details import CourseDetails
7676
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
77+
from openedx.core.djangoapps.user_api.models import UserPreference
7778
from openedx.core.djangolib.js_utils import dump_js_escaped_json
7879
from openedx.core.lib.course_tabs import CourseTabPluginManager
7980
from openedx.core.lib.courses import course_image_url
@@ -1249,6 +1250,12 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
12491250
elif 'application/json' in request.META.get('HTTP_ACCEPT', ''): # pylint: disable=too-many-nested-blocks
12501251
if request.method == 'GET':
12511252
course_details = CourseDetails.fetch(course_key)
1253+
1254+
# Fetch the prefered timezone setup by the user
1255+
# and pass it as part of Json response
1256+
user_timezone = UserPreference.get_value(request.user, 'time_zone')
1257+
course_details.user_timezone = user_timezone
1258+
12521259
return JsonResponse(
12531260
course_details,
12541261
# encoder serializes dates, old locations, and instances

cms/static/cms/js/spec/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
'jquery.simulate': 'xmodule_js/common_static/js/vendor/jquery.simulate',
4848
'datepair': 'xmodule_js/common_static/js/vendor/timepicker/datepair',
4949
'date': 'xmodule_js/common_static/js/vendor/date',
50+
'moment-timezone': 'common/js/vendor/moment-timezone-with-data',
5051
moment: 'common/js/vendor/moment-with-locales',
5152
'text': 'xmodule_js/common_static/js/vendor/requirejs/text',
5253
'underscore': 'common/js/vendor/underscore',

cms/static/js/utils/date_utils.js

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
define(['jquery', 'date', 'js/utils/change_on_enter', 'jquery.ui', 'jquery.timepicker'],
2-
function($, date, TriggerChangeEventOnEnter) {
1+
define(['jquery', 'date', 'js/utils/change_on_enter', 'moment-timezone', 'jquery.ui', 'jquery.timepicker'],
2+
function($, date, TriggerChangeEventOnEnter, moment) {
33
'use strict';
44

55
function getDate(datepickerInput, timepickerInput) {
@@ -67,15 +67,51 @@ define(['jquery', 'date', 'js/utils/change_on_enter', 'jquery.ui', 'jquery.timep
6767
return obj;
6868
}
6969

70-
function setupDatePicker(fieldName, view, index) {
70+
/**
71+
* Calculates the utc offset in miliseconds for given
72+
* timezone and subtracts it from given localized time
73+
* to get time in UTC
74+
*
75+
* @param {Date} localTime JS Date object in Local Time
76+
* @param {string} timezone IANA timezone name ex. "Australia/Brisbane"
77+
* @returns JS Date object in UTC
78+
*/
79+
function convertLocalizedDateToUTC(localTime, timezone) {
80+
const localTimeMS = localTime.getTime();
81+
const utcOffset = moment.tz(localTime, timezone)._offset;
82+
return new Date(localTimeMS - (utcOffset * 60 *1000));
83+
}
84+
85+
/**
86+
* Returns the timezone abbreviation for given
87+
* timezone name
88+
*
89+
* @param {string} timezone IANA timezone name ex. "Australia/Brisbane"
90+
* @returns Timezone abbreviation ex. "AEST"
91+
*/
92+
function getTZAbbreviation(timezone) {
93+
return moment(new Date()).tz(timezone).format('z');
94+
}
95+
96+
/**
97+
* Converts the given datetime string from UTC to localized time
98+
*
99+
* @param {string} utcDateTime JS Date object with UTC datetime
100+
* @param {string} timezone IANA timezone name ex. "Australia/Brisbane"
101+
* @returns Formatted datetime string with localized timezone
102+
*/
103+
function getLocalizedCurrentDate(utcDateTime, timezone) {
104+
const localDateTime = moment(utcDateTime).tz(timezone);
105+
return localDateTime.format('YYYY-MM-DDTHH[:]mm[:]ss');
106+
}function setupDatePicker(fieldName, view, index) {
71107
var cacheModel;
72108
var div;
73109
var datefield;
74-
var timefield;
110+
var timefield;var tzfield;
75111
var cacheview;
76112
var setfield;
77113
var currentDate;
78-
if (typeof index !== 'undefined' && view.hasOwnProperty('collection')) {
114+
var timezone;if (typeof index !== 'undefined' && view.hasOwnProperty('collection')) {
79115
cacheModel = view.collection.models[index];
80116
div = view.$el.find('#' + view.collectionSelector(cacheModel.cid));
81117
} else {
@@ -84,11 +120,16 @@ define(['jquery', 'date', 'js/utils/change_on_enter', 'jquery.ui', 'jquery.timep
84120
}
85121
datefield = $(div).find('input.date');
86122
timefield = $(div).find('input.time');
87-
cacheview = view;
123+
tzfield = $(div).find('span.timezone');
124+
cacheview = view;
125+
126+
timezone = cacheModel.get('user_timezone');
88127
setfield = function(event) {
89128
var newVal = getDate(datefield, timefield);
90129

91-
// Setting to null clears the time as well, as date and time are linked.
130+
if (timezone) {
131+
newVal = convertLocalizedDateToUTC(newVal, timezone);
132+
}// Setting to null clears the time as well, as date and time are linked.
92133
// Note also that the validation logic prevents us from clearing the start date
93134
// (start date is required by the back end).
94135
cacheview.clearValidationErrors();
@@ -109,8 +150,13 @@ define(['jquery', 'date', 'js/utils/change_on_enter', 'jquery.ui', 'jquery.timep
109150
if (cacheModel) {
110151
currentDate = cacheModel.get(fieldName);
111152
}
112-
// timepicker doesn't let us set null, so check that we have a time
113-
if (currentDate) {
153+
if (timezone) {
154+
const tz = getTZAbbreviation(timezone);
155+
$(tzfield).text("("+tz+")");
156+
} // timepicker doesn't let us set null, so check that we have a time
157+
if (currentDate) {if (timezone) {
158+
currentDate = getLocalizedCurrentDate(currentDate, timezone);
159+
}
114160
setDate(datefield, timefield, currentDate);
115161
} else {
116162
// but reset fields either way

0 commit comments

Comments
 (0)