b=294104, remove isUtc to explicit 'UTC' timezone, and change null timezone -> 'floating', r=shaver+pav

This commit is contained in:
vladimir%pobox.com 2005-05-19 21:14:24 +00:00
parent 7d2d3e065c
commit 41d1a31363
8 changed files with 224 additions and 156 deletions

View File

@ -265,7 +265,7 @@
<field name="mEventMap">null</field>
<field name="mCalendarView">null</field>
<field name="mDate">null</field>
<field name="mTimezone">null</field>
<field name="mTimezone">"UTC"</field>
<field name="mDragState">null</field>
<!-- properties -->
@ -481,10 +481,10 @@
var stdate = aOccurrence.occurrenceStartDate;
var enddate = aOccurrence.occurrenceEndDate;
if (stdate.isUtc || stdate.timezone != this.mTimezone)
if (stdate.timezone != this.mTimezone)
stdate = stdate.getInTimezone (this.mTimezone);
if (enddate.isUtc || enddate.timezone != this.mTimezone)
if (enddate.timezone != this.mTimezone)
enddate = enddate.getInTimezone (this.mTimezone);
return { start: stdate.hour * 60 + stdate.minute,
@ -1493,8 +1493,8 @@
<body><![CDATA[
var targetDate = aDate.clone();
targetDate.isDate = true;
if (!targetDate.isUtc)
targetDate = targetDate.getInTimezone(null);
if (targetDate.timezone != "UTC")
targetDate = targetDate.getInTimezone("UTC");
if (this.mStartDate && this.mEndDate) {
if (this.mStartDate.compare(targetDate) <= 0 &&
@ -1819,8 +1819,8 @@
d.isDate = true;
if (!d.isUtc)
d = d.getInTimezone(null);
if (d.timezone != "UTC")
d = d.getInTimezone("UTC");
this.mDateColumns.push ( { date: d, column: dayEventsBox, header: dayHeaderBox } );
}
@ -1838,8 +1838,8 @@
var eday = estart.clone();
eday.isDate = true;
if (!eday.isUtc)
eday = eday.getInTimezone(null);
if (eday.timezone != "UTC")
eday = eday.getInTimezone("UTC");
var column = null;
var header = null;

View File

@ -43,97 +43,165 @@
[scriptable, uuid(5678d4a3-2543-4ece-afbb-079292f2866e)]
interface calIDateTime : nsISupports
{
// returns true if this thing is able to be modified;
// if the item is not mutable, attempts to modify
// any data will throw CAL_ERROR_ITEM_IS_IMMUTABLE
/**
* isMutable is true if this instance is modifiable.
* If isMutable is false, any attempts to modify
* the object will throw CAL_ERROR_ITEM_IS_MUTABLE.
*/
readonly attribute boolean isMutable;
// makes this item immutable
/**
* Make this calIDateTime instance immutable.
*/
void makeImmutable();
// clone always returns a mutable event
/**
* Clone this calIDateTime instance into a new
* mutable object.
*/
calIDateTime clone();
/**
* valid is true if this object contains a valid
* time/date.
*/
// true if this thing is set/valid
readonly attribute boolean isValid;
// this thing's base PRTime value, either as UTC or as timezoneless-
// local. Setting this will explode the PRTime value to year/etc
// based on the current value of timezone. PRTime is milliseconds
// since the epoch, in UTC.
/**
* nativeTime contains this instance's PRTime value relative
* to the UTC epoch, regardless of the timezone that's set
* on this instance. If nativeTime is set, the given UTC PRTime
* value is exploded into year/month/etc, taking into account
* the timezone setting.
*/
attribute PRTime nativeTime;
//
// Year, fully exploded (e.g. "1989", "2004")
/**
* Full 4-digit year value (e.g. "1989", "2004")
*/
attribute short year;
// Month, 0-11
/**
* Month, 0-11, 0 = January
*/
attribute short month;
// Day, 1-[28,29,31]
/**
* Day of month, 1-[28,29,31]
*/
attribute short day;
// Hour, 0-23
/**
* Hour, 0-23
*/
attribute short hour;
// Minute, 0-59
/**
* Minute, 0-59
*/
attribute short minute;
// Second, 0-59
/**
* Second, 0-59
*/
attribute short second;
// isUtc and tiemzone together specify the timezone of this file;
// - if isUtc is true, timezone is ignored and this datetime is UTC.
// - if isUtc is false and timezone is not null, then this datetime
// is in the given timezone
// - if isUtc is false and timezone is null, then this datetime
// represents a floating time; the actual nativeTime representation
// will still be as if it was in UTC
attribute PRBool isUtc;
/**
* Gets or sets the timezone of this calIDateTime instance.
* Setting the timezone does not change the actual date/time components;
* to convert between timezones, use getInTimezone().
*
* Valid values are:
*
* - "UTC" (or "utc", "UTC" preferred)
* - the object refers to a time in UTC.
* - a TZID string, understood by the ICS Service
* - the object refers to a time in that tz
* - "floating"
* - the object is in floating time and does not have an
* associated timezone.
*
* @throws NS_ERROR_INVALID_ARG if an invalid timezone is passed in.
*/
attribute AUTF8String timezone;
// if true, this calIDateTime represents a date (whole day), not a
// specific hour/minute/second
/**
* isDate indicates that this calIDateTime instance represents a date
* (a whole day), and not a specific time on that day. If isDate is set,
* accessing the hour/minute/second fields will return 0, and and setting
* them is an illegal operation.
*/
attribute PRBool isDate;
//
// computed values
//
/*
* computed values
*/
// Day of the week, 0-6, Sunday = 0
/**
* Day of the week. 0-6, with Sunday = 0.
*/
readonly attribute short weekday;
// Day of the year, 0-365/366
/**
* Day of the year, 0-365/366.
*/
readonly attribute short yearday;
//
// Methods
//
/*
* Methods
*/
// reset to an invalid state
/**
* Reset this instance to an invalid state.
*/
void reset();
// return a string representation of this date/time
// in the current locale
/**
* Return a string representation of this instance.
*/
AUTF8String toString();
// normalize and validate the expanded-out values
// XXX going away soon
void normalize();
// sets this thing to a time in the given timezone
void setTimeInTimezone (in PRTime aTime, in string aTimezone);
/**
* Set the value of this calIDateTime instance
* to aTime milliseconds since the epoch in the
* given timezone. Valid values for the aTimezone
* are either a known TZID or "UTC"; null/empty string
* is not valid.
*/
void setTimeInTimezone (in PRTime aTime, in AUTF8String aTimezone);
// gets a new calIDateTime object representing this
// item in the given timezone
calIDateTime getInTimezone (in string aTimezone);
/**
* Return a new calIDateTime instance that's the result of
* converting this one into the given timezone. Valid values
* for aTimezone are the same as the timezone field. If
* the "floating" timezone is given, then this object
* is just cloned, and the timezone is set to floating.
*/
calIDateTime getInTimezone (in AUTF8String aTimezone);
// add the given calIDateTime, treating it as a duration, to
// this item
// this item.
// XXX will change
void addDuration (in calIDateTime aDuration);
// returns -1, 0, 1 to indicate this < aOtherDate,
// this == aOtherDate, or this > aOtherDate.
long compare (in calIDateTime aOtherDate);
/**
* Compare this calIDateTime instance to aOther. Returns -1, 0, 1 to
* indicate if this < aOther, this == aOther, or this > aOther,
* respectively.
*
* This comparison is timezone-aware; the given values are converted
* to a common timezone before comparing. If either this or aOther is
* floating, both objects are treated as floating for the comparison.
*
* If either this or aOther has isDate set, then only the date portion is
* compared.
*/
long compare (in calIDateTime aOther);
//
// Some helper getters for calculating useful ranges

View File

@ -176,7 +176,7 @@ calAlarmService.prototype = {
/* calIAlarmService APIs */
snoozeEvent: function(event, duration) {
/* modify the event for a new alarm time */
var alarmTime = jsDateToDateTime((new Date())).getInTimezone(null);
var alarmTime = jsDateToDateTime((new Date())).getInTimezone("UTC");
alarmTime.addDuration(duration);
newEvent = event.clone();
newEvent.alarmTime = alarmTime;
@ -291,9 +291,9 @@ calAlarmService.prototype = {
addAlarm: function(aItem, skipCheck, alarmTime) {
// if aItem.alarmTime >= 'now' && aItem.alarmTime <= gAlarmEndTime
if (!alarmTime)
alarmTime = aItem.alarmTime.getInTimezone(null);
alarmTime = aItem.alarmTime.getInTimezone("UTC");
var now = jsDateToDateTime((new Date())).getInTimezone(null);
var now = jsDateToDateTime((new Date())).getInTimezone("UTC");
var callbackObj = {
alarmService: this,
@ -343,12 +343,12 @@ calAlarmService.prototype = {
// figure out the 'now' and 6 hours from now and look for events
// between then with alarms
this.mRangeStart = jsDateToDateTime((new Date())).getInTimezone(null);
this.mRangeStart = jsDateToDateTime((new Date())).getInTimezone("UTC");
var until = this.mRangeStart.clone();
until.hour += kHoursBetweenUpdates;
until.normalize();
this.mRangeEnd = until.getInTimezone(null);
this.mRangeEnd = until.getInTimezone("UTC");
var calendarManager = Components.classes["@mozilla.org/calendar/manager;1"].getService(Components.interfaces.calICalendarManager);
var calendars = calendarManager.getCalendars({});

View File

@ -81,7 +81,6 @@ calDateTime::calDateTime(const calDateTime& cdt)
mHour = cdt.mHour;
mMinute = cdt.mMinute;
mSecond = cdt.mSecond;
mIsUtc = cdt.mIsUtc;
mWeekday = cdt.mWeekday;
mYearday = cdt.mYearday;
@ -138,11 +137,12 @@ calDateTime::Reset()
mHour = 0;
mMinute = 0;
mSecond = 0;
mIsUtc = PR_FALSE;
mWeekday = 0;
mYearday = 0;
mIsDate = PR_FALSE;
mTimezone.AssignLiteral("UTC");
mIsValid = PR_FALSE;
return NS_OK;
}
@ -154,7 +154,6 @@ CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Day)
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Hour)
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Minute)
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Second)
CAL_VALUETYPE_ATTR(calDateTime, PRBool, IsUtc)
CAL_VALUETYPE_ATTR(calDateTime, PRBool, IsDate)
CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRInt16, Weekday)
@ -165,14 +164,17 @@ CAL_STRINGTYPE_ATTR_GETTER(calDateTime, nsACString, Timezone)
NS_IMETHODIMP
calDateTime::SetTimezone(const nsACString& aTimezone)
{
mTimezone.Assign(aTimezone);
if (aTimezone.EqualsLiteral("UTC") ||
aTimezone.EqualsLiteral("utc"))
{
mTimezone.Truncate();
mIsUtc = PR_TRUE;
} else if (!aTimezone.IsEmpty()) {
mIsUtc = PR_FALSE;
if (aTimezone.EqualsLiteral("UTC") || aTimezone.EqualsLiteral("utc")) {
mTimezone.AssignLiteral("UTC");
} else if (aTimezone.EqualsLiteral("floating")) {
mTimezone.AssignLiteral("floating");
} else {
icaltimezone *tz = nsnull;
nsresult rv = GetIcalTZ(aTimezone, &tz);
if (NS_FAILED(rv))
return rv;
mTimezone.Assign(aTimezone);
}
return NS_OK;
@ -188,7 +190,7 @@ calDateTime::GetNativeTime(PRTime *aResult)
NS_IMETHODIMP
calDateTime::SetNativeTime(PRTime aNativeTime)
{
return SetTimeInTimezone (aNativeTime, NULL);
return SetTimeInTimezone (aNativeTime, NS_LITERAL_CSTRING("UTC"));
}
NS_IMETHODIMP
@ -197,9 +199,7 @@ calDateTime::Normalize()
struct icaltimetype icalt;
ToIcalTime(&icalt);
icalt = icaltime_normalize(icalt);
FromIcalTime(&icalt);
mIsValid = PR_TRUE;
@ -219,7 +219,7 @@ calDateTime::AddDuration(calIDateTime *aDuration)
mLastModified = PR_Now();
return SetNativeTime(mNativeTime + nativeDur);
return SetTimeInTimezone(mNativeTime + nativeDur, mTimezone);
}
NS_IMETHODIMP
@ -229,29 +229,22 @@ calDateTime::ToString(nsACString& aResult)
"%04d/%02d/%02d %02d:%02d:%02d%s%s",
mYear, mMonth + 1, mDay,
mHour, mMinute, mSecond,
((mTimezone.IsEmpty()) ? "" : " "),
((mTimezone.IsEmpty()) ? "" : mTimezone.get())));
mTimezone.get()));
return NS_OK;
}
NS_IMETHODIMP
calDateTime::SetTimeInTimezone(PRTime aTime, const char *aTimezone)
calDateTime::SetTimeInTimezone(PRTime aTime, const nsACString& aTimezone)
{
struct icaltimetype icalt;
time_t tt;
icaltimezone *tz = nsnull;
icaltimezone *zone = icaltimezone_get_utc_timezone();
if (aTimezone.IsEmpty())
return NS_ERROR_INVALID_ARG;
if (aTimezone && strcmp(aTimezone, "UTC") != 0 && strcmp(aTimezone, "utc") != 0) {
nsCOMPtr<calIICSService> ics = do_GetService(kCalICSService);
nsCOMPtr<calIIcalComponent> tz;
ics->GetTimezone(nsDependentCString(aTimezone), getter_AddRefs(tz));
if (!tz)
return NS_ERROR_FAILURE;
icalcomponent *zonecomp = tz->GetIcalComponent();
zone = icalcomponent_get_timezone(zonecomp, aTimezone);
}
nsresult rv = GetIcalTZ(aTimezone, &tz);
NS_ENSURE_SUCCESS(rv, rv);
PRInt64 temp, million;
LL_I2L(million, PR_USEC_PER_SEC);
@ -260,11 +253,7 @@ calDateTime::SetTimeInTimezone(PRTime aTime, const char *aTimezone)
LL_L2I(sectime, temp);
tt = sectime;
if (zone) {
icalt = icaltime_from_timet_with_zone(tt, 0, zone);
} else {
icalt = icaltime_from_timet(tt, 0);
}
icalt = icaltime_from_timet_with_zone(tt, 0, tz);
FromIcalTime(&icalt);
mIsValid = PR_TRUE;
@ -273,7 +262,7 @@ calDateTime::SetTimeInTimezone(PRTime aTime, const char *aTimezone)
}
NS_IMETHODIMP
calDateTime::GetInTimezone(const char *aTimezone, calIDateTime **aResult)
calDateTime::GetInTimezone(const nsACString& aTimezone, calIDateTime **aResult)
{
calDateTime *cdt = nsnull;
@ -281,42 +270,25 @@ calDateTime::GetInTimezone(const char *aTimezone, calIDateTime **aResult)
// if it's a date, we really just want to make a copy of this
// and set the timezone.
cdt = new calDateTime(*this);
if (aTimezone) {
cdt->mTimezone.Assign(aTimezone);
cdt->mIsUtc = PR_FALSE;
} else {
cdt->mTimezone.Truncate();
cdt->mIsUtc = PR_TRUE;
}
cdt->mTimezone.Assign(aTimezone);
} else {
struct icaltimetype icalt;
icaltimezone *destzone;
icaltimezone *tz = nsnull;
ToIcalTime(&icalt);
if (!aTimezone || strcmp(aTimezone, "UTC") == 0 || strcmp(aTimezone, "utc") == 0) {
destzone = icaltimezone_get_utc_timezone();
} else {
nsCOMPtr<calIICSService> ics = do_GetService(kCalICSService);
nsCOMPtr<calIIcalComponent> tz;
ics->GetTimezone(nsDependentCString(aTimezone), getter_AddRefs(tz));
if (!tz)
return NS_ERROR_FAILURE;
icalcomponent *zonecomp = tz->GetIcalComponent();
destzone = icalcomponent_get_timezone(zonecomp, aTimezone);
}
nsresult rv = GetIcalTZ(aTimezone, &tz);
if (NS_FAILED(rv))
return rv;
/* If there's a zone, we need to convert; otherwise, we just
* assign, since this item is floating */
if (icalt.zone) {
icaltimezone_convert_time(&icalt, (icaltimezone*) icalt.zone, destzone);
icalt.zone = destzone;
} else {
icalt.zone = destzone;
if (icalt.zone && tz) {
icaltimezone_convert_time(&icalt, (icaltimezone*) icalt.zone, tz);
}
icalt.zone = tz;
cdt = new calDateTime(&icalt);
}
@ -448,26 +420,24 @@ calDateTime::ToIcalTime(icaltimetype *icalt)
icalt->minute = mMinute;
icalt->second = mSecond;
icalt->is_utc = mIsUtc ? 1 : 0;
icalt->is_date = mIsDate ? 1 : 0;
icalt->is_daylight = 0;
if (icalt->is_utc) {
icalt->zone = icaltimezone_get_utc_timezone();
} else if (mTimezone.IsEmpty()) {
icalt->zone = nsnull;
} else {
nsCOMPtr<calIICSService> ics = do_GetService(kCalICSService);
nsCOMPtr<calIIcalComponent> tz;
ics->GetTimezone(mTimezone, getter_AddRefs(tz));
if (tz) {
icalcomponent *zonecomp = tz->GetIcalComponent();
icalt->zone = icalcomponent_get_timezone(zonecomp, mTimezone.get());
} else {
NS_WARNING("Specified timezone not found; generating floating time!");
icalt->zone = nsnull;
}
icaltimezone* tz = nsnull;
nsresult rv = GetIcalTZ(mTimezone, &tz);
// this will always succeed, because
// mTimezone can't be set without GetIcalTZ
// succeeding.
if (NS_FAILED(rv)) {
NS_ERROR("calDateTime::ToIcalTime: GetIcalTZ failed!");
}
icalt->zone = tz;
if (icalt->zone == icaltimezone_get_utc_timezone())
icalt->is_utc = 1;
else
icalt->is_utc = 0;
}
void
@ -482,10 +452,14 @@ calDateTime::FromIcalTime(icaltimetype *icalt)
mMinute = t.minute;
mSecond = t.second;
mIsUtc = (t.zone == icaltimezone_get_utc_timezone());
mIsDate = t.is_date ? PR_TRUE : PR_FALSE;
mTimezone.Assign(icaltimezone_get_tzid((icaltimezone*)t.zone));
if (t.is_utc || t.zone == icaltimezone_get_utc_timezone())
mTimezone.AssignLiteral("UTC");
else if (t.zone)
mTimezone.Assign(icaltimezone_get_tzid((icaltimezone*)t.zone));
else
mTimezone.AssignLiteral("floating");
// reconstruct nativetime
time_t tt = icaltime_as_timet_with_zone(*icalt, icaltimezone_get_utc_timezone());
@ -518,6 +492,38 @@ calDateTime::Compare(calIDateTime *aOther, PRInt32 *aResult)
return NS_OK;
}
nsresult
calDateTime::GetIcalTZ(const nsACString& tzid, struct _icaltimezone **tzp)
{
if (tzid.IsEmpty()) {
return NS_ERROR_INVALID_ARG;
}
if (tzid.EqualsLiteral("floating")) {
*tzp = nsnull;
return NS_OK;
}
if (tzid.EqualsLiteral("UTC") || tzid.EqualsLiteral("utc")) {
*tzp = icaltimezone_get_utc_timezone();
return NS_OK;
}
nsCOMPtr<calIICSService> ics = do_GetService(kCalICSService);
nsCOMPtr<calIIcalComponent> tz;
nsresult rv = ics->GetTimezone(tzid, getter_AddRefs(tz));
if (NS_FAILED(rv) || !tz)
return NS_ERROR_INVALID_ARG;
if (tzp) {
icalcomponent *zonecomp = tz->GetIcalComponent();
*tzp = icalcomponent_get_timezone(zonecomp, nsPromiseFlatCString(tzid).get());
}
return NS_OK;
}
/*
* nsIXPCScriptable impl
*/
@ -595,8 +601,6 @@ calDateTime::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
nsresult rv = SetNativeTime(utcTime);
if (NS_SUCCEEDED(rv)) {
mIsUtc = PR_TRUE;
mTimezone.Truncate();
mIsValid = PR_TRUE;
} else {
mIsValid = PR_FALSE;

View File

@ -79,7 +79,6 @@ protected:
PRInt16 mMinute;
PRInt16 mSecond;
PRBool mIsUtc;
PRBool mIsDate;
nsCString mTimezone;
@ -87,7 +86,7 @@ protected:
PRInt16 mYearday;
void FromIcalTime(icaltimetype *icalt);
struct _icaltimezone* GetIcalTZ(const nsACString& tzid);
nsresult GetIcalTZ(const nsACString& tzid, struct _icaltimezone **tzp);
PRTime mLastModified;
};

View File

@ -141,7 +141,7 @@ function textToDate(d) {
date = newDateTime(dval, "UTC");
} else if (d[0] == 'L') {
// is local time
date = newDateTime(dval, null);
date = newDateTime(dval, "floating");
}
if (d[1] == 'D')
date.isDate = true;
@ -150,7 +150,7 @@ function textToDate(d) {
function dateToText(d) {
var datestr;
if (d.isUtc) {
if (d.timezone != "floating") {
datestr = "U";
} else {
datestr = "L";
@ -173,11 +173,10 @@ function dateToText(d) {
function newDateTime(aNativeTime, aTimezone) {
var t = new CalDateTime();
t.nativeTime = aNativeTime;
if (aTimezone && aTimezone != "UTC") {
if (aTimezone != "floating") {
t = t.getInTimezone(aTimezone);
} else if (!aTimezone) {
t.isUtc = false;
t.timezone = null;
} else {
t.timezone = "floating";
}
return t;
@ -1225,10 +1224,7 @@ calStorageCalendar.prototype = {
function setDateParamHelper(params, entryname, cdt) {
params[entryname] = cdt.nativeTime;
if (cdt.isUtc)
params[entryname + "_tz"] = "UTC";
else
params[entryname + "_tz"] = cdt.timezone;
params[entryname + "_tz"] = cdt.timezone;
}
// build flags up as we go

View File

@ -191,6 +191,7 @@ function guessSystemTimezone()
try {
return tzTable[offset + " " + timezone];
} catch(ex) {
return null;
// XXX we don't really have a better option here
return "floating";
}
}

View File

@ -1126,8 +1126,8 @@ function eventArrayToICalString( calendarEventArray, doPatchForExport )
if(calendarEvent.isAllDay != true) {
var startDate = calendarEvent.startDate;
var endDate = calendarEvent.endDate;
calendarEvent.startDate = startDate.getInTimezone(null);
calendarEvent.endDate = endDate.getInTimezone(null);
calendarEvent.startDate = startDate.getInTimezone("UTC");
calendarEvent.endDate = endDate.getInTimezone("UTC");
}
// check if all required properties are available
/*