Полный календар и временные интервалы. Помогите, я делаю это неправильно
Я как-то делаю это неправильно. Я сработал на часовых поясах с помощью Fullcalendar
. Я пробовал установить ignoreTimezone
на true и false, но это, похоже, не имеет значения. Это в коде ниже в двух местах, потому что я не был уверен в документе, где он идет.
Мой источник данных - это скрытое поле формы. Данные, выходящие из Fullcalendar
, корректируются путем добавления 5 часов (CDT). Данные, которые идут в Fullcalendar
, не корректируются путем удаления 5 часов.
В фоновом режиме я просто сохраняю и возвращаю строку JSON без ее обработки (или даже расшифровывая ее)
Page Load:
Data In: Empty, no data
Data Edit: drag from noon to 2pm (CDT), then submit form
Data Out: Use clientEvent to get data, and JSON.stringify to put into form field.
[{"id":6844,"title":"Open","start":"2011-04-19T17:00:00.000Z","end":"2011-04-19T19:00:00.000Z","allDay":false}]
Page Load (after submitting form):
Data In: Use JSON.parse to load data from hidden form field. This is the incoming data, but the event is shifted to 5pm (CDT) in the control.
[{"id":6844,"title":"Open","start":"2011-04-19T17:00:00.000Z","end":"2011-04-19T19:00:00.000Z","allDay":false}]
Data Out: Without changing the control, it now:
[{"id":6844,"title":"Open","start":"2011-04-19T22:00:00.000Z","end":"2011-04-20T00:00:00.000Z","allDay":false}]
Я устанавливаю Fullcalendar
следующим образом:
// Fullcalendar for business hours page
jQuery(document).ready(function() {
jQuery('#edit-submit').bind("click", business_hours_set);
jQuery('#edit-preview').bind("click", business_hours_set);
jQuery('#calendar').fullCalendar({
// configure display
header: {
left: '',
center: '',
right: ''
},
ignoreTimezone: false,
defaultView: 'agendaWeek',
allDaySlot: false,
firstHour: 8,
// configure selection for event creation
selectable: true,
selectHelper: true,
select: business_hours_add,
// configure data source
editable: true,
eventSources: [
{
events: jQuery.parseJSON(jQuery('#fullcalendar_data').val()),
color: '#992B0A',
textColor: 'white',
ignoreTimezone: false
}
],
// configure editing
eventClick: function(calEvent) {
business_hours_delete(calEvent.id);
}
});
alert(jQuery('#fullcalendar_data').val());
});
function business_hours_add(startDate, endDate) {
var calendar = jQuery('#calendar');
var newid = Math.ceil(Math.random()*64000);
calendar.fullCalendar('renderEvent',
{
id: newid,
title: "Open",
start: startDate,
end: endDate,
allDay: false
},
true // make the event "stick"
);
calendar.fullCalendar('unselect');
}
var business_hours_selectedId = -1;
function business_hours_delete(id) {
business_hours_selectedId = id;
jQuery( "#dialog-confirm" ).dialog({
resizable: false,
height:160,
modal: true,
buttons: {
"Yes, delete!": function() {
calendar = jQuery('#calendar');
calendar.fullCalendar( 'removeEvents', business_hours_selectedId);
jQuery( this ).dialog( "close" );
},
Cancel: function() {
jQuery( this ).dialog( "close" );
}
}
}, id);
}
function business_hours_set() {
var data = jQuery('#calendar').fullCalendar( 'clientEvents' );
// data is cyclical. Create a new data structure to stringify.
var ret = [];
for(var i=0; i<data.length; i++) {
var datum = {
id: data[i].id,
title: data[i].title,
start: data[i].start,
end: data[i].end,
allDay: data[i].allDay
}
ret[i] = datum;
}
// stringify and return
jQuery('#fullcalendar_data').val(JSON.stringify(ret));
alert(JSON.stringify(ret));
}
Что я делаю неправильно?
Спасибо заранее, Майк
Ответы
Ответ 1
Вы устанавливаете даты, установленные в формате CDT, как даты UTC (таким образом, получая 5-часовую смену), поэтому, когда они считываются обратно, они переустанавливаются на CDT и т.д.
Поскольку не существует способа установить часовой пояс для объектов даты JS, Fullcalendar представляет их внутренне в качестве дат UTC, но корректирует смещение временной зоны во время ввода.
$.fullCalendar.parseISO8601('2011-04-19T17:00:00.000-05:00');
// Tue Apr 19 2011 22:00:00 GMT+0000 (GMT) <-- note time shift
Вот почему, когда вы сериализуете JSON, вы получаете строку с часовым поясом "Zulu" (UTC):
var dt = $.fullCalendar.parseISO8601('2011-04-19T17:00:00.000-05:00');
JSON.stringify( dt ); // "2011-04-19T22:00:00.000Z"
Вам нужна дата в вашем часовом поясе. Это не похоже на то, что у Fullcalendar есть это, поэтому вам нужно будет работать:
// detect local timezone offset
var localoffset = (new Date()).getTimezoneOffset();
// "unadjust" date
ret = new Date( ret.valueOf() + (localoffset * 60 * 1000) );
// serialize
function pad (n) { return String(n).replace(/^(-?)(\d)$/,'$10$2'); }
JSON.stringify( ret )
// replace Z timezone with current
.replace('Z', pad(Math.floor(localoffset / 60))+':'+ pad(localoffset % 60));
// should result in something like: "2011-04-21T19:00:00.000-05:00"
Может быть, лучший способ решить это с помощью Fullcalendar, но я не знаком с ним.
Код не тестировался: я живу в GMT без DST и не хочу связываться с моей системой, чтобы увидеть ее работу (YMMW).: -)
Ответ 2
У меня был тот же сдвиг по времени в FullCalendar.
Проверьте свой часовой пояс на сервере, когда я изменил его на свое, это поможет мне.
Вы можете попробовать сделать это несколькими способами:
На serer:
[root @mx ~] # mv/etc/localtime/etc/localtime.old
[root @mx ~] # ln -s/usr/share/zoneinfo/Европа/Москва/etc/localtime
Или в PHP script (который возвращает строку JSON):
date_default_timezone_set ( 'Europe/Moscow');
P.S.
Не забудьте изменить "Европа/Москва" на ваши значения: -)
Затем вы должны установить свое действительное время в новом часовом поясе (команда "date" );