很明显,我缺少在FullCalendar中创建事件的完全根本的东西,因此,看看是否有人有解决方案或建议。
目标:具有日历功能,辅导员可以使用该功能让客户知道他们的开放时间(时间不是全天,可以短至一小时)。
顾问和客户不一定要处于同一时区,因此必须以反映各个时区的适当时间的方式来创建事件。
例如,一名辅导员(在新西兰)创建了一个可用活动,始于:
Friday, 1 March 2019 at 7:00:00 a.m.
纽约的客户应将该事件视为:
Thursday, 28 February 2019 at 1:00:00 p.m
这是我在努力实现的目标,不确定使用FullCalendar能否实现
在创建事件时,“时区”选项似乎没有任何区别(是的,我完全接受我可能做的事情完全错误)。
在这个calendar小提琴中,我将时区设置如下:
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
timezone: 'Pacific/Auckland'
....
});
当我在2019年3月1日上午7点选择FullCalendar时,其开始日期为UTC:
Fri Mar 01 2019 07:00:00 GMT+0000
如果我使用moment.tz将开始日期格式化为太平洋/奥克兰:
console.log(moment.tz(startDate, 'Pacific/Auckland').format());
我得到:
2019-03-01T20:00:00+13:00
这是对原始开始日期的正确转换,但显然在这种情况下没有用,因为它不是预期的日期。
如果我将事件拖放到2019年3月1日上午7点(请参阅相同的fiddle),然后单击它以使用以下命令将事件对象写到控制台:
eventClick: function(event, element)
{
console.log("event: ");
console.log(event);
},
显示以下内容(为简单起见,在此缩短):
"_fc3"
_start
Fri Mar 01 2019 07:00:00 GMT+0000 {...}
_a
[2019, 2, 1, 4 more...]
_ambigTime
false
_ambigZone
true
_d
Fri Mar 01 2019 20:00:00 GMT+1300 (New Zealand Daylight Time) {}
所以 _start 是星期五2019年3月1日格林尼治标准时间+0000-它(现在忽略偏移量)是应该的时间(例如,应该是上午7点)
和 _d 是2019年3月1日星期五格林尼治标准时间+1300(新西兰夏令时间)。
但是我显然不能保存 _d 的值,因为在这种情况下显然不是期望的时间。
此外,如果我将_start日期原样保存到MySQL datetime字段中,它将存储为“ 2019-03-01 07:00:00”(MySQL服务器设置为UTC),并且如果导入了它日历中显示为2019年3月1日上午7点,并且不考虑用户时区。
我一如既往地检查了可能的答案,但似乎没有答案可以解决这个问题。
正如我所说,我希望我只是缺少一些基本知识。
任何建议将不胜感激。
编辑:更新小提琴
EDIT (添加图片和说明)
在fiddle中(如本图所示):
所以我想我在这里缺少的是如何获取公共启动属性
我正在寻找/期望的开始时间是:
Sat Mar 02 2019 07:00:00 GMT+1300 (New Zealand Daylight Time)
这是UTC时间:
Friday, 1 March 2019 at 6:00:00 p.m. UTC
因此,UTC星期五时间正是我希望保存在数据库中的时间。
注意:我实际上在新西兰,因此该时区以外的人的提琴会有所不同。
答案 0 :(得分:0)
我通过将所有日期时间存储在UTC中来完成类似的项目。这样,很容易显示任何时区的时间。
我已经实现了以下目标: 1.我创建了一个下拉列表以选择时区。 2.初始化页面上的全日历 3.使用moment.js猜测用户的时区。 4.将日历时区转换为UTC 5. Ajax使用UTC时间保存删除的事件 6.呈现事件时,从下拉列表中显示默认时区,否则显示用户选择的时区。
let calendar = $("#calendar").fullCalendar({
defaultView: "agendaWeek",
header: {
left: "prev,next today",
center: "title",
right: "month,agendaWeek,agendaDay"
},
now: moment().format("Y-MM-DD HH:mm:ss"),
height: "auto",
slotDuration: "00:30:00",
defaultTimedEventDuration: "00:30:00",
timezone: "local",
weekends: false,
dragRevertDuration: 0,
allDaySlot: false,
slotEventOverlap: false,
editable: true,
eventStartEditable: true,
eventDurationEditable: true,
droppable: true,
eventSources: [
fcSources.loadEvents,
fcSources.loadEwsEvents
],
businessHours: [ // highlight working hours
{
dow: [ 1, 2, 3, 4, 5], // weekdays
start: '08:00',
end: '18:00'
}
],
drop: function (date) {
//Call when you drop slot for the first time
let defaultDuration = moment.duration($("#calendar").fullCalendar("option", "defaultTimedEventDuration"));
$("input[name='EVENTS[ID]']").val(null);
$("input[name='EVENTS[TITLE]']").val($(this).data().event.title);
$("input[name='EVENTS[EVENT_START]']").val($(this).convertTimeToUTC(date));
$("input[name='EVENTS[EVENT_END]']").val($(this).convertTimeToUTC(date.clone().add(defaultDuration)));
$(this).addCalendarEvent();
},
eventOverlap: function (stillEvent, movingEvent) {
return stillEvent.allDay && movingEvent.allDay;
},
eventDrop: function (event) {
$("input[name='EVENTS[ID]']").val(event.id);
$("input[name='EVENTS[TITLE]']").val(event.title);
$("input[name='EVENTS[EVENT_START]']").val($(this).convertTimeToUTC(event.start));
$("input[name='EVENTS[EVENT_END]']").val($(this).convertTimeToUTC(event.end));
//if the call is confirmed or complete then do not move it
if ($.trim(event.status) !== "COMPLETE" && $.trim(event.status) !== "CONFIRMED") {
$(this).updateCalendarEvent();
}
}
});
//然后选择下拉列表
//self initialising function for timezones dropdown
(function(window, document, $, undefined){
const _t = (s) => {
if (i18n !== void 0 && i18n[s]) {
return i18n[s];
}
return s;
};
const timezones = [
"Etc/GMT+12",
"Pacific/Midway",
"Pacific/Honolulu",
"America/Juneau",
"America/Dawson",
"America/Boise",
"America/Chihuahua",
"America/Phoenix",
"America/Chicago",
"America/Regina",
"America/Mexico_City",
"America/Belize",
"America/Detroit",
"America/Indiana/Indianapolis",
"America/Bogota",
"America/Glace_Bay",
"America/Caracas",
"America/Santiago",
"America/St_Johns",
"America/Sao_Paulo",
"America/Argentina/Buenos_Aires",
"America/Godthab",
"Etc/GMT+2",
"Atlantic/Azores",
"Atlantic/Cape_Verde",
"GMT",
"Africa/Casablanca",
"Atlantic/Canary",
"Europe/Belgrade",
"Europe/Sarajevo",
"Europe/Brussels",
"Europe/Amsterdam",
"Africa/Algiers",
"Europe/Bucharest",
"Africa/Cairo",
"Europe/London",
"Europe/Helsinki",
"Europe/Athens",
"Asia/Jerusalem",
"Africa/Harare",
"Europe/Moscow",
"Asia/Kuwait",
"Africa/Nairobi",
"Asia/Baghdad",
"Asia/Tehran",
"Asia/Dubai",
"Asia/Baku",
"Asia/Kabul",
"Asia/Yekaterinburg",
"Asia/Karachi",
"Asia/Kolkata",
"Asia/Kathmandu",
"Asia/Dhaka",
"Asia/Colombo",
"Asia/Almaty",
"Asia/Rangoon",
"Asia/Bangkok",
"Asia/Krasnoyarsk",
"Asia/Shanghai",
"Asia/Kuala_Lumpur",
"Asia/Taipei",
"Australia/Perth",
"Asia/Irkutsk",
"Asia/Seoul",
"Asia/Tokyo",
"Asia/Yakutsk",
"Australia/Darwin",
"Australia/Adelaide",
"Australia/Sydney",
"Australia/Brisbane",
"Australia/Hobart",
"Asia/Vladivostok",
"Pacific/Guam",
"Asia/Magadan",
"Pacific/Fiji",
"Pacific/Auckland",
"Pacific/Tongatapu"
];
const i18n = {
"Etc/GMT+12": "International Date Line West",
"Pacific/Midway": "Midway Island, Samoa",
"Pacific/Honolulu": "Hawaii",
"America/Juneau": "Alaska",
"America/Dawson": "Pacific Time (US and Canada); Tijuana",
"America/Boise": "Mountain Time (US and Canada)",
"America/Chihuahua": "Chihuahua, La Paz, Mazatlan",
"America/Phoenix": "Arizona",
"America/Chicago": "Central Time (US and Canada)",
"America/Regina": "Saskatchewan",
"America/Mexico_City": "Guadalajara, Mexico City, Monterrey",
"America/Belize": "Central America",
"America/Detroit": "Eastern Time (US and Canada)",
"America/Indiana/Indianapolis": "Indiana (East)",
"America/Bogota": "Bogota, Lima, Quito",
"America/Glace_Bay": "Atlantic Time (Canada)",
"America/Caracas": "Caracas, La Paz",
"America/Santiago": "Santiago",
"America/St_Johns": "Newfoundland and Labrador",
"America/Sao_Paulo": "Brasilia",
"America/Argentina/Buenos_Aires": "Buenos Aires, Georgetown",
"America/Godthab": "Greenland",
"Etc/GMT+2": "Mid-Atlantic",
"Atlantic/Azores": "Azores",
"Atlantic/Cape_Verde": "Cape Verde Islands",
"Europe/London": "Dublin, Edinburgh, Lisbon, London",
"Africa/Casablanca": "Casablanca, Monrovia",
"Atlantic/Canary": "Canary Islands",
"Europe/Belgrade": "Belgrade, Bratislava, Budapest, Ljubljana, Prague",
"Europe/Sarajevo": "Sarajevo, Skopje, Warsaw, Zagreb",
"Europe/Brussels": "Brussels, Copenhagen, Madrid, Paris",
"Europe/Amsterdam": "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna",
"Africa/Algiers": "West Central Africa",
"Europe/Bucharest": "Bucharest",
"Africa/Cairo": "Cairo",
"Europe/Helsinki": "Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius",
"Europe/Athens": "Athens, Istanbul, Minsk",
"Asia/Jerusalem": "Jerusalem",
"Africa/Harare": "Harare, Pretoria",
"Europe/Moscow": "Moscow, St. Petersburg, Volgograd",
"Asia/Kuwait": "Kuwait, Riyadh",
"Africa/Nairobi": "Nairobi",
"Asia/Baghdad": "Baghdad",
"Asia/Tehran": "Tehran",
"Asia/Dubai": "Abu Dhabi, Muscat",
"Asia/Baku": "Baku, Tbilisi, Yerevan",
"Asia/Kabul": "Kabul",
"Asia/Yekaterinburg": "Ekaterinburg",
"Asia/Karachi": "Islamabad, Karachi, Tashkent",
"Asia/Kolkata": "Chennai, Kolkata, Mumbai, New Delhi",
"Asia/Kathmandu": "Kathmandu",
"Asia/Dhaka": "Astana, Dhaka",
"Asia/Colombo": "Sri Jayawardenepura",
"Asia/Almaty": "Almaty, Novosibirsk",
"Asia/Rangoon": "Yangon Rangoon",
"Asia/Bangkok": "Bangkok, Hanoi, Jakarta",
"Asia/Krasnoyarsk": "Krasnoyarsk",
"Asia/Shanghai": "Beijing, Chongqing, Hong Kong SAR, Urumqi",
"Asia/Kuala_Lumpur": "Kuala Lumpur, Singapore",
"Asia/Taipei": "Taipei",
"Australia/Perth": "Perth",
"Asia/Irkutsk": "Irkutsk, Ulaanbaatar",
"Asia/Seoul": "Seoul",
"Asia/Tokyo": "Osaka, Sapporo, Tokyo",
"Asia/Yakutsk": "Yakutsk",
"Australia/Darwin": "Darwin",
"Australia/Adelaide": "Adelaide",
"Australia/Sydney": "Canberra, Melbourne, Sydney",
"Australia/Brisbane": "Brisbane",
"Australia/Hobart": "Hobart",
"Asia/Vladivostok": "Vladivostok",
"Pacific/Guam": "Guam, Port Moresby",
"Asia/Magadan": "Magadan, Solomon Islands, New Caledonia",
"Pacific/Fiji": "Fiji Islands, Kamchatka, Marshall Islands",
"Pacific/Auckland": "Auckland, Wellington",
"Pacific/Tongatapu": "Nuku'alofa"
};
//get current time
const dateTimeUtc = moment().utc();
document.querySelector(".js-TimeUtc").innerHTML = dateTimeUtc.format("ddd, DD MMM YYYY HH:mm:ss");
const dateTimeLocal = moment().utc(moment.tz.guess());
document.querySelector(".js-TimeLocal").innerHTML = dateTimeLocal.format("ddd, DD MMM YYYY HH:mm:ss");
const selectorOptions = moment.tz.names()
.filter(tz => {
return timezones.includes(tz)
})
.reduce((memo, tz) => {
memo.push({
name: tz,
offset: moment.tz(tz).utcOffset()
});
return memo;
}, [])
.sort((a, b) => {
return a.offset - b.offset
})
.reduce((memo, tz) => {
const timezone = tz.offset ? moment.tz(tz.name).format('Z') : '';
return memo.concat(`<option value="${tz.name}">${_t(tz.name)}</option>`);
}, "");
document.querySelector(".js-Selector").innerHTML = selectorOptions;
$(".js-Selector").on("change", e => {
const timestamp = dateTimeUtc.unix();
const offset = moment.tz(e.target.value).utcOffset() * 60;
const dateTimeSelected = moment.unix(timestamp + offset).utc();
document.querySelector(".js-TimeSelected").innerHTML = dateTimeSelected.format("ddd, DD MMM YYYY HH:mm:ss");
timeZone = $(".js-Selector").val();
if(timeZone != moment.tz.guess()) {
let timezoneWarningMessage = '<div class="alert alert-warning timezone-warning" role="alert" class="btn btn-indigo btn-sm ml-0 waves-effect waves-light bg-warning timezone-warning">' +
'Your timezone has been changed to <b>' + timeZone + '</b></div>';
if($(".timezone-warning").length > 0) {
$(".timezone-warning").replaceWith(timezoneWarningMessage);
} else {
$(".fc-view-container").prepend(timezoneWarningMessage);
}
} else {
$(".timezone-warning").replaceWith('');
}
$('#calendar').fullCalendar('option', 'timezone', $(".js-Selector").val() || false);
});
document.querySelector(".js-Selector").value = "Europe/London";
const event = new Event("change");
document.querySelector(".js-Selector").dispatchEvent(event);
$(".js-Selector").chosen();
})(window, document, jQuery);
//现在将所选时区传递给事件源
let loadEvents: {
url: "", //your url,
type: "GET",
cache: true,
dataType: "json",
success: function (data) {
//based on the dropdown changetimezone of each event
let updatedTime = [];
$.each(data.events, function( k, v ) {
v.start = moment.tz(v.start, timeZone);
v.end = moment.tz(v.end, timeZone);
updatedTime[k] = v ;
});
return updatedTime;
}
}
//function to convert fullcalendar time to utc
$.fn.convertTimeToUTC = function (convertTime) {
if($(this).isObject(convertTime)) {
return moment.tz(convertTime.format("Y-MM-DD HH:mm:ss"), moment.tz.guess()).utc().format("Y-MM-DD HH:mm:ss");
}
};
// Returns if a value is an object
$.fn.isObject = function(value) {
return value && typeof value === 'object';
};