我有一个工作流程,可将项目从标准日历列表复制到第二个标准日历列表。但是副本所包含的有关任何给定日历项目的详细信息要少于原始内容。除Start Time
和End Time
字段以UTC时间复制并且我们需要将这些时间显示在用户的本地时区(我们在世界各地都有员工之外,它可以使用)外,此方法工作正常t是静态调整)。我知道SharePoint将所有日期/时间存储为UTC,我知道为什么。
我对此问题的解决方案是(在主日历中)创建两个隐藏的“日期/时间”列,这些列将由EventDate
和EndDate
日历列(UTC)中的日期/时间填充值),但可以使用SharePoint Client Side Object Model (using 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)
--------------------------------------------------------------------------------
但是,日历项目没有更新两个“更正”字段:
答案 0 :(得分:1)
您可以在SP.ClientContext
函数中重新创建onLoadListItemsSucceeded
,因此您实际上不会为原始列表项调用update。将其保存在变量中,然后重新使用。
<script src="/_layouts/15/sp.runtime.js"></script>
<script src="/_layouts/15/sp.js"></script>
<script>
var siteUrl = "https://duckcreek.sharepoint.com/sites/DCU";
var ctx;
function loadListItems(siteUrl) {
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 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>
时区偏移量可以为负(-)或正(+),因此这些行可能不完整
// Get the GMT time zone offset
let startDateOffsetHours = parseInt(startDateString.split("GMT-")[1]) / 100;
let endDateOffsetHours = parseInt(endDateString.split("GMT-")[1]) / 100;