clock2/clockengines/clocktimezoneresolver/src/clocktimezoneresolverimpl.cpp
changeset 0 f979ecb2b13e
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   The source file for the CClockTimeZoneResolverImpl class.
       
    15 *
       
    16 */
       
    17 
       
    18 // System includes
       
    19 #include <tzlocalizer.h>
       
    20 
       
    21 // User includes
       
    22 #include "clocktimezoneresolverimpl.h"
       
    23 #include "clockmcctzmapper.h"
       
    24 #include "clocktimezoneresolver.h"
       
    25 #include "clock_debug.h"
       
    26 
       
    27 // Constants
       
    28 const TInt KMinute( 60 );     // Seconds
       
    29 const TInt KZerothRule( 0 );
       
    30 const TInt KOne( 1 );
       
    31 
       
    32 // Literals
       
    33 _LIT( KDefault, "default" );
       
    34 
       
    35 // ---------------------------------------------------------------------------
       
    36 // CClockTimeZoneResolverImpl::NewL
       
    37 // rest of the details are commented in the header
       
    38 // ---------------------------------------------------------------------------
       
    39 //
       
    40 CClockTimeZoneResolverImpl* CClockTimeZoneResolverImpl::NewL()
       
    41 	{
       
    42 	__PRINTS( "CClockTimeZoneResolverImpl::NewL - Entry" );
       
    43 	
       
    44 	CClockTimeZoneResolverImpl* self = new ( ELeave ) CClockTimeZoneResolverImpl();
       
    45 	CleanupStack::PushL( self );
       
    46 	
       
    47 	self->ConstructL();
       
    48 	
       
    49 	CleanupStack::Pop();
       
    50 	
       
    51 	__PRINTS( "CClockTimeZoneResolverImpl::NewL - Exit" );
       
    52 	
       
    53 	return self;
       
    54 	}
       
    55 	
       
    56 // ---------------------------------------------------------
       
    57 // CClockTimeZoneResolverImpl::~CClockTimeZoneResolverImpl
       
    58 // rest of the details are commented in the header
       
    59 // ---------------------------------------------------------
       
    60 //
       
    61 CClockTimeZoneResolverImpl::~CClockTimeZoneResolverImpl()
       
    62 	{
       
    63 	__PRINTS( "CClockTimeZoneResolverImpl::~CClockTimeZoneResolverImpl - Entry" );
       
    64 	
       
    65 	if( iMccTzIdMapper )
       
    66 		{
       
    67 		delete iMccTzIdMapper;
       
    68 		iMccTzIdMapper = NULL;
       
    69 		}
       
    70 		
       
    71 	iRtz.Close();
       
    72 	
       
    73 	iTempZoneIds.ResetAndDestroy();
       
    74 		
       
    75 	__PRINTS( "CClockTimeZoneResolverImpl::~CClockTimeZoneResolverImpl - Exit" );
       
    76 	}
       
    77 	
       
    78 // ---------------------------------------------------------
       
    79 // CClockTimeZoneResolverImpl::CClockTimeZoneResolverImpl
       
    80 // rest of the details are commented in the header
       
    81 // ---------------------------------------------------------
       
    82 //	
       
    83 CClockTimeZoneResolverImpl::CClockTimeZoneResolverImpl()
       
    84 	{
       
    85 	__PRINTS( "CClockTimeZoneResolverImpl::CClockTimeZoneResolverImpl - Entry" );
       
    86 	
       
    87 	// No implementation yet
       
    88 	
       
    89 	__PRINTS( "CClockTimeZoneResolverImpl::CClockTimeZoneResolverImpl - Exit" );
       
    90 	}
       
    91 	
       
    92 // ---------------------------------------------------------
       
    93 // CClockTimeZoneResolverImpl::ConstructL
       
    94 // rest of the details are commented in the header
       
    95 // ---------------------------------------------------------
       
    96 //
       
    97 void CClockTimeZoneResolverImpl::ConstructL()
       
    98 	{
       
    99 	__PRINTS( "CClockTimeZoneResolverImpl::ConstructL - Entry" );
       
   100 	
       
   101 	iMccTzIdMapper = CClockMCCTzIdMapper::NewL();
       
   102 	
       
   103 	User::LeaveIfError( iRtz.Connect() );
       
   104 	iRtz.SetAutoUpdateBehaviorL( RTz::ETZAutoDSTUpdateOn );
       
   105 	
       
   106 	__PRINTS( "CClockTimeZoneResolverImpl::ConstructL - Exit" );
       
   107 	}
       
   108 	
       
   109 // ---------------------------------------------------------
       
   110 // CClockTimeZoneResolverImpl::GetTimeZoneL
       
   111 // rest of the details are commented in the header
       
   112 // ---------------------------------------------------------
       
   113 //
       
   114 TInt CClockTimeZoneResolverImpl::GetTimeZoneL( const STimeAttributes& aTimeInfo, 
       
   115 										  	   const RMobilePhone::TMobilePhoneNetworkCountryCode& aMcc,
       
   116 										  	   TInt& aTzId )
       
   117 	{
       
   118 	__PRINTS( "CClockTimeZoneResolverImpl::GetTimeZoneL - Entry" );
       
   119 	
       
   120 	__PRINTS( "CClockTimeZoneResolverImpl::GetTimeZoneL - Exit" );
       
   121 	
       
   122 	// Try and find a DST zone Id that has current MCC and this UTC offset. 
       
   123     return FindDstZoneIdFromMccAndUtcOffsetL( aTimeInfo, aMcc, aTzId );
       
   124 	}
       
   125 
       
   126 // ---------------------------------------------------------
       
   127 // CClockTimeZoneResolverImpl::TzIdFromMccL
       
   128 // rest of the details are commented in the header
       
   129 // ---------------------------------------------------------
       
   130 //
       
   131 void CClockTimeZoneResolverImpl::TzIdFromMccL( const RMobilePhone::TMobilePhoneNetworkCountryCode& aMCC,
       
   132 									  		   RArray< CTzId >& aTzIdArray,
       
   133 									  		   const TTimeIntervalMinutes& aStdTimeOffset )
       
   134 	{
       
   135 	__PRINTS( "CClockTimeZoneResolverImpl::TzIdFromMccL - Entry" );
       
   136 	
       
   137 	iMccTzIdMapper->TzIdFromMccL( aMCC, aTzIdArray, aStdTimeOffset );
       
   138 	
       
   139 	__PRINTS( "CClockTimeZoneResolverImpl::TzIdFromMccL - Exit" );
       
   140 	}
       
   141 
       
   142 // ---------------------------------------------------------
       
   143 // CClockTimeZoneResolverImpl::MCCFromTzIdL
       
   144 // rest of the details are commented in the header
       
   145 // ---------------------------------------------------------
       
   146 //
       
   147 TInt CClockTimeZoneResolverImpl::MCCFromTzIdL( const CTzId& aTzId )
       
   148 	{
       
   149 	__PRINTS( "CClockTimeZoneResolverImpl::MCCFromTzIdL - Entry" );
       
   150 	
       
   151 	__PRINTS( "CClockTimeZoneResolverImpl::MCCFromTzIdL - Exit" );
       
   152 	
       
   153 	return iMccTzIdMapper->MCCFromTzIdL( aTzId );
       
   154 	}
       
   155 
       
   156 // ---------------------------------------------------------
       
   157 // CClockTimeZoneResolverImpl::FindDstZoneIdFromMccAndUtcOffsetL
       
   158 // rest of the details are commented in the header
       
   159 // ---------------------------------------------------------
       
   160 //
       
   161 TInt CClockTimeZoneResolverImpl::FindDstZoneIdFromMccAndUtcOffsetL( const STimeAttributes& aTimeInfo, 
       
   162 																	const RMobilePhone::TMobilePhoneNetworkCountryCode& aMcc,
       
   163 										  							TInt& aTzId )
       
   164 	{
       
   165 	__PRINTS( "CClockTimeZoneResolverImpl::FindDstZoneIdFromMccAndUtcOffsetL - Entry" );
       
   166 	
       
   167 	// Check if MCC is not available, in which case aMcc will be sent as 9999. 
       
   168 	// Try to narrow down to the timezone ID using the offset that we have got in aTimeInfo.
       
   169 	const TBuf< 4 > invalidMCC( KInvalidMCC );
       
   170 	
       
   171 	if( invalidMCC == aMcc &&  aTimeInfo.iTimeZoneOffset != TTimeIntervalMinutes( KErrNotFound ) )
       
   172 		{
       
   173 		__PRINTS( "CClockTimeZoneResolverImpl::FindDstZoneIdFromMccAndUtcOffsetL - Exit" );
       
   174 		
       
   175 		// Try to find if we can narrow down to a timezone ID with just the offset.
       
   176 		return GetTimeZoneIdWithOffsetL( aTimeInfo.iTimeZoneOffset, aTzId );
       
   177 		}
       
   178 	
       
   179 	// Check if we can find any zones for the given MCC even though we dont have a valid
       
   180 	// timezone offset. If so, set the timezone in case of countries with single zone.
       
   181 	if( aTimeInfo.iTimeZoneOffset == TTimeIntervalMinutes( KErrNotFound ) )
       
   182 		{		
       
   183 		__PRINTS( "CClockTimeZoneResolverImpl::FindDstZoneIdFromMccAndUtcOffsetL - Exit" );
       
   184 		
       
   185 		return GetTimeZoneIdWithMccL( aMcc, aTimeInfo.iTimeZoneOffset, aTzId );
       
   186 		}
       
   187 
       
   188     // Calculate timezone offset.
       
   189     TTimeIntervalSeconds tzOffsetSec(0);
       
   190     
       
   191     if( KErrNotFound != aTimeInfo.iTimeZoneOffset.Int() )
       
   192     	{
       
   193     	tzOffsetSec=(aTimeInfo.iTimeZoneOffset.Int() * KMinute );
       
   194     	}
       
   195     
       
   196     // Calculate dst offset.
       
   197     TTimeIntervalSeconds dstOffsetSec(0);
       
   198     
       
   199     if( KErrNotFound != aTimeInfo.iDstOffset.Int() )
       
   200     	{
       
   201     	dstOffsetSec=( aTimeInfo.iDstOffset.Int() * KMinute );
       
   202     	}
       
   203     
       
   204     // Time sent by nw is UTC
       
   205     TTime nwUtcTime( aTimeInfo.iUtcDateTime );
       
   206 
       
   207     // Calculate local time => UTC time + timzone offset + DST offset
       
   208     TTime nwLocalTime( nwUtcTime + tzOffsetSec + dstOffsetSec );
       
   209 	
       
   210 
       
   211 	// Create array we we store all localized zones
       
   212     CTzLocalizedTimeZoneArray* locTimeZones = CTzLocalizedTimeZoneArray::NewL();
       
   213     CleanupStack::PushL( locTimeZones );
       
   214     
       
   215     // Create array of CTzID to store all unlocalized zones
       
   216     RArray<CTzId> tzArray;
       
   217     CleanupClosePushL(tzArray);
       
   218 
       
   219     // Get the unlocalized zones based on the utc offset and mcc we have.
       
   220     GetAllUnLocalizedZonesL( aMcc, aTimeInfo.iTimeZoneOffset, tzArray );
       
   221     
       
   222     // Make sure old stuff is deleted.
       
   223     iTempZoneIds.ResetAndDestroy();
       
   224 
       
   225     // Try to find a truly matching zone.
       
   226     FindMatchingUnLocalizedZoneL( tzArray, iTempZoneIds,nwLocalTime, nwUtcTime );
       
   227        
       
   228     CleanupStack::PopAndDestroy(1, &tzArray);   
       
   229     
       
   230     if( KErrNone == iTempZoneIds.Count() )
       
   231     	{
       
   232     	// Get the localized zones based on the utc offset and mcc we have
       
   233     	GetLocalizedZonesL( aMcc, aTimeInfo.iTimeZoneOffset, *locTimeZones );
       
   234 
       
   235     	// If we have no localised zones and network supports DST, we have done everything right, 
       
   236     	// OR if UTC offset is invalid and we have a multizone country, we can do nothing.
       
   237     
       
   238     	TInt returnVal( GetCorrectZone( *locTimeZones, aTimeInfo.iTimeZoneOffset, aTimeInfo.iDstOffset, aTzId ) );
       
   239     		
       
   240     	if( KErrNotFound == aTzId || KErrNone == returnVal )
       
   241     		{
       
   242     		__PRINTS( "CClockTimeZoneResolverImpl::FindDstZoneIdFromMccAndUtcOffsetL - Exit" );
       
   243 		
       
   244     		return returnVal;
       
   245     		}
       
   246     		    	
       
   247     	// Make sure old stuff is deleted.
       
   248     	iTempZoneIds.ResetAndDestroy();
       
   249 
       
   250     	// Try to find a truly matching zone.
       
   251     	FindMatchingLocalisedZoneL( *locTimeZones, iTempZoneIds, nwLocalTime, nwUtcTime );
       
   252 
       
   253     	// nitz improvement for spreading UTC offset start/
       
   254 
       
   255     	// If no matches found and DST indication is not supported by the NW,
       
   256     	// we need to subtract one DST offset amount from the UTC offset
       
   257     	// and see if that gives us any zones. 
       
   258     	// This is for cases when operators dont send the DST section of a nitz
       
   259     	// even when it is included in the utc offset.
       
   260 
       
   261     	if ( KErrNone == iTempZoneIds.Count() && ( KErrNotFound == aTimeInfo.iDstOffset.Int() ) ) 
       
   262     		{
       
   263     		TTimeIntervalMinutes tempUtcOffset( 0 );
       
   264     		RArray< CTzId > aTzIdArray;
       
   265     		CleanupClosePushL( aTzIdArray );
       
   266 
       
   267     		// Convert the TMobilePhoneNetworkCountryCode to a TInt
       
   268     		TInt mcc;
       
   269     		TLex lex( aMcc );
       
   270     		User::LeaveIfError( lex.Val( mcc ) );
       
   271 
       
   272     		// Get the DST zones within this country code
       
   273     		iMccTzIdMapper->DoGetTzIdFromMCCL( mcc, aTzIdArray );
       
   274 
       
   275     		CTzLocalizedTimeZoneArray* spreadLocTimeZones = CTzLocalizedTimeZoneArray::NewL();
       
   276     		CleanupStack::PushL( spreadLocTimeZones );
       
   277     		TInt32 dstOffsetInt = 0;
       
   278     		TInt32 tmpUtcOffset = 0;
       
   279     		TInt32 dstOffsetOld = -1;
       
   280 
       
   281     		for( TInt i( 0 ) ; i < aTzIdArray.Count(); i++ )
       
   282     			{
       
   283     			// Get the StdOffset and DstOffset values for every time zone.
       
   284     			// Use each new value of StdOffset to find matching LocalTimeZones
       
   285     			GetStdOffSetAndDstOffSetL( dstOffsetInt, tmpUtcOffset, aTzIdArray[ i ] );
       
   286     			if( dstOffsetOld != dstOffsetInt )
       
   287     				{
       
   288     				dstOffsetOld = dstOffsetInt;
       
   289     				}
       
   290     			else
       
   291     				{
       
   292     				continue;
       
   293     				}
       
   294 
       
   295     			tmpUtcOffset = aTimeInfo.iTimeZoneOffset.Int() - dstOffsetInt;
       
   296     			GetLocalizedZonesL( aMcc, tmpUtcOffset, *spreadLocTimeZones );
       
   297     			FindMatchingLocalisedZoneL( *spreadLocTimeZones, iTempZoneIds, nwLocalTime, nwUtcTime );  
       
   298     			}
       
   299 
       
   300     		CleanupStack::PopAndDestroy( spreadLocTimeZones );
       
   301     		CleanupStack::PopAndDestroy( &aTzIdArray );
       
   302     		}    
       
   303     	// nitz improvement for spreading UTC offset end
       
   304     	}
       
   305       
       
   306    
       
   307     TInt returnValue ( GetMatchingZonesL( locTimeZones, aTzId ) );
       
   308     
       
   309     if ( KErrNone == returnValue )
       
   310     {
       
   311     __PRINTS( "CClockTimeZoneResolverImpl::FindDstZoneIdFromMccAndUtcOffsetL - Exit" );
       
   312     
       
   313     return returnValue;
       
   314     }
       
   315 
       
   316     // If there are more than one matching unlocalized cities and zero localized cities
       
   317     // set to any one of the unlocalized cities.
       
   318     __PRINTS( "CClockTimeZoneResolverImpl::FindDstZoneIdFromMccAndUtcOffsetL - Exit" );
       
   319     
       
   320     return ProcessMatchingZones( *locTimeZones, aTzId );
       
   321     }
       
   322     
       
   323 // ---------------------------------------------------------
       
   324 // CClockTimeZoneResolverImpl::GetLocalizedZonesL
       
   325 // rest of the details are commented in the header
       
   326 // ---------------------------------------------------------
       
   327 //
       
   328 void CClockTimeZoneResolverImpl::GetLocalizedZonesL( const RMobilePhone::TMobilePhoneNetworkCountryCode& aMcc,
       
   329                                             		 const TTimeIntervalMinutes& aTimezoneOffset,                                            
       
   330                                             		 CTzLocalizedTimeZoneArray& aTzLocalisedArray )
       
   331     {
       
   332     __PRINTS( "CClockTimeZoneResolverImpl::GetLocalizedZonesL - Entry" );
       
   333     
       
   334     RArray< CTzId > tzArray;
       
   335     CleanupClosePushL( tzArray );
       
   336   
       
   337     // Get the DST zones within this country code
       
   338     iMccTzIdMapper->TzIdFromMccL( aMcc, tzArray, aTimezoneOffset );
       
   339         
       
   340     // If there is no DST zones for this MCC in our database, we can do nothing.
       
   341     if( tzArray.Count() == 0 ) 
       
   342 		{
       
   343 	    CleanupStack::PopAndDestroy( &tzArray );
       
   344 	    
       
   345 	    __PRINTS( "CClockTimeZoneResolverImpl::GetLocalizedZonesL - Exit" );
       
   346 	    
       
   347         return;
       
   348 		}
       
   349 
       
   350     CTzLocalizedTimeZone* timezone( NULL );
       
   351     
       
   352     // Create the localizer component
       
   353     CTzLocalizer* localizer = CTzLocalizer::NewL(); 
       
   354     CleanupStack::PushL( localizer );
       
   355     
       
   356     // Loop through the returned DST zone Ids picking the ones that have 
       
   357     // a corresponding localized timezone
       
   358     for( TInt index = 0 ; index < tzArray.Count() ; index++) 		
       
   359 		{
       
   360         TRAPD( error, timezone = localizer->GetLocalizedTimeZoneL( tzArray[ index ].TimeZoneNumericID() ) );
       
   361         if( !error )
       
   362             {
       
   363             if( timezone ) 
       
   364                 {
       
   365                 aTzLocalisedArray.AppendL( timezone );
       
   366                 }			
       
   367             }
       
   368 		}
       
   369     
       
   370     CleanupStack::PopAndDestroy( 2, &tzArray );
       
   371     
       
   372     __PRINTS( "CClockTimeZoneResolverImpl::GetLocalizedZonesL - Exit" );
       
   373     }
       
   374 
       
   375 // ---------------------------------------------------------
       
   376 // CClockTimeZoneResolverImpl::FindMatchingLocalisedZoneL
       
   377 // rest of the details are commented in the header
       
   378 // ---------------------------------------------------------
       
   379 //
       
   380 void CClockTimeZoneResolverImpl::FindMatchingLocalisedZoneL( CTzLocalizedTimeZoneArray& aLocTimeZones, 
       
   381                                            	            	 RPointerArray< CTzId >& aZoneIdArray, 
       
   382                                                         	 TTime& aNwLocalTime, 
       
   383                                                         	 TTime& aNwUtcTime )
       
   384     {
       
   385     __PRINTS( "CClockTimeZoneResolverImpl::FindMatchingLocalisedZoneL - Entry" );
       
   386     
       
   387     CTzConverter* tempCTzConv = CTzConverter::NewL( iRtz );
       
   388     CleanupStack::PushL( tempCTzConv );
       
   389  
       
   390     // Try to find a matching time from the list of localised timezones
       
   391     for( TInt index = 0 ; index < aLocTimeZones.Count() ; index++ )
       
   392         {            
       
   393         CTzId* tempTzId = CTzId::NewL( aLocTimeZones.At( index ).TimeZoneId() );
       
   394         CleanupStack::PushL( tempTzId );
       
   395         
       
   396         TTime tempTime = aNwUtcTime;            
       
   397         User::LeaveIfError( tempCTzConv->ConvertToLocalTime( tempTime,*tempTzId ) );
       
   398         if( tempTime == aNwLocalTime )
       
   399             {            
       
   400             aZoneIdArray.AppendL( tempTzId );
       
   401             CleanupStack::Pop( tempTzId );
       
   402             }
       
   403         else
       
   404             {
       
   405             CleanupStack::PopAndDestroy( tempTzId );
       
   406             }           
       
   407         }
       
   408     
       
   409     CleanupStack::PopAndDestroy( tempCTzConv );
       
   410     
       
   411     __PRINTS( "CClockTimeZoneResolverImpl::FindMatchingLocalisedZoneL - Exit" );
       
   412     }
       
   413     
       
   414 // ---------------------------------------------------------
       
   415 // CClockTimeZoneResolverImpl::GetAllUnLocalizedZonesL
       
   416 // rest of the details are commented in the header
       
   417 // ---------------------------------------------------------
       
   418 //
       
   419 void CClockTimeZoneResolverImpl::GetAllUnLocalizedZonesL( const RMobilePhone::TMobilePhoneNetworkCountryCode& aMcc,
       
   420                                             			  const TTimeIntervalMinutes& aTimezoneOffset,                                                                                        
       
   421                                            				  RArray< CTzId >& aTzUnLocalizedArray )
       
   422     {      
       
   423     __PRINTS( "CClockTimeZoneResolverImpl::GetAllUnLocalizedZonesL - Entry" );
       
   424         
       
   425     // Get the DST zones within this country code
       
   426     iMccTzIdMapper->TzIdFromMccL( aMcc,aTzUnLocalizedArray,aTimezoneOffset);
       
   427     
       
   428     __PRINTS( "CClockTimeZoneResolverImpl::GetAllUnLocalizedZonesL - Exit" );
       
   429     }
       
   430 
       
   431 // ---------------------------------------------------------
       
   432 // CClockTimeZoneResolverImpl::FindMatchingUnLocalizedZoneL
       
   433 // rest of the details are commented in the header
       
   434 // ---------------------------------------------------------
       
   435 //
       
   436 void CClockTimeZoneResolverImpl::FindMatchingUnLocalizedZoneL( RArray< CTzId >& aUnLocalizedTzArray, 
       
   437                                            					   RPointerArray< CTzId >& aZoneIdArray, 
       
   438                                            					   TTime& aNwLocalTime, 
       
   439                                            					   TTime& aNwUtcTime)
       
   440     {
       
   441 	__PRINTS( "CClockTimeZoneResolverImpl::FindMatchingUnLocalizedZoneL - Entry" );
       
   442 
       
   443 	CTzConverter* tempCTzConv = CTzConverter::NewL(iRtz);
       
   444 	CleanupStack::PushL(tempCTzConv);
       
   445 
       
   446 	// Try to find a matching time from the list of timezones
       
   447 	for (TInt index( 0 ); index < aUnLocalizedTzArray.Count(); index++)
       
   448 		{                    
       
   449 
       
   450 		CTzId* tempTzId = CTzId::NewL( aUnLocalizedTzArray[ index ].TimeZoneNumericID() );
       
   451 		CleanupStack::PushL( tempTzId );
       
   452 		TTime tempTime = aNwUtcTime;   
       
   453 
       
   454 		//Convert the zone time of the city to local time in microseconds                  
       
   455 		User::LeaveIfError( tempCTzConv->ConvertToLocalTime(tempTime,*tempTzId) );
       
   456 
       
   457 		//If the networklocal time and unlocalised city time from TZ rules 
       
   458 		//are same, add it to list
       
   459 		if( tempTime == aNwLocalTime )
       
   460 			{            
       
   461 			aZoneIdArray.AppendL( tempTzId );
       
   462 			CleanupStack::Pop( tempTzId );
       
   463 			}
       
   464 		else
       
   465 			{
       
   466 			CleanupStack::PopAndDestroy( tempTzId );
       
   467 			}           
       
   468 		}
       
   469 
       
   470 	CleanupStack::PopAndDestroy( tempCTzConv );
       
   471     
       
   472     __PRINTS( "CClockTimeZoneResolverImpl::FindMatchingUnLocalizedZoneL - Exit" );
       
   473 	}
       
   474 
       
   475 // ---------------------------------------------------------
       
   476 // CClockTimeZoneResolverImpl::GetStdOffSetAndDstOffSetL
       
   477 // rest of the details are commented in the header
       
   478 // ---------------------------------------------------------
       
   479 //
       
   480 void CClockTimeZoneResolverImpl::GetStdOffSetAndDstOffSetL( TInt32& aDstOffset,
       
   481 													   		TInt32& aStdOffset,
       
   482 													   		const CTzId& aTzId )
       
   483     {
       
   484 	__PRINTS( "CClockTimeZoneResolverImpl::GetStdOffSetAndDstOffSetL - Entry" );   
       
   485 	
       
   486 	// Local time
       
   487     TTime homeTime;
       
   488     homeTime.HomeTime();    
       
   489     
       
   490     TDateTime dateTime;
       
   491     dateTime = homeTime.DateTime();
       
   492     
       
   493 	// Get the CTzRules for the current year and for the given time zone id.
       
   494     CTzRules* tzRules = iRtz.GetTimeZoneRulesL( aTzId, 
       
   495     										    dateTime.Year(), 
       
   496     										    dateTime.Year(), 
       
   497     										    ETzWallTimeReference );
       
   498 	CleanupStack::PushL( tzRules );
       
   499     
       
   500 	// Get the Actualised rules for the same year. These are the DST rules from which we get the iNewOffset.
       
   501     CVTzActualisedRules *vActualisedRules = CVTzActualisedRules::NewL(
       
   502 													homeTime.DateTime().Year(), 
       
   503 													homeTime.DateTime().Year() );
       
   504 	CleanupStack::PushL( vActualisedRules );
       
   505 	tzRules->GetActualisedRulesL( *vActualisedRules );
       
   506 	
       
   507 	// The initial offset or the standard offset (w/o DST)
       
   508 	TInt32 initialTimeZoneOffset = tzRules->InitialStdTimeOffset();
       
   509 	
       
   510 	// The number of actualised rules
       
   511 	TInt ruleCount = vActualisedRules->Count();
       
   512 	
       
   513 	for( TInt ruleIndex( KZerothRule ); ruleIndex < ruleCount; ruleIndex++ )
       
   514 		{
       
   515 		const TVTzActualisedRule& tVTzactRule = ( *vActualisedRules )[ ruleIndex ];
       
   516 		
       
   517 		// If the standard offset and the new offset do not match then we have a dst offset.
       
   518 		// Technically if a timezone has DST then it can have a max of two offsets. One is the standard which doesn't show the 
       
   519 		// DST usage, and the other is the DST offset which is standard offset + the amount of DST
       
   520 		if( initialTimeZoneOffset != tVTzactRule.iNewOffset )
       
   521 			{
       
   522 			aDstOffset = tVTzactRule.iNewOffset - initialTimeZoneOffset;
       
   523 			aStdOffset = initialTimeZoneOffset;
       
   524 			CleanupStack::PopAndDestroy( vActualisedRules );
       
   525 			CleanupStack::PopAndDestroy( tzRules );
       
   526 			
       
   527 			__PRINTS( "CClockTimeZoneResolverImpl::GetStdOffSetAndDstOffSetL - Exit" );
       
   528 	
       
   529 			return;
       
   530 			}
       
   531 		}
       
   532 	__PRINTS( "CClockTimeZoneResolverImpl::GetStdOffSetAndDstOffSetL - Exit" );	
       
   533 
       
   534     CleanupStack::PopAndDestroy( vActualisedRules );
       
   535 	CleanupStack::PopAndDestroy( tzRules );
       
   536 	}
       
   537 
       
   538 // ---------------------------------------------------------------------------
       
   539 // CClockTimeZoneResolverImpl::GetTimeZoneIdWithOffsetL
       
   540 // rest of the details commented in the header
       
   541 // ---------------------------------------------------------------------------
       
   542 //
       
   543 TInt CClockTimeZoneResolverImpl::GetTimeZoneIdWithOffsetL( const TTimeIntervalMinutes& aTzOffset, TInt& aTzId )
       
   544 	{
       
   545 	__PRINTS( "CClockTimeZoneResolverImpl::GetTimeZoneIdWithOffsetL() - Entry" );
       
   546 	
       
   547 	TInt retVal( KErrNotFound );
       
   548 	
       
   549 	RArray< CTzId > tzIdArray;
       
   550 	CleanupClosePushL( tzIdArray );
       
   551 	
       
   552 	iMccTzIdMapper->TzIdFromOffsetL( aTzOffset, tzIdArray );
       
   553 	
       
   554 	if( KOne < tzIdArray.Count() )	
       
   555 		{
       
   556 		// For a multizone country without NITZ, it is not possible to 
       
   557 		// calculate the TZ.
       
   558 		aTzId = KErrNotFound;					
       
   559 		}
       
   560 	else if( KOne == tzIdArray.Count() )
       
   561 		{
       
   562 		// For a single zone country, without NITZ, set the default TZ
       
   563 		aTzId = tzIdArray[ KErrNone ].TimeZoneNumericID();		 	
       
   564 		retVal = KErrNone;
       
   565 		}
       
   566 	
       
   567 	CleanupStack::PopAndDestroy();
       
   568 	
       
   569 	__PRINTS( "CClockTimeZoneResolverImpl::GetTimeZoneIdWithOffsetL() - Exit" );
       
   570 	
       
   571 	return retVal;
       
   572 	}
       
   573     
       
   574 // ---------------------------------------------------------------------------
       
   575 // CClockTimeZoneResolverImpl::GetTimeZoneIdWithMccL
       
   576 // rest of the details commented in the header
       
   577 // ---------------------------------------------------------------------------
       
   578 //
       
   579 TInt CClockTimeZoneResolverImpl::GetTimeZoneIdWithMccL( const RMobilePhone::TMobilePhoneNetworkCountryCode& aMcc,
       
   580                                                    const TTimeIntervalMinutes& aTzOffset,
       
   581                                                    TInt& aTzId )
       
   582     {
       
   583     __PRINTS( "CClockTimeZoneResolverImpl::GetTimeZoneIdWithMccL() - Entry" );
       
   584     
       
   585     TInt retVal( KErrNotFound );
       
   586     
       
   587     RArray< CTzId > tzIdArray;
       
   588     CleanupClosePushL( tzIdArray );
       
   589             
       
   590     // Use the MCC to get all unlocalised zones.
       
   591     iMccTzIdMapper->TzIdFromMccL( aMcc, tzIdArray, aTzOffset );
       
   592     
       
   593     if( KOne < tzIdArray.Count() ) 
       
   594         {
       
   595         // For a multizone country without NITZ, it is not possible to 
       
   596         // calculate the TZ.
       
   597         aTzId = KErrNotFound;                 
       
   598         }
       
   599     else if( KOne == tzIdArray.Count() )
       
   600         {
       
   601         // For a single zone country, without NITZ, set the default TZ
       
   602         aTzId = tzIdArray[ KErrNone ].TimeZoneNumericID();         
       
   603         retVal = KErrNone;
       
   604         }
       
   605     
       
   606     CleanupStack::PopAndDestroy();
       
   607     
       
   608     __PRINTS( "CClockTimeZoneResolverImpl::GetTimeZoneIdWithMccL() - Exit" );
       
   609     
       
   610     return retVal;
       
   611     }
       
   612 
       
   613 // ---------------------------------------------------------------------------
       
   614 // CClockTimeZoneResolverImpl::ProcessMatchingZonesL
       
   615 // rest of the details commented in the header
       
   616 // ---------------------------------------------------------------------------
       
   617 //
       
   618 TInt CClockTimeZoneResolverImpl::ProcessMatchingZones( CTzLocalizedTimeZoneArray& aLocTimeZones, TInt& aTzId )
       
   619     {
       
   620     __PRINTS( "CClockTimeZoneResolverImpl::ProcessMatchingZonesL() - Entry" );
       
   621     
       
   622     if( ( KOne < iTempZoneIds.Count() ) && ( KErrNone == aLocTimeZones.Count() ) )
       
   623         {
       
   624         aTzId = iTempZoneIds[ FALSE ]->TimeZoneNumericID();
       
   625         iTempZoneIds.ResetAndDestroy();
       
   626         CleanupStack::PopAndDestroy( &aLocTimeZones );
       
   627 
       
   628         __PRINT( "aTzId: %d", aTzId );
       
   629         __PRINTS( "CClockTimeZoneResolverImpl::ProcessMatchingZonesL() - Exit" );
       
   630 
       
   631         return KErrNone;
       
   632         }
       
   633 
       
   634     iTempZoneIds.ResetAndDestroy();
       
   635 
       
   636     // If we don't have any localized zones at this point, we can do nothing
       
   637     if( KErrNone == aLocTimeZones.Count() )
       
   638         {        
       
   639         aTzId = KErrNotFound;
       
   640         CleanupStack::PopAndDestroy( &aLocTimeZones );
       
   641 
       
   642         __PRINT( "aTzId: %d", aTzId );
       
   643         __PRINTS( "CClockTimeZoneResolverImpl::ProcessMatchingZonesL() - Exit" );
       
   644 
       
   645         return KErrNotFound;
       
   646         }
       
   647 
       
   648     // If we have more than one localized zone at this point, we need to find the default one.
       
   649     TInt matchIndex( FALSE );
       
   650     for( TInt index( FALSE ); index < aLocTimeZones.Count(); index++ )
       
   651         {
       
   652         if( FALSE == aLocTimeZones.At( index ).StandardName().Compare( KDefault ) )
       
   653             {
       
   654             matchIndex = index;
       
   655             break; // We will take the first one we find.
       
   656             }
       
   657         }
       
   658 
       
   659     // This is the DST zone we are in.            
       
   660     aTzId = aLocTimeZones.At( matchIndex ).TimeZoneId();
       
   661 
       
   662     CleanupStack::PopAndDestroy( &aLocTimeZones );
       
   663 
       
   664     __PRINT( "aTzId: %d", aTzId );
       
   665 
       
   666     __PRINTS( "CClockTimeZoneResolverImpl::ProcessMatchingZonesL() - Exit" );
       
   667 
       
   668     return KErrNone;
       
   669     }
       
   670  
       
   671     
       
   672 // ---------------------------------------------------------------------------
       
   673 // CClockTimeZoneResolverImpl::GetCorrectZone
       
   674 // rest of the details commented in the header
       
   675 // ---------------------------------------------------------------------------
       
   676 // 
       
   677   TInt CClockTimeZoneResolverImpl::GetCorrectZone( CTzLocalizedTimeZoneArray& aLocTimeZones, 
       
   678                        						  const TTimeIntervalMinutes& aTimeZoneOffset,
       
   679                        						  const TTimeIntervalMinutes& aDstOffset,
       
   680                        						  TInt& aTzId )
       
   681 	{
       
   682 	__PRINTS( "CClockTimeZoneResolverImpl::GetCorrectZone - Entry" );
       
   683      
       
   684 	TInt returnVal( KErrNotFound );
       
   685 	
       
   686    	// If we have no localised zones and network supports DST, we have done everything right, 
       
   687 	// OR if UTC offset is invalid and we have a multizone country, we can do nothing.
       
   688 	if( ( KErrNone == aLocTimeZones.Count() && KErrNotFound != aDstOffset.Int() ) ||
       
   689 		( KOne < aLocTimeZones.Count() && KErrNotFound == aTimeZoneOffset.Int() ) )
       
   690 		{
       
   691 		aTzId = KErrNotFound;
       
   692 		
       
   693 		CleanupStack::PopAndDestroy( &aLocTimeZones );
       
   694 		}    
       
   695 	// Only one zone and DST indication supported by network. This is the dream case.
       
   696 	else if( KOne == aLocTimeZones.Count() && KErrNotFound != aDstOffset.Int() )
       
   697 		{
       
   698 		// This is the easiest case, get the zone id and return correct zone
       
   699 		aTzId = aLocTimeZones.At( FALSE ).TimeZoneId();
       
   700 		returnVal = KErrNone;
       
   701 		
       
   702 		CleanupStack::PopAndDestroy( &aLocTimeZones );
       
   703 		}
       
   704 
       
   705 	
       
   706     __PRINTS( "CClockTimeZoneResolverImpl::GetCorrectZone - Exit" );
       
   707     
       
   708    	return returnVal;
       
   709    	}
       
   710    	
       
   711    	
       
   712 // ---------------------------------------------------------------------------
       
   713 // CClockTimeZoneResolverImpl::GetMatchingZonesL
       
   714 // rest of the details commented in the header
       
   715 // ---------------------------------------------------------------------------
       
   716 //
       
   717 TInt CClockTimeZoneResolverImpl::GetMatchingZonesL( CTzLocalizedTimeZoneArray* aLocTimeZones, TInt& aTzId )
       
   718 	{
       
   719     // If we have only one matching zone, pick that up.
       
   720     if( KOne == iTempZoneIds.Count() )
       
   721         {
       
   722         aTzId = iTempZoneIds[ FALSE ]->TimeZoneNumericID();
       
   723         
       
   724         iTempZoneIds.ResetAndDestroy();
       
   725         CleanupStack::PopAndDestroy( aLocTimeZones );
       
   726         
       
   727        	__PRINT( "aTzId: %d", aTzId);
       
   728         
       
   729         __PRINTS( "CClockTimeZoneResolverImpl::GetMatchingZonesL - Exit" );
       
   730         
       
   731         return KErrNone;
       
   732         }        
       
   733 
       
   734     // If we have more zones, we will process them further.
       
   735     else if( KOne < iTempZoneIds.Count() )
       
   736         {
       
   737         
       
   738         for( TInt index( NULL ); index < aLocTimeZones->Count(); index++ )
       
   739         	{
       
   740         	aLocTimeZones->Remove( index );
       
   741         	}
       
   742         
       
   743         CTzLocalizedTimeZone* timezone( NULL );
       
   744         CTzLocalizer* localizer = CTzLocalizer::NewL();
       
   745         CleanupStack::PushL( localizer );
       
   746 
       
   747 		// Get the localized timezones for each zone that matches.
       
   748         for( TInt zoneIndex( FALSE ); zoneIndex < iTempZoneIds.Count(); zoneIndex++ )
       
   749            {
       
   750             TRAPD( errVal,
       
   751             	timezone = localizer->GetLocalizedTimeZoneL( iTempZoneIds[ zoneIndex ]->TimeZoneNumericID() ) );
       
   752             if( KErrNone == errVal && timezone )
       
   753                 {
       
   754                 aLocTimeZones->AppendL( timezone );
       
   755                 }                
       
   756             }
       
   757         CleanupStack::PopAndDestroy( localizer );
       
   758         } 
       
   759         
       
   760     __PRINTS( "CClockTimeZoneResolverImpl::GetMatchingZonesL - Exit" );
       
   761         
       
   762     return KErrNotFound;
       
   763 	}
       
   764 	
       
   765 // End of file