js/xpconnect/loader/ISO8601DateUtils.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 const HOURS_TO_MINUTES = 60;
michael@0 7 const MINUTES_TO_SECONDS = 60;
michael@0 8 const SECONDS_TO_MILLISECONDS = 1000;
michael@0 9 const MINUTES_TO_MILLISECONDS = MINUTES_TO_SECONDS * SECONDS_TO_MILLISECONDS;
michael@0 10 const HOURS_TO_MILLISECONDS = HOURS_TO_MINUTES * MINUTES_TO_MILLISECONDS;
michael@0 11
michael@0 12 this.EXPORTED_SYMBOLS = ["ISO8601DateUtils"];
michael@0 13
michael@0 14 debug("*** loading ISO8601DateUtils\n");
michael@0 15
michael@0 16 this.ISO8601DateUtils = {
michael@0 17
michael@0 18 /**
michael@0 19 * XXX Thunderbird's W3C-DTF function
michael@0 20 *
michael@0 21 * Converts a W3C-DTF (subset of ISO 8601) date string to a Javascript
michael@0 22 * date object. W3C-DTF is described in this note:
michael@0 23 * http://www.w3.org/TR/NOTE-datetime IETF is obtained via the Date
michael@0 24 * object's toUTCString() method. The object's toString() method is
michael@0 25 * insufficient because it spells out timezones on Win32
michael@0 26 * (f.e. "Pacific Standard Time" instead of "PST"), which Mail doesn't
michael@0 27 * grok. For info, see
michael@0 28 * http://lxr.mozilla.org/mozilla/source/js/src/jsdate.c#1526.
michael@0 29 */
michael@0 30 parse: function ISO8601_parse(aDateString) {
michael@0 31 var dateString = aDateString;
michael@0 32 if (!dateString.match('-')) {
michael@0 33 // Workaround for server sending
michael@0 34 // dates such as: 20030530T11:18:50-08:00
michael@0 35 // instead of: 2003-05-30T11:18:50-08:00
michael@0 36 var year = dateString.slice(0, 4);
michael@0 37 var month = dateString.slice(4, 6);
michael@0 38 var rest = dateString.slice(6, dateString.length);
michael@0 39 dateString = year + "-" + month + "-" + rest;
michael@0 40 }
michael@0 41
michael@0 42 var parts = dateString.match(/(\d{4})(-(\d{2,3}))?(-(\d{2}))?(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|([+-])(\d{2}):(\d{2}))?)?/);
michael@0 43
michael@0 44 // Here's an example of a W3C-DTF date string and what .match returns for it.
michael@0 45 //
michael@0 46 // date: 2003-05-30T11:18:50.345-08:00
michael@0 47 // date.match returns array values:
michael@0 48 //
michael@0 49 // 0: 2003-05-30T11:18:50-08:00,
michael@0 50 // 1: 2003,
michael@0 51 // 2: -05,
michael@0 52 // 3: 05,
michael@0 53 // 4: -30,
michael@0 54 // 5: 30,
michael@0 55 // 6: T11:18:50-08:00,
michael@0 56 // 7: 11,
michael@0 57 // 8: 18,
michael@0 58 // 9: :50,
michael@0 59 // 10: 50,
michael@0 60 // 11: .345,
michael@0 61 // 12: 345,
michael@0 62 // 13: -08:00,
michael@0 63 // 14: -,
michael@0 64 // 15: 08,
michael@0 65 // 16: 00
michael@0 66
michael@0 67 // Create a Date object from the date parts. Note that the Date
michael@0 68 // object apparently can't deal with empty string parameters in lieu
michael@0 69 // of numbers, so optional values (like hours, minutes, seconds, and
michael@0 70 // milliseconds) must be forced to be numbers.
michael@0 71 var date = new Date(parts[1], parts[3] - 1, parts[5], parts[7] || 0,
michael@0 72 parts[8] || 0, parts[10] || 0, parts[12] || 0);
michael@0 73
michael@0 74 // We now have a value that the Date object thinks is in the local
michael@0 75 // timezone but which actually represents the date/time in the
michael@0 76 // remote timezone (f.e. the value was "10:00 EST", and we have
michael@0 77 // converted it to "10:00 PST" instead of "07:00 PST"). We need to
michael@0 78 // correct that. To do so, we're going to add the offset between
michael@0 79 // the remote timezone and UTC (to convert the value to UTC), then
michael@0 80 // add the offset between UTC and the local timezone //(to convert
michael@0 81 // the value to the local timezone).
michael@0 82
michael@0 83 // Ironically, W3C-DTF gives us the offset between UTC and the
michael@0 84 // remote timezone rather than the other way around, while the
michael@0 85 // getTimezoneOffset() method of a Date object gives us the offset
michael@0 86 // between the local timezone and UTC rather than the other way
michael@0 87 // around. Both of these are the additive inverse (i.e. -x for x)
michael@0 88 // of what we want, so we have to invert them to use them by
michael@0 89 // multipying by -1 (f.e. if "the offset between UTC and the remote
michael@0 90 // timezone" is -5 hours, then "the offset between the remote
michael@0 91 // timezone and UTC" is -5*-1 = 5 hours).
michael@0 92
michael@0 93 // Note that if the timezone portion of the date/time string is
michael@0 94 // absent (which violates W3C-DTF, although ISO 8601 allows it), we
michael@0 95 // assume the value to be in UTC.
michael@0 96
michael@0 97 // The offset between the remote timezone and UTC in milliseconds.
michael@0 98 var remoteToUTCOffset = 0;
michael@0 99 if (parts[13] && parts[13] != "Z") {
michael@0 100 var direction = (parts[14] == "+" ? 1 : -1);
michael@0 101 if (parts[15])
michael@0 102 remoteToUTCOffset += direction * parts[15] * HOURS_TO_MILLISECONDS;
michael@0 103 if (parts[16])
michael@0 104 remoteToUTCOffset += direction * parts[16] * MINUTES_TO_MILLISECONDS;
michael@0 105 }
michael@0 106 remoteToUTCOffset = remoteToUTCOffset * -1; // invert it
michael@0 107
michael@0 108 // The offset between UTC and the local timezone in milliseconds.
michael@0 109 var UTCToLocalOffset = date.getTimezoneOffset() * MINUTES_TO_MILLISECONDS;
michael@0 110 UTCToLocalOffset = UTCToLocalOffset * -1; // invert it
michael@0 111 date.setTime(date.getTime() + remoteToUTCOffset + UTCToLocalOffset);
michael@0 112
michael@0 113 return date;
michael@0 114 },
michael@0 115
michael@0 116 create: function ISO8601_create(aDate) {
michael@0 117 function zeropad (s, l) {
michael@0 118 s = s.toString(); // force it to a string
michael@0 119 while (s.length < l) {
michael@0 120 s = '0' + s;
michael@0 121 }
michael@0 122 return s;
michael@0 123 }
michael@0 124
michael@0 125 var myDate;
michael@0 126 // if d is a number, turn it into a date
michael@0 127 if (typeof aDate == 'number') {
michael@0 128 myDate = new Date()
michael@0 129 myDate.setTime(aDate);
michael@0 130 } else {
michael@0 131 myDate = aDate;
michael@0 132 }
michael@0 133
michael@0 134 // YYYY-MM-DDThh:mm:ssZ
michael@0 135 var result = zeropad(myDate.getUTCFullYear (), 4) +
michael@0 136 zeropad(myDate.getUTCMonth () + 1, 2) +
michael@0 137 zeropad(myDate.getUTCDate (), 2) + 'T' +
michael@0 138 zeropad(myDate.getUTCHours (), 2) + ':' +
michael@0 139 zeropad(myDate.getUTCMinutes (), 2) + ':' +
michael@0 140 zeropad(myDate.getUTCSeconds (), 2) + 'Z';
michael@0 141
michael@0 142 return result;
michael@0 143 }
michael@0 144 }

mercurial