set emacs indentation level
[lightning-exchange-provider:ianmartins-lightning-exchange-provider.git] / js / compat2.js
1 /* -*- espresso-indent-level: 8; -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  * http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  *
15  * The Original Code is Google Calendar Provider code.
16  *
17  * The Initial Developer of the Original Code is
18  *   Philipp Kewisch <mozilla@kewis.ch>
19  * Portions created by the Initial Developer are Copyright (C) 2007
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  *   Joey Minta <jminta@gmail.com>
24  *   Axel Zechner <axel.zechner@googlemail.com> - category support
25  *
26  * Alternatively, the contents of this file may be used under the terms of
27  * either the GNU General Public License Version 2 or later (the "GPL"), or
28  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29  * in which case the provisions of the GPL or the LGPL are applicable instead
30  * of those above. If you wish to allow use of your version of this file only
31  * under the terms of either the GPL or the LGPL, and not to allow others to
32  * use your version of this file under the terms of the MPL, indicate your
33  * decision by deleting the provisions above and replace them with the notice
34  * and other provisions required by the GPL or the LGPL. If you do not delete
35  * the provisions above, a recipient may use your version of this file under
36  * the terms of any one of the MPL, the GPL or the LGPL.
37  *
38  * ***** END LICENSE BLOCK ***** */
39
40 // this is needed only for thunderbird 2
41
42 /**
43  * fromRFC3339
44  * Convert a RFC3339 compliant Date string to a calIDateTime.
45  *  
46  * @param aStr          The RFC3339 compliant Date String
47  * @param aTimezone     The timezone this date string is most likely in
48  * @return              A calIDateTime object
49  */ 
50 function fromRFC3339(aStr, aTimezone) {
51     
52     // XXX I have not covered leapseconds (matches[8]), this might need to
53     // be done. The only reference to leap seconds I found is bug 227329.
54     //
55     
56     // Create a DateTime instance (calUtils.js)
57     var dateTime = createDateTime();
58     
59     // Killer regex to parse RFC3339 dates
60     var re = new RegExp("^([0-9]{4})-([0-9]{2})-([0-9]{2})" +
61         "([Tt]([0-9]{2}):([0-9]{2}):([0-9]{2})(\.[0-9]+)?)?" +
62         "(([Zz]|([+-])([0-9]{2}):([0-9]{2})))?");
63     
64     var matches = re.exec(aStr);
65             
66     if (!matches) {
67         return null;
68     }       
69         
70     // Set usual date components
71     dateTime.isDate = (matches[4]==null);
72         
73     dateTime.year = matches[1];
74     dateTime.month = matches[2] - 1; // Jan is 0
75     dateTime.day = matches[3];
76
77     if (!dateTime.isDate) {
78         dateTime.hour = matches[5];
79         dateTime.minute = matches[6];
80         dateTime.second = matches[7];
81     }
82     
83     // Timezone handling
84     if (matches[9] == "Z") {
85         // If the dates timezone is "Z", then this is UTC, no matter
86         // what timezone was passed
87         dateTime.timezone = UTC();
88
89     } else if (matches[9] == null) {
90         // We have no timezone info, only a date. We have no way to
91         // know what timezone we are in, so lets assume we are in the
92         // timezone of our local calendar, or whatever was passed.
93
94         dateTime.timezone = aTimezone;
95
96     } else {
97         var offset_in_s = (matches[11] == "-" ? -1 : 1) *
98             ( (matches[12] * 3600) + (matches[13] * 60) );
99
100         // try local timezone first
101         dateTime.timezone = aTimezone;
102
103         // If offset does not match, go through timezones. This will
104         // give you the first tz in the alphabet and kill daylight
105         // savings time, but we have no other choice
106         if (dateTime.timezoneOffset != offset_in_s) {
107             // TODO A patch to Bug 363191 should make this more efficient.
108                         
109                         var tzService = getTimezoneService();
110             // Enumerate timezones, set them, check their offset
111             var enumerator = tzService.timezoneIds;
112             while (enumerator.hasMore()) {
113                 var id = enumerator.getNext();
114                 dateTime.timezone = tzService.getTimezone(id);
115                 if (dateTime.timezoneOffset == offset_in_s) {
116                     // This is our last step, so go ahead and return
117                     return dateTime;
118                 }
119             }
120             // We are still here: no timezone was found
121             dateTime.timezone = UTC();
122             if (!dateTime.isDate) {
123                 dateTime.hour += (matches[11] == "-" ? -1 : 1) * matches[12];
124                 dateTime.minute += (matches[11] == "-" ? -1 : 1) * matches[13];
125              }
126         }
127     }
128     return dateTime;
129 }
130
131 /**
132  * toRFC3339
133  * Convert a calIDateTime to a RFC3339 compliant Date string
134  *
135  * @param aDateTime     The calIDateTime object
136  * @return              The RFC3339 compliant date string
137  */
138 function toRFC3339(aDateTime) {
139
140     if (!aDateTime) {
141         return "";
142     }
143     
144     var full_tzoffset = aDateTime.timezoneOffset;
145     var tzoffset_hr = Math.floor(Math.abs(full_tzoffset) / 3600);
146
147     var tzoffset_mn = ((Math.abs(full_tzoffset) / 3600).toFixed(2) -
148                        tzoffset_hr) * 60;
149
150     var str = aDateTime.year + "-" +
151         ("00" + (aDateTime.month + 1)).substr(-2) +  "-" +
152         ("00" + aDateTime.day).substr(-2);
153
154     // Time and Timezone extension
155     if (!aDateTime.isDate) {
156         str += "T" +
157                ("00" + aDateTime.hour).substr(-2) + ":" +
158                ("00" + aDateTime.minute).substr(-2) + ":" +
159                ("00" + aDateTime.second).substr(-2);
160         if (aDateTime.timezoneOffset != 0) {
161             str += (full_tzoffset < 0 ? "-" : "+") +
162                    ("00" + tzoffset_hr).substr(-2) + ":" +
163                    ("00" + tzoffset_mn).substr(-2);
164         } else if (aDateTime.timezone.isFloating) {
165             // RFC3339 Section 4.3 Unknown Local Offset Convention
166             str += "-00:00";
167         } else {
168             // ZULU Time, according to ISO8601's timezone-offset
169             str += "Z";
170         }
171     }
172     return str;
173 }