javascript 全日历和时区。求助,我做错了
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5724142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fullcalendar and timezones. Help, I'm doing it wrong
提问by Mike
I'm doing it wrong somehow. I'm getting tripped up on timezones with Fullcalendar. I've tried setting ignoreTimezoneto true and false, but it doesn't seem to matter. It's in the code below in two places because I wasn't sure from the doc where it goes.
我以某种方式做错了。我被时区绊倒了Fullcalendar。我试过设置ignoreTimezone为 true 和 false,但这似乎无关紧要。它在下面的代码中的两个地方,因为我不确定文档的去向。
My data source is a hidden form field. Data that goes outof FullCalendaris adjusted by adding 5 hours (CDT). Data that goes into FullCalendarisn't adjusted by removing 5 hours.
我的数据源是一个隐藏的表单域。超出的数据FullCalendar通过增加 5 小时 (CDT) 进行调整。数据云中,以FullCalendar不是除去5小时调整。
On the back-end, I'm just saving and returning the JSON string without processing it (or even decoding it)
在后端,我只是保存并返回 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's now:
[{"id":6844,"title":"Open","start":"2011-04-19T22:00:00.000Z","end":"2011-04-20T00:00:00.000Z","allDay":false}]
I setup the Fullcalendarlike this:
我设置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));
}
What am I doing wrong?
我究竟做错了什么?
Thanks in advance, Mike
提前致谢,迈克
回答by Borgar
You are serializing CDT-adjusted dates as UTC dates (thus getting a 5 hour shift) so when they are read back in they get re-adjusted to CDT, and so on..
您将 CDT 调整后的日期序列化为 UTC 日期(因此有 5 小时的轮班),因此当它们被读回时,它们会重新调整为 CDT,依此类推。
Because there isn't a way to set a timezone on JS date objects, Fullcalendar represents them internally as UTC dates, but adjusts for timezone offset on input time.
因为没有办法在 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
This is why, when you serialize to JSON, you get a string with the "Zulu" (UTC) timezone:
这就是为什么当您序列化为 JSON 时,您会得到一个带有“Zulu”(UTC)时区的字符串:
var dt = $.fullCalendar.parseISO8601('2011-04-19T17:00:00.000-05:00');
JSON.stringify( dt ); // "2011-04-19T22:00:00.000Z"
You need the date back to your timezone. It doesn't look like Fullcalendar has this so you'll need to to the work:
您需要将日期追溯到您的时区。看起来 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)$/,''); }
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"
There may be a better way of solving this using Fullcalendar but I am not familiar with it.
使用 Fullcalendar 可能有更好的方法来解决这个问题,但我不熟悉它。
Code is untested: I live in GMT with no-DST and don't really want to mess with my system just to see it work (YMMW). :-)
代码未经测试:我住在没有 DST 的格林威治标准时间,并且真的不想为了看到它工作而弄乱我的系统(YMMW)。:-)
回答by Sergey Bogdanov
I had the same timeshift in FullCalendar. Check out your timezone on server, when I changed it to my own it help me. You may try to do it in few ways:
我在 FullCalendar 中也有同样的时移。在服务器上查看您的时区,当我将其更改为我自己的时区时,它会帮助我。您可以尝试通过以下几种方式来做到这一点:
On serer:
在服务器上:
[root@mx ~]# mv /etc/localtime /etc/localtime.old
[root@mx ~]# ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime
[root@mx ~]# mv /etc/localtime /etc/localtime.old
[root@mx ~]# ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime
Or in PHP script (which returns JSON string):
或者在 PHP 脚本中(返回 JSON 字符串):
date_default_timezone_set('Europe/Moscow');
date_default_timezone_set('欧洲/莫斯科');
P.S. Don't forget to change "Europe/Moscow" to your values :-)
PS不要忘记将“欧洲/莫斯科”更改为您的价值观:-)
Then you have to set your valid time in new time zone ("date" command);
然后你必须在新的时区设置你的有效时间(“date”命令);

