У меня есть рабочий процесс, который копирует элементы из стандартного списка Календаря во второй стандартный список Календаря. Но копии содержат меньше деталей о любом элементе календаря, чем оригинал. Это прекрасно работает, за исключением того, что поля Start Time
и End Time
копируются в UTC время, и нам нужно, чтобы это время отображалось в местном часовом поясе пользователя (у нас есть сотрудники по всему миру, поэтому это не может быть статическим регулировка). Мне известно, что SharePoint хранит все даты / время в формате UTC, и я понимаю, почему.
Мое решение этой проблемы состоит в том, чтобы (в главном календаре) создать два скрытых столбца даты / времени, которые я бы заполнил датами / временем из столбцов календаря EventDate
и EndDate
(значения UTC), но эти новые значения будут исправлены для смещения часового пояса с использованием объектной модели на стороне клиента SharePoint (с использованием JS) . Тогда мой рабочий процесс скопировал бы эти исправленные даты / время во второй календарь.
Следующий код работает. Мои обработчики успеха вызываются для каждой итерации элементов списка, и мой зарегистрированный вывод показывает все правильные значения. Однако после выполнения кода два поля даты, которые должны быть обновлены / установлены для каждого элемента с помощью кода, остаются пустыми.
<script src="/_layouts/15/sp.runtime.js"></script>
<script src="/_layouts/15/sp.js"></script>
<script>
var siteUrl = "https://duckcreek.sharepoint.com/sites/DCU";
function loadListItems(siteUrl) {
var ctx = new SP.ClientContext(siteUrl);
var oList = ctx.get_web().get_lists().getByTitle("Master Calendar");
var camlQuery = new SP.CamlQuery();
this.collListItem = oList.getItems(camlQuery);
// EventDate and EndDate are the pre-defined fields (from the Event
// content type) that represent the event start and end date / times
// CorrectedStartDateTime and CorrectedEndDateTime are pre-existing
// Date / Time fields in the list.
ctx.load(collListItem,
"Include(Id, DisplayName, EventDate, EndDate, CorrectedStartDateTime, CorrectedEndDateTime)");
ctx.executeQueryAsync(
Function.createDelegate(this, this.onLoadListItemsSucceeded),
Function.createDelegate(this, this.onLoadListItemsFailed));
}
function onLoadListItemsSucceeded(sender, args) {
var ctx = new SP.ClientContext(siteUrl);
var oList = ctx.get_web().get_lists().getByTitle("Master Calendar");
var listItemInfo = "";
var listItemEnumerator = collListItem.getEnumerator();
while (listItemEnumerator.moveNext()) {
// List is loaded. Enumerate the list items
let oListItem = listItemEnumerator.get_current();
// Get the Calendar item Start and End dates as stored in SharePoint (UTC)
let startDateString = oListItem.get_item("EventDate").toString();
let endDateString = oListItem.get_item("EndDate").toString();
// Get the GMT time zone offset
let startDateOffsetHours = parseInt(startDateString.split("GMT-")[1]) / 100;
let endDateOffsetHours = parseInt(endDateString.split("GMT-")[1]) / 100;
// Create new dates that are the same as the originals
let resultStartDate = new Date(startDateString);
let resultEndDate = new Date(endDateString);
// Adjust the new dates to be correct for the local time zone based on the UTC offset
resultStartDate.setHours(resultStartDate.getHours() + startDateOffsetHours);
resultEndDate.setHours(resultEndDate.getHours() + endDateOffsetHours);
// Update the two placeholder fields in the current list item with the corrected dates
oListItem.set_item("CorrectedStartDateTime", resultStartDate);
oListItem.set_item("CorrectedEndDateTime", resultEndDate);
// Update SharePoint
oListItem.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onSetCorrectDateTimesSucceeded),
Function.createDelegate(this, this.onSetCorrectDateTimesFailed)
);
// This is just for diagnostics, but it does show the correct data.
// And since we are using .get_item() here, it would seem that we
// are pulling the correct data out of SharePoint, but the two "Corrected"
// fields remain empty after this function completes successfully.
listItemInfo += "\nDisplay name: " + oListItem.get_displayName() +
"\n\tEventDate: " + oListItem.get_item("EventDate") +
"\n\tEndDate: " + oListItem.get_item("EndDate") +
"\n\t\tCorrectedStartDateTime: " + oListItem.get_item("CorrectedStartDateTime") +
"\n\t\tCorrectedEndDateTime: " + oListItem.get_item("CorrectedEndDateTime") +
"\n--------------------------------------------------------------------------------";
}
console.log(listItemInfo.toString());
}
function onLoadListItemsFailed(sender, args) {
console.log("Request failed!" + args.get_message() + "\n" + args.get_stackTrace());
}
function onSetCorrectDateTimesSucceeded() {
console.log("Item updated!");
}
function onSetCorrectDateTimesFailed(sender, args) {
console.log("Request failed!" + args.get_message() + "\n" + args.get_stackTrace());
}
loadListItems(siteUrl);
</script>
И вот одна из записей, которые создает код (фактически он производит одну из следующих записей для каждого элемента в первом календаре, как и должно быть):
Display name: NEW TEST
EventDate: Mon Dec 31 2018 19:00:00 GMT-0500 (Eastern Standard Time)
EndDate: Tue Jan 01 2019 18:59:00 GMT-0500 (Eastern Standard Time)
CorrectedStartDateTime: Tue Jan 01 2019 00:00:00 GMT-0500 (Eastern Standard Time)
CorrectedEndDateTime: Tue Jan 01 2019 23:59:00 GMT-0500 (Eastern Standard Time)
--------------------------------------------------------------------------------
Однако элементы календаря не обновляют два «исправленных» поля: