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:
mostafah%oeone.com 2003-03-04 20:54:14 +00:00
parent ee97617e6b
commit 82e74ecb31
5 changed files with 228 additions and 7 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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();
};