First shot at implementing timezones, bug 165963: [RFE] Specify timezone for start and end dates
git-svn-id: svn://10.0.0.236/trunk@138876 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
ee97617e6b
commit
82e74ecb31
@ -45,6 +45,7 @@
|
||||
|
||||
icaltimetype ConvertFromPrtime( PRTime indate );
|
||||
PRTime ConvertToPrtime ( icaltimetype indate );
|
||||
icaltimezone *currenttimezone = nsnull;
|
||||
|
||||
/* Implementation file */
|
||||
NS_IMPL_ISUPPORTS1(oeDateTimeImpl, oeIDateTime)
|
||||
@ -68,11 +69,13 @@ oeDateTimeImpl::oeDateTimeImpl()
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
m_datetime = icaltime_null_time();
|
||||
m_tzid = nsnull;
|
||||
}
|
||||
|
||||
oeDateTimeImpl::~oeDateTimeImpl()
|
||||
{
|
||||
/* destructor code */
|
||||
if( m_tzid )
|
||||
nsMemory::Free( m_tzid );
|
||||
}
|
||||
|
||||
/* attribute short year; */
|
||||
@ -163,6 +166,35 @@ NS_IMETHODIMP oeDateTimeImpl::SetTime( PRTime ms )
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP oeDateTimeImpl::SetTimeInTimezone( PRTime ms, const char *tzid )
|
||||
{
|
||||
#ifdef ICAL_DEBUG_ALL
|
||||
printf( "SetTimeInTimezone( %s )\n", tzid );
|
||||
#endif
|
||||
if( m_tzid )
|
||||
nsMemory::Free( m_tzid );
|
||||
|
||||
if( tzid )
|
||||
m_tzid= (char*) nsMemory::Clone( tzid, strlen(tzid)+1);
|
||||
else
|
||||
m_tzid = nsnull;
|
||||
|
||||
icaltimetype newdatetime = ConvertFromPrtime( ms );
|
||||
|
||||
icaltimezone *from_zone = icaltimezone_get_builtin_timezone_from_tzid ( tzid );
|
||||
if( from_zone )
|
||||
icaltimezone_convert_time ( &newdatetime, from_zone, currenttimezone );
|
||||
else {
|
||||
if( m_tzid )
|
||||
nsMemory::Free( m_tzid );
|
||||
m_tzid = nsnull;
|
||||
}
|
||||
|
||||
m_datetime = newdatetime;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP oeDateTimeImpl::Clear()
|
||||
{
|
||||
m_datetime = icaltime_null_time();
|
||||
@ -189,3 +221,21 @@ void oeDateTimeImpl::AdjustToWeekday( short weekday ) {
|
||||
currentday = icaltime_day_of_week( m_datetime );
|
||||
}
|
||||
}
|
||||
|
||||
/* readonly attribute string tzid; */
|
||||
NS_IMETHODIMP oeDateTimeImpl::GetTzID(char **aRetVal)
|
||||
{
|
||||
#ifdef ICAL_DEBUG_ALL
|
||||
printf( "GetTzID() = " );
|
||||
#endif
|
||||
if( m_tzid ) {
|
||||
*aRetVal= (char*) nsMemory::Clone( m_tzid, strlen(m_tzid)+1);
|
||||
if( *aRetVal == nsnull )
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
} else
|
||||
*aRetVal= nsnull;
|
||||
#ifdef ICAL_DEBUG_ALL
|
||||
printf( "\"%s\"\n", *aRetVal );
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -41,8 +41,12 @@
|
||||
#include "oeIICal.h"
|
||||
extern "C" {
|
||||
#include "ical.h"
|
||||
int icaltimezone_get_vtimezone_properties (icaltimezone *zone,
|
||||
icalcomponent *component);
|
||||
}
|
||||
|
||||
extern icaltimezone *currenttimezone;
|
||||
|
||||
#define OE_DATETIME_CID \
|
||||
{ 0x78b5b255, 0x7450, 0x47c0, { 0xba, 0x16, 0x0a, 0x6e, 0x7e, 0x80, 0x6e, 0x5d } }
|
||||
|
||||
@ -58,6 +62,7 @@ public:
|
||||
void AdjustToWeekday( short weekday );
|
||||
/* additional members */
|
||||
struct icaltimetype m_datetime;
|
||||
char *m_tzid;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -41,6 +41,105 @@
|
||||
icaltimetype ConvertFromPrtime( PRTime indate );
|
||||
PRTime ConvertToPrtime ( icaltimetype indate );
|
||||
|
||||
extern icalarray *builtin_timezones;
|
||||
extern char *gDefaultTzidPrefix;
|
||||
|
||||
//icaltimetype ConvertFromPrtime( PRTime indate );
|
||||
void icaltimezone_init_mozilla_zones (void)
|
||||
{
|
||||
gDefaultTzidPrefix="/Mozilla.org/";
|
||||
|
||||
char timezonecalstr[] = \
|
||||
"BEGIN:VCALENDAR\n\
|
||||
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar Timezone Table V1.0//EN\n\
|
||||
VERSION:2.0\n\
|
||||
END:VCALENDAR\n\
|
||||
";
|
||||
|
||||
char *timezoneformatstr = "BEGIN:VTIMEZONE\n\
|
||||
TZID:/Mozilla.org/BasicTimezones/NH-GMT%c%02d:%02d\n\
|
||||
LOCATION:NH-GMT%c%02d:%02d\n\
|
||||
BEGIN:STANDARD\n\
|
||||
TZOFFSETFROM:%c%02d%02d\n\
|
||||
TZOFFSETTO:%c%02d%02d\n\
|
||||
TZNAME:NHS-GMT%c%02d:%02d\n\
|
||||
DTSTART:19991031T020000\n\
|
||||
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\n\
|
||||
END:STANDARD\n\
|
||||
BEGIN:DAYLIGHT\n\
|
||||
TZOFFSETFROM:%c%02d%02d\n\
|
||||
TZOFFSETTO:%c%02d%02d\n\
|
||||
TZNAME:NHD-GMT%c%02d:%02d\n\
|
||||
DTSTART:20000402T020000\n\
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYMONTHDAY=1,2,3,4,5,6,7;BYDAY=SU\n\
|
||||
END:DAYLIGHT\n\
|
||||
END:VTIMEZONE\n";
|
||||
|
||||
char timezonestr[1024];
|
||||
|
||||
builtin_timezones = icalarray_new ( 44, 32); //HARDCODED sizeof(icaltimezone)=44
|
||||
|
||||
icalcomponent *vcalendar = icalparser_parse_string(timezonecalstr);
|
||||
icalcomponent *vtimezone;
|
||||
|
||||
//Components should be sorted by location
|
||||
//+00:00 to +12:00
|
||||
for( int i=0; i<25; i++ ) {
|
||||
char sign = '+';
|
||||
int hour = i/2;
|
||||
int minute = i%2==0 ? 00 : 30;
|
||||
int hour2 = (i+2)/2;
|
||||
sprintf( timezonestr, timezoneformatstr
|
||||
, sign, hour, minute
|
||||
, sign, hour, minute
|
||||
, sign, hour2, minute
|
||||
, sign, hour, minute
|
||||
, sign, hour, minute
|
||||
, sign, hour, minute
|
||||
, sign, hour2, minute
|
||||
, sign, hour, minute );
|
||||
vtimezone = icalcomponent_new_from_string( timezonestr );
|
||||
icalcomponent_add_component( vcalendar, vtimezone );
|
||||
}
|
||||
//-00:30 to -12:00
|
||||
for( int i=-1; i>-25; i-- ) {
|
||||
char sign = '-';
|
||||
int hour = -1*i/2;
|
||||
int minute = i%2==0 ? 00 : 30;
|
||||
char sign2 = (i+2)<0 ? '-' : '+';
|
||||
int hour2 = (i+2)<0 ? -1*(i+2)/2 : (i+2)/2;
|
||||
sprintf( timezonestr, timezoneformatstr
|
||||
, sign, hour, minute
|
||||
, sign, hour, minute
|
||||
, sign2, hour2, minute
|
||||
, sign, hour, minute
|
||||
, sign, hour, minute
|
||||
, sign, hour, minute
|
||||
, sign2, hour2, minute
|
||||
, sign, hour, minute );
|
||||
vtimezone = icalcomponent_new_from_string( timezonestr );
|
||||
icalcomponent_add_component( vcalendar, vtimezone );
|
||||
}
|
||||
|
||||
for( vtimezone = icalcomponent_get_first_component( vcalendar, ICAL_VTIMEZONE_COMPONENT );
|
||||
vtimezone != NULL;
|
||||
vtimezone = icalcomponent_get_next_component( vcalendar, ICAL_VTIMEZONE_COMPONENT ) ) {
|
||||
icaltimezone *zone=icaltimezone_new();
|
||||
icaltimezone_get_vtimezone_properties ( zone, vtimezone );
|
||||
icalarray_append (builtin_timezones, zone);
|
||||
}
|
||||
|
||||
PRExplodedTime ext;
|
||||
PR_ExplodeTime( PR_Now(), PR_LocalTimeParameters, &ext);
|
||||
int gmtoffsethour = ext.tm_params.tp_gmt_offset < 0 ? -1*ext.tm_params.tp_gmt_offset / 3600 : ext.tm_params.tp_gmt_offset / 3600;
|
||||
int gmtoffsetminute = ext.tm_params.tp_gmt_offset%3600 ? 30 : 00;
|
||||
char zone_location[20];
|
||||
sprintf( zone_location, "NH-GMT%c%02d:%02d", ext.tm_params.tp_gmt_offset < 0 ? '-' : '+'
|
||||
, gmtoffsethour, gmtoffsetminute );
|
||||
|
||||
currenttimezone = icaltimezone_get_builtin_timezone ( zone_location );
|
||||
}
|
||||
|
||||
oeICalContainerImpl::oeICalContainerImpl()
|
||||
{
|
||||
#ifdef ICAL_DEBUG
|
||||
@ -73,6 +172,8 @@ oeICalContainerImpl::oeICalContainerImpl()
|
||||
m_filter = new oeICalContainerFilter();
|
||||
NS_ADDREF( m_filter );
|
||||
m_filter->m_calendarArray = m_calendarArray;
|
||||
|
||||
icaltimezone_init_mozilla_zones ();
|
||||
}
|
||||
|
||||
oeICalContainerImpl::~oeICalContainerImpl()
|
||||
@ -1453,3 +1554,14 @@ void oeFilterDateTime::SetFieldType( PRInt32 icaltype )
|
||||
{
|
||||
m_icaltype = icaltype;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP oeFilterDateTime::GetTzID(char **aRetVal)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP oeFilterDateTime::SetTimeInTimezone( PRTime ms, const char *tzid )
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
@ -1935,6 +1935,15 @@ bool oeICalEventImpl::ParseIcalComponent( icalcomponent *comp )
|
||||
m_start->SetMinute( 0 );
|
||||
m_start->m_datetime.is_date = false; //Because currently we depend on m_datetime being a complete datetime value.
|
||||
}
|
||||
icalparameter *tmppar = icalproperty_get_first_parameter( prop, ICAL_TZID_PARAMETER );
|
||||
const char *tzid=nsnull;
|
||||
if( tmppar )
|
||||
tzid = icalparameter_get_tzid( tmppar );
|
||||
if( tzid ) {
|
||||
PRTime timeinms;
|
||||
m_start->GetTime( &timeinms );
|
||||
m_start->SetTimeInTimezone( timeinms, tzid );
|
||||
}
|
||||
} else {
|
||||
m_start->m_datetime = icaltime_null_time();
|
||||
}
|
||||
@ -1952,6 +1961,15 @@ bool oeICalEventImpl::ParseIcalComponent( icalcomponent *comp )
|
||||
prop = icalcomponent_get_first_property( vevent, ICAL_DTEND_PROPERTY );
|
||||
if ( prop != 0) {
|
||||
m_end->m_datetime = icalproperty_get_dtend( prop );
|
||||
icalparameter *tmppar = icalproperty_get_first_parameter( prop, ICAL_TZID_PARAMETER );
|
||||
const char *tzid=nsnull;
|
||||
if( tmppar )
|
||||
tzid = icalparameter_get_tzid( tmppar );
|
||||
if( tzid ) {
|
||||
PRTime timeinms;
|
||||
m_end->GetTime( &timeinms );
|
||||
m_end->SetTimeInTimezone( timeinms, tzid );
|
||||
}
|
||||
} else if( !icaltime_is_null_time( m_start->m_datetime ) ) {
|
||||
m_end->m_datetime = m_start->m_datetime;
|
||||
} else {
|
||||
@ -2414,26 +2432,59 @@ icalcomponent* oeICalEventImpl::AsIcalComponent()
|
||||
}
|
||||
|
||||
//startdate
|
||||
char *starttzid=nsnull;
|
||||
if( m_start && !icaltime_is_null_time( m_start->m_datetime ) ) {
|
||||
if( m_allday ) {
|
||||
m_start->GetTzID( &starttzid );
|
||||
if( m_allday && !starttzid ) {
|
||||
m_start->SetHour( 0 );
|
||||
m_start->SetMinute( 0 );
|
||||
m_start->m_datetime.is_date = true; //This will reflect the event being an all-day event
|
||||
}
|
||||
prop = icalproperty_new_dtstart( m_start->m_datetime );
|
||||
if( starttzid ) {
|
||||
icaltimezone *timezone = icaltimezone_get_builtin_timezone_from_tzid (starttzid);
|
||||
icaltimetype convertedtime = m_start->m_datetime;
|
||||
icaltimezone_convert_time ( &convertedtime, currenttimezone, timezone );
|
||||
if( m_allday ) {
|
||||
convertedtime.is_date = true; //This will reflect the event being an all-day event
|
||||
}
|
||||
icalproperty_set_dtstart( prop, convertedtime );
|
||||
icalparameter *tmppar = icalparameter_new_tzid( starttzid );
|
||||
icalproperty_add_parameter( prop, tmppar );
|
||||
icalcomponent_add_component( newcalendar, icalcomponent_new_clone( icaltimezone_get_component ( timezone ) ) );
|
||||
}
|
||||
icalcomponent_add_property( vevent, prop );
|
||||
m_start->m_datetime.is_date = false; //Because currently we depend on m_datetime being a complete datetime value.
|
||||
}
|
||||
|
||||
//enddate
|
||||
if( m_end && !icaltime_is_null_time( m_end->m_datetime ) ) {
|
||||
//enddate
|
||||
if( m_allday ) {
|
||||
char *tzid=nsnull;
|
||||
m_end->GetTzID( &tzid );
|
||||
if( m_allday && !tzid ) {
|
||||
m_end->SetHour( 23 );
|
||||
m_end->SetMinute( 59 );
|
||||
}
|
||||
prop = icalproperty_new_dtend( m_end->m_datetime );
|
||||
if( tzid ) {
|
||||
icaltimezone *timezone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
|
||||
icaltimetype convertedtime = m_end->m_datetime;
|
||||
icaltimezone_convert_time ( &convertedtime, currenttimezone, timezone );
|
||||
if( m_allday ) {
|
||||
convertedtime.hour=23;
|
||||
convertedtime.minute=59;
|
||||
}
|
||||
icalproperty_set_dtend( prop, convertedtime );
|
||||
icalparameter *tmppar = icalparameter_new_tzid( tzid );
|
||||
icalproperty_add_parameter( prop, tmppar );
|
||||
if( !starttzid || strcmp( starttzid, tzid ) != 0 )
|
||||
icalcomponent_add_component( newcalendar, icalcomponent_new_clone( icaltimezone_get_component ( timezone ) ) );
|
||||
nsMemory::Free( tzid );
|
||||
}
|
||||
icalcomponent_add_property( vevent, prop );
|
||||
}
|
||||
if( starttzid )
|
||||
nsMemory::Free( starttzid );
|
||||
|
||||
if( m_stamp && !icaltime_is_null_time( m_stamp->m_datetime ) ) {
|
||||
//stampdate
|
||||
@ -2443,11 +2494,11 @@ icalcomponent* oeICalEventImpl::AsIcalComponent()
|
||||
|
||||
//snoozetimes
|
||||
icalcomponent *tmpcomp=NULL;
|
||||
int i;
|
||||
for( i=0; i<m_snoozetimes.Count(); i++ ) {
|
||||
int j;
|
||||
for( j=0; j<m_snoozetimes.Count(); j++ ) {
|
||||
if( tmpcomp == NULL )
|
||||
tmpcomp = icalcomponent_new( ICAL_X_COMPONENT );
|
||||
icaltimetype snoozetime = ConvertFromPrtime( *(PRTime *)(m_snoozetimes[i]) );
|
||||
icaltimetype snoozetime = ConvertFromPrtime( *(PRTime *)(m_snoozetimes[j]) );
|
||||
prop = icalproperty_new_dtstamp( snoozetime );
|
||||
icalcomponent_add_property( tmpcomp, prop );
|
||||
}
|
||||
@ -2457,6 +2508,7 @@ icalcomponent* oeICalEventImpl::AsIcalComponent()
|
||||
PRUint32 attachmentCount = 0;
|
||||
m_attachments->Count(&attachmentCount);
|
||||
nsCOMPtr<nsIMsgAttachment> element;
|
||||
unsigned int i;
|
||||
for (i = 0; i < attachmentCount; i ++) {
|
||||
m_attachments->QueryElementAt(i, NS_GET_IID(nsIMsgAttachment), getter_AddRefs(element));
|
||||
if (element)
|
||||
|
||||
@ -70,8 +70,10 @@ interface oeIDateTime : nsISupports
|
||||
attribute short hour;
|
||||
attribute short minute;
|
||||
attribute boolean utc;
|
||||
readonly attribute string tzID;
|
||||
PRTime getTime();
|
||||
void setTime( in PRTime ms );
|
||||
void setTimeInTimezone( in PRTime ms, in string tzID );
|
||||
string toString();
|
||||
void clear();
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user