From 7d42712f436c8f040fda38288d34b5e9d3085132 Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Fri, 28 Dec 2012 20:10:45 +0000 Subject: [PATCH] first steps for better timezone management --- js/data/timezones.js | 84 +++++++++++++++++++++++++++++++++++ js/dialogs/ImportPanel.js | 49 +++++++++++++++++++- manifest.xml | 2 + php/ical/calendar.txt | 4 +- php/ical/class.icalparser.php | 24 +++++++--- 5 files changed, 152 insertions(+), 11 deletions(-) create mode 100644 js/data/timezones.js diff --git a/js/data/timezones.js b/js/data/timezones.js new file mode 100644 index 0000000..4de1ba0 --- /dev/null +++ b/js/data/timezones.js @@ -0,0 +1,84 @@ +Ext.namespace("Zarafa.plugins.calendarimporter.data"); + +Zarafa.plugins.calendarimporter.data.Timezones = Ext.extend(Object, { + + store : [ + ['Pacific/Midway','(UTC -11:00) Midway, Niue, Pago Pago'], + ['America/Adak','(UTC -10:00) Adak'], + ['Pacific/Fakaofo','(UTC -10:00) Fakaofo, Honolulu, Johnston, Rarotonga, Tahiti'], + ['Pacific/Marquesas','(UTC -10:30) Marquesas'], + ['America/Anchorage','(UTC -09:00) Anchorage, Juneau, Nome, Sitka, Yakutat'], + ['Pacific/Gambier','(UTC -09:00) Gambier'], + ['America/Dawson','(UTC -08:00) Dawson, Los Angeles, Tijuana, Vancouver, Whitehorse'], + ['America/Santa_Isabel','(UTC -08:00) Santa Isabel'], + ['America/Metlakatla','(UTC -08:00) Metlakatla, Pitcairn'], + ['America/Dawson_Creek','(UTC -07:00) Dawson Creek, Hermosillo, Phoenix'], + ['America/Chihuahua','(UTC -07:00) Chihuahua, Mazatlan'], + ['America/Boise','(UTC -07:00) Boise, Cambridge Bay, Denver, Edmonton, Inuvik, Ojinaga, Shiprock, Yellowknife'], + ['America/Chicago','(UTC -06:00) Beulah, Center, Chicago, Knox, Matamoros, Menominee, New Salem, Rainy River, Rankin Inlet, Resolute, Tell City, Winnipeg'], + ['America/Belize','(UTC -06:00) Belize, Costa Rica, El Salvador, Galapagos, Guatemala, Managua, Regina, Swift Current, Tegucigalpa'], + ['Pacific/Easter','(UTC -06:00) Easter'], + ['America/Bahia_Banderas','(UTC -06:00) Bahia Banderas, Cancun, Merida, Mexico City, Monterrey'], + ['America/Detroit','(UTC -05:00) Detroit, Grand Turk, Indianapolis, Iqaluit, Louisville, Marengo, Monticello, Montreal, Nassau, New York, Nipigon, Pangnirtung, Petersburg, Thunder Bay, Toronto, Vevay, Vincennes, Winamac'], + ['America/Atikokan','(UTC -05:00) Atikokan, Bogota, Cayman, Guayaquil, Jamaica, Lima, Panama, Port-au-Prince'], + ['America/Havana','(UTC -05:00) Havana'], + ['America/Caracas','(UTC -05:30) Caracas'], + ['America/Glace_Bay','(UTC -04:00) Bermuda, Glace Bay, Goose Bay, Halifax, Moncton, Thule'], + ['Atlantic/Stanley','(UTC -04:00) Stanley'], + ['America/Santiago','(UTC -04:00) Palmer, Santiago'], + ['America/Anguilla','(UTC -04:00) Anguilla, Antigua, Aruba, Barbados, Blanc-Sablon, Boa Vista, Curacao, Dominica, Eirunepe, Grenada, Guadeloupe, Guyana, Kralendijk, La Paz, Lower Princes, Manaus, Marigot, Martinique, Montserrat, Port of Spain, Porto Velho, Puerto Rico, Rio Branco, Santo Domingo, St Barthelemy, St Kitts, St Lucia, St Thomas, St Vincent, Tortola'], + ['America/Campo_Grande','(UTC -04:00) Campo Grande, Cuiaba'], + ['America/Asuncion','(UTC -04:00) Asuncion'], + ['America/St_Johns','(UTC -04:30) St Johns'], + ['America/Sao_Paulo','(UTC -03:00) Sao Paulo'], + ['America/Araguaina','(UTC -03:00) Araguaina, Bahia, Belem, Buenos Aires, Catamarca, Cayenne, Cordoba, Fortaleza, Jujuy, La Rioja, Maceio, Mendoza, Paramaribo, Recife, Rio Gallegos, Rothera, Salta, San Juan, Santarem, Tucuman, Ushuaia'], + ['America/Montevideo','(UTC -03:00) Montevideo'], + ['America/Godthab','(UTC -03:00) Godthab'], + ['America/Argentina/San_Luis','(UTC -03:00) San Luis'], + ['America/Miquelon','(UTC -03:00) Miquelon'], + ['America/Noronha','(UTC -02:00) Noronha, South Georgia'], + ['Atlantic/Cape_Verde','(UTC -01:00) Cape Verde'], + ['America/Scoresbysund','(UTC -01:00) Azores, Scoresbysund'], + ['Atlantic/Canary','(UTC) Canary, Dublin, Faroe, Guernsey, Isle of Man, Jersey, Lisbon, London, Madeira'], + ['Africa/Abidjan','(UTC) Abidjan, Accra, Bamako, Banjul, Bissau, Casablanca, Conakry, Dakar, Danmarkshavn, El Aaiun, Freetown, Lome, Monrovia, Nouakchott, Ouagadougou, Reykjavik, Sao Tome, St Helena'], + ['Africa/Algiers','(UTC +01:00) Algiers, Bangui, Brazzaville, Douala, Kinshasa, Lagos, Libreville, Luanda, Malabo, Ndjamena, Niamey, Porto-Novo, Tunis'], + ['Africa/Ceuta','(UTC +01:00) Amsterdam, Andorra, Belgrade, Berlin, Bratislava, Brussels, Budapest, Ceuta, Copenhagen, Gibraltar, Ljubljana, Longyearbyen, Luxembourg, Madrid, Malta, Monaco, Oslo, Paris, Podgorica, Prague, Rome, San Marino, Sarajevo, Skopje, Stockholm, Tirane, Vaduz, Vatican, Vienna, Warsaw, Zagreb, Zurich'], + ['Africa/Windhoek','(UTC +01:00) Windhoek'], + ['Asia/Damascus','(UTC +02:00) Damascus'], + ['Asia/Beirut','(UTC +02:00) Beirut'], + ['Asia/Jerusalem','(UTC +02:00) Jerusalem'], + ['Asia/Nicosia','(UTC +02:00) Athens, Bucharest, Chisinau, Helsinki, Istanbul, Mariehamn, Nicosia, Riga, Sofia, Tallinn, Vilnius'], + ['Africa/Blantyre','(UTC +02:00) Blantyre, Bujumbura, Cairo, Gaborone, Gaza, Harare, Hebron, Johannesburg, Kigali, Lubumbashi, Lusaka, Maputo, Maseru, Mbabane, Tripoli'], + ['Asia/Amman','(UTC +02:00) Amman'], + ['Africa/Addis_Ababa','(UTC +03:00) Addis Ababa, Aden, Antananarivo, Asmara, Baghdad, Bahrain, Comoro, Dar es Salaam, Djibouti, Juba, Kaliningrad, Kampala, Khartoum, Kiev, Kuwait, Mayotte, Minsk, Mogadishu, Nairobi, Qatar, Riyadh, Simferopol, Syowa, Uzhgorod, Zaporozhye'], + ['Asia/Tehran','(UTC +03:30) Tehran'], + ['Asia/Yerevan','(UTC +04:00) Yerevan'], + ['Asia/Dubai','(UTC +04:00) Dubai, Mahe, Mauritius, Moscow, Muscat, Reunion, Samara, Tbilisi, Volgograd'], + ['Asia/Baku','(UTC +04:00) Baku'], + ['Asia/Kabul','(UTC +04:30) Kabul'], + ['Antarctica/Mawson','(UTC +05:00) Aqtau, Aqtobe, Ashgabat, Dushanbe, Karachi, Kerguelen, Maldives, Mawson, Oral, Samarkand, Tashkent'], + ['Asia/Colombo','(UTC +05:30) Colombo, Kolkata'], + ['Asia/Kathmandu','(UTC +05:45) Kathmandu'], + ['Antarctica/Vostok','(UTC +06:00) Almaty, Bishkek, Chagos, Dhaka, Qyzylorda, Thimphu, Vostok, Yekaterinburg'], + ['Asia/Rangoon','(UTC +06:30) Cocos, Rangoon'], + ['Antarctica/Davis','(UTC +07:00) Bangkok, Christmas, Davis, Ho Chi Minh, Hovd, Jakarta, Novokuznetsk, Novosibirsk, Omsk, Phnom Penh, Pontianak, Vientiane'], + ['Antarctica/Casey','(UTC +08:00) Brunei, Casey, Choibalsan, Chongqing, Harbin, Hong Kong, Kashgar, Krasnoyarsk, Kuala Lumpur, Kuching, Macau, Makassar, Manila, Perth, Shanghai, Singapore, Taipei, Ulaanbaatar, Urumqi'], + ['Australia/Eucla','(UTC +08:45) Eucla'], + ['Asia/Dili','(UTC +09:00) Dili, Irkutsk, Jayapura, Palau, Pyongyang, Seoul, Tokyo'], + ['Australia/Adelaide','(UTC +09:30) Adelaide, Broken Hill'], + ['Australia/Darwin','(UTC +09:30) Darwin'], + ['Antarctica/DumontDUrville','(UTC +10:00) Brisbane, Chuuk, DumontDUrville, Guam, Lindeman, Port Moresby, Saipan, Yakutsk'], + ['Australia/Currie','(UTC +10:00) Currie, Hobart, Melbourne, Sydney'], + ['Australia/Lord_Howe','(UTC +10:30) Lord Howe'], + ['Antarctica/Macquarie','(UTC +11:00) Efate, Guadalcanal, Kosrae, Macquarie, Noumea, Pohnpei, Sakhalin, Vladivostok'], + ['Pacific/Norfolk','(UTC +11:30) Norfolk'], + ['Antarctica/McMurdo','(UTC +12:00) Auckland, McMurdo, South Pole'], + ['Asia/Anadyr','(UTC +12:00) Anadyr, Fiji, Funafuti, Kamchatka, Kwajalein, Magadan, Majuro, Nauru, Tarawa, Wake, Wallis'], + ['Pacific/Chatham','(UTC +12:45) Chatham'], + ['Pacific/Enderbury','(UTC +13:00) Enderbury, Tongatapu'], + ['Pacific/Apia','(UTC +13:00) Apia'], + ['Pacific/Kiritimati','(UTC +14:00) Kiritimati'] + ] +}); + +Zarafa.plugins.calendarimporter.data.Timezones = new Zarafa.plugins.calendarimporter.data.Timezones(); \ No newline at end of file diff --git a/js/dialogs/ImportPanel.js b/js/dialogs/ImportPanel.js index 1cc73aa..32cbfb8 100644 --- a/js/dialogs/ImportPanel.js +++ b/js/dialogs/ImportPanel.js @@ -8,6 +8,9 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, { /* store the imported timezone here... */ timezone: null, + + /* keep the parsed result here, for timezone changes... */ + parsedresult: null, /** * @constructor @@ -31,6 +34,7 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, { }, items : [ this.createSelectBox(), + this.createTimezoneBox(), this.initForm() ], buttons: [ @@ -75,7 +79,6 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, { * @private */ createGrid : function(eventdata) { - var parsedData = []; if(eventdata !== null) { var parsedData = new Array(eventdata.events.length); @@ -179,6 +182,29 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, { } }, + createTimezoneBox: function() { + return { + xtype: "selectbox", + ref: 'timezoneselector', + id: 'timezoneselector', + editable: false, + name: "choosen_timezone", + width: 100, + fieldLabel: "Select a timezone (optional)", + store: Zarafa.plugins.calendarimporter.data.Timezones.store, + labelSeperator: ":", + mode: 'local', + border: false, + anchor: "100%", + scope: this, + allowBlank: true, + listeners: { + 'select': this.onTimezoneSelected, + scope: this + } + } + }, + createUploadField: function() { return { xtype: "fileuploadfield", @@ -259,6 +285,19 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, { } }, + /** + * This is called when a timezone has been seleceted in the timezone dialog + * @param {Ext.form.ComboBox} combo + * @param {Ext.data.Record} record + * @param {Number} index + */ + onTimezoneSelected : function(combo, record, index) { + // record.data.field1 == timezone + //this.remove("eventgrid"); + this.timezone = record.data.field1; + //this.insert(this.items.length,this.createGrid(this.parsedresult)); + }, + /** * This is called when a file has been seleceted in the file dialog * in the {@link Ext.ux.form.FileUploadField} and the dialog is closed @@ -285,7 +324,13 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, { uploadField.reset(); Ext.getCmp('submitButton').enable(); Ext.getCmp('submitAllButton').enable(); - this.timezone = action.result.response.calendar["X-WR-TIMEZONE"]; + this.parsedresult = action.result.response; + + if(this.timezone == null) {; + this.timezone = action.result.response.calendar["X-WR-TIMEZONE"]; + } else { + this.timezone = this.timezoneselector.value; + } this.insert(this.items.length,this.createGrid(action.result.response)); this.doLayout(); }, diff --git a/manifest.xml b/manifest.xml index 5f01d4c..7236a1b 100644 --- a/manifest.xml +++ b/manifest.xml @@ -20,11 +20,13 @@ php/module.calendarexporter.php + js/data/timezones.js js/plugin.calendarimporter.js js/data/ResponseHandler.js js/dialogs/ImportContentPanel.js js/dialogs/ImportPanel.js + js/data/timezones.js js/plugin.calendarimporter.js js/data/ResponseHandler.js js/dialogs/ImportContentPanel.js diff --git a/php/ical/calendar.txt b/php/ical/calendar.txt index bd5f492..b6f86c2 100644 --- a/php/ical/calendar.txt +++ b/php/ical/calendar.txt @@ -7,8 +7,8 @@ X-WR-CALNAME:Testkalender X-WR-TIMEZONE:Europe/Berlin X-WR-CALDESC:Nur zum testen vom Google Kalender BEGIN:VEVENT -DTSTART:20121112T173000Z -DTEND:20121116T180000Z +DTSTART;TZID="W. Europe":20121227T100000 +DTEND;TZID="W. Europe":20121227T110000Z DTSTAMP:20110121T195741Z UID:1koigufm110c5hnq6ln57murd4@google.com CREATED:20110119T142901Z diff --git a/php/ical/class.icalparser.php b/php/ical/class.icalparser.php index fa08fd3..516317f 100644 --- a/php/ical/class.icalparser.php +++ b/php/ical/class.icalparser.php @@ -176,7 +176,7 @@ class ICal { * @return {array} array("VCALENDAR", "Begin") */ public function keyValueFromString($text) { - preg_match("/(^[^a-z:]+[;a-zA-Z=\/]*)[:]([\w\W]*)/", $text, $matches); + preg_match("/(^[^a-z:]+[;a-zA-Z=\/\"\']*)[:]([\w\W]*)/", $text, $matches); error_log("macthes: " . count($matches). " " . $text); if (count($matches) == 0) { @@ -195,7 +195,11 @@ class ICal { * * @return {int} */ - public function iCalDateToUnixTimestamp($icalDate) { + public function iCalDateToUnixTimestamp($icalDate) { + + /* timestring format */ + $utc = strpos("zZ",substr($icalDate, -1)) === false ? false : true; + $icalDate = str_replace('T', '', $icalDate); $icalDate = str_replace('Z', '', $icalDate); @@ -206,6 +210,9 @@ class ICal { $pattern .= '([0-9]{0,2})'; // 5: MM $pattern .= '([0-9]{0,2})/'; // 6: SS preg_match($pattern, $icalDate, $date); + + + // Unix timestamp can't represent dates before 1970 if ($date[1] <= 1970) { @@ -221,11 +228,14 @@ class ICal { (int)$date[1]); - $utcdate = new DateTime(); - $utcdate->setTimestamp($timestamp); - $utcdate->setTimezone(new DateTimeZone($this->default_timezone)); - $utcoffset = $utcdate->getOffset(); - + if($utc) { + $utcdate = new DateTime(); + $utcdate->setTimestamp($timestamp); + $utcdate->setTimezone(new DateTimeZone($this->default_timezone)); + $utcoffset = $utcdate->getOffset(); + } else { + $utcoffset = 0; + } return ($timestamp + $utcoffset); }