tzservices/tzserver/Client/Source/timezoneconverter.cpp
changeset 0 2e3d3ce01487
child 81 676b6116ca93
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <tz.h>
       
    17 #include "tzrules.h"
       
    18 #include <vtzrules.h>
       
    19 #include <tzconverter.h>
       
    20 #include "tzruleholder.h"
       
    21 #include "tzchangenotifier.h"
       
    22 
       
    23 //
       
    24 // CTzRuleHolder
       
    25 //
       
    26 
       
    27 CTzRuleHolder::CTzRuleHolder( RTz& aTzServer ) :
       
    28     iTzServer (aTzServer)
       
    29 	{
       
    30 	}
       
    31 
       
    32 CTzRuleHolder::~CTzRuleHolder()
       
    33 	{
       
    34 	delete iTzChangeNotifier;
       
    35 	delete iTzActualisedRules;
       
    36 	delete iTzRules;
       
    37 	}
       
    38 
       
    39 CTzRuleHolder* CTzRuleHolder::NewL( RTz& aTzServer )
       
    40 	{
       
    41 	CTzRuleHolder* self = new(ELeave) CTzRuleHolder( aTzServer );
       
    42 	CleanupStack::PushL( self );
       
    43 	self->ConstructL();
       
    44 	CleanupStack::Pop( self );
       
    45 	return self;
       
    46     }
       
    47 
       
    48 void CTzRuleHolder::ConstructL()
       
    49     {
       
    50 	// Must be connected.
       
    51 	if (!iTzServer.Handle())
       
    52 	    {
       
    53 	    User::Leave( KErrNotReady );
       
    54 	    }
       
    55 
       
    56 	CTzId* tzId = iTzServer.GetTimeZoneIdL();
       
    57 	SetCurrentTzId(tzId->TimeZoneNumericID());
       
    58 	delete tzId;
       
    59 	
       
    60     iTzChangeNotifier = CTzChangeNotifier::NewL( *this );
       
    61     iTzChangeNotifier->StartObserving();
       
    62     }
       
    63 
       
    64 /**
       
    65 Clears the cache.
       
    66 */
       
    67 void CTzRuleHolder::ClearRules()
       
    68 	{
       
    69 	delete iTzActualisedRules;
       
    70 	iTzActualisedRules = NULL;
       
    71 	delete iTzRules;
       
    72 	iTzRules = NULL;
       
    73 	iCurrentTzId = 0;
       
    74 	}
       
    75 
       
    76 
       
    77 
       
    78 
       
    79 void CTzRuleHolder::DoConvertL(TTime& aTime, TTzTimeReference aTimerRef)
       
    80 	{
       
    81 	// The change notifier may not have had a chance to run yet
       
    82 	// so check if it is ready to run now to force the update of the client side cache
       
    83 	iTzChangeNotifier->RunIfReadyL();
       
    84 	
       
    85 	if (!(iTzRules && iTzRules->RulesApply(aTime) ) )
       
    86 		{
       
    87 		if (!iTzRules)
       
    88 
       
    89 			{
       
    90 			TTime startTime(TDateTime(0,EJanuary,0,0,0,0,0));
       
    91 			TTime endTime(TDateTime(KMaxYear,EDecember,30,23,59,59,0));
       
    92 			iTzRules = iTzServer.GetTimeZoneRulesL(startTime, endTime, aTimerRef);
       
    93 			}
       
    94 		}
       
    95 		
       
    96 	// adjust for aTimerRef?
       
    97 	TDateTime dateTime = aTime.DateTime();
       
    98 	TUint year = dateTime.Year();
       
    99 	if (!(iTzActualisedRules 
       
   100 			&& year >= iTzActualisedRules->StartYear() 
       
   101 			&& year <= iTzActualisedRules->EndYear() ) )
       
   102 		{
       
   103 		// avoid over/under flow
       
   104 		TUint startYear = year;
       
   105 		TUint endYear = startYear;
       
   106 		if (startYear >= (KRuleCacheLowerLimit+1))
       
   107 			{
       
   108 			startYear -= (KRuleCacheLowerLimit+1);
       
   109 			}
       
   110 		if (endYear < (KMaxTUint - KRuleCacheUpperLimit))
       
   111 			{
       
   112 			endYear += KRuleCacheUpperLimit;
       
   113 			}
       
   114 
       
   115 		CVTzActualisedRules* newRules = CVTzActualisedRules::NewL(startYear, endYear);
       
   116 		CleanupStack::PushL(newRules);
       
   117 		iTzRules->GetActualisedRulesL(*newRules);
       
   118 		CleanupStack::Pop(newRules);
       
   119 
       
   120 		delete iTzActualisedRules;
       
   121 		iTzActualisedRules = newRules;
       
   122 		}
       
   123 		
       
   124 	User::LeaveIfError(iTzRules->ConvertTime(*iTzActualisedRules, aTime, aTimerRef));
       
   125 	}
       
   126 
       
   127 /**
       
   128 Handles notifications from the Time Zone Server
       
   129 if the Time Zone Database Changes or the System Time Zone is Changed then
       
   130 the cached rules are no longer valid. Discard them.
       
   131 */
       
   132 void CTzRuleHolder::NotifyTimeZoneChangeL(RTz::TTzChanges aChange)
       
   133 	{
       
   134 	User::LeaveIfError(aChange);
       
   135 
       
   136 	if (aChange == RTz::ETZDatabaseChanged ||
       
   137 		aChange == RTz::ETZSystemTimeZoneChanged)
       
   138 		{
       
   139 		ClearRules();
       
   140 		CTzId* tzId = iTzServer.GetTimeZoneIdL();
       
   141 		SetCurrentTzId(tzId->TimeZoneNumericID());
       
   142 		delete tzId;
       
   143 		}
       
   144 		
       
   145 	// re-request notification
       
   146 	iTzChangeNotifier->StartObserving();
       
   147 
       
   148 	}
       
   149 	
       
   150 //
       
   151 // CTzChangeNotifier
       
   152 //
       
   153 CTzChangeNotifier::~CTzChangeNotifier()
       
   154 	{
       
   155 	Cancel();
       
   156 	}
       
   157 
       
   158 CTzChangeNotifier* CTzChangeNotifier::NewL( CTzRuleHolder& aRulesHolder )
       
   159 
       
   160 	{
       
   161 	CTzChangeNotifier* self = new(ELeave) CTzChangeNotifier( aRulesHolder );
       
   162 	CActiveScheduler::Add(self);
       
   163 	return self;
       
   164 	}
       
   165 
       
   166 /**
       
   167 Starts observing for changes to the time zone from the the Time Zone Server.
       
   168 @return KErrNotReady if already active, KErrNotReady if session not
       
   169 open, otherwise KErrNone.
       
   170 */
       
   171 TInt CTzChangeNotifier::StartObserving()
       
   172 	{
       
   173 	if (IsActive())
       
   174 		{
       
   175 		return KErrNotReady;
       
   176 		}
       
   177 
       
   178 	iStatus = KRequestPending;
       
   179 	SetActive();
       
   180 	iRulesHolder.Server().RegisterTzChangeNotifier(iStatus);
       
   181 	return KErrNone;
       
   182 	}
       
   183 
       
   184 /**
       
   185 Stops Observing the Time Zone Server.
       
   186 */
       
   187 void CTzChangeNotifier::StopObserving()
       
   188 	{
       
   189 	Cancel();
       
   190 	}
       
   191 
       
   192 void CTzChangeNotifier::RunIfReadyL()
       
   193 	{
       
   194 	if (IsActive() && iStatus != KRequestPending)
       
   195 		{
       
   196 		RunL();
       
   197 		Cancel();
       
   198 		StartObserving();
       
   199 		}
       
   200 	}
       
   201 
       
   202 void CTzChangeNotifier::RunL()
       
   203 	{
       
   204 	iRulesHolder.NotifyTimeZoneChangeL( static_cast<RTz::TTzChanges>(
       
   205 	    iStatus.Int()) );
       
   206 	}
       
   207 
       
   208 void CTzChangeNotifier::DoCancel()
       
   209 	{
       
   210 	iRulesHolder.Server().CancelRequestForNotice();
       
   211 	}
       
   212 
       
   213 //
       
   214 // CTzConverter
       
   215 //
       
   216 const RTz& CTzConverter::Server() const
       
   217 	{
       
   218 	return iTzServer;
       
   219 	}
       
   220 
       
   221 CTzConverter::CTzConverter(RTz& aTzServer) : iTzServer(aTzServer)
       
   222 	{
       
   223 	}
       
   224 
       
   225 void CTzConverter::ConstructL()
       
   226 	{
       
   227 	// Caching is now done through RTz so enable its caching. This will
       
   228 	// do nothing if connected, but if unconnected, then this will leave 
       
   229 	// with KErrNotReady.
       
   230 	iTzServer.StartCachingL();
       
   231 
       
   232 	}
       
   233 
       
   234 // Handles notifications from the Time Zone Server
       
   235 // if the Time Zone Database Changes or the System Time Zone is Changed then
       
   236 // the cached rules is no longer valid. discard it.
       
   237 void CTzConverter::NotifyTimeZoneChangeL(RTz::TTzChanges /*aChange*/)
       
   238 	{
       
   239 	// No longer does anything. This is done in RTz.
       
   240 	}
       
   241 
       
   242 /** 
       
   243 CTzConverter factory method.
       
   244 
       
   245 Provides client side caching for conversions in the local time zone. Caching 
       
   246 is done through RTz but enabled through this interface. When caching has been 
       
   247 enabled by this class and the RTz functions for local time zone conversion are
       
   248 used, they too will use the cache instead of the server. Multiple CTzConverter's
       
   249 can use the same RTz session. Each converter will be notified by the server if
       
   250 the time zone changes, and the cache will be updated appropriately.
       
   251 
       
   252 
       
   253 To disable caching in RTz, the session must be closed. Caching will be 
       
   254 re-enabled if a CTzConverter associated with the RTz is later used again 
       
   255 for local time zone conversions.
       
   256  
       
   257 This will leave with KErrNotReady if the RTz passed in is not connected.
       
   258 
       
   259 @param aTzServer Connection to the time zone server. 
       
   260 @return A pointer to the new CTzConverter object. The caller takes ownership.
       
   261 */
       
   262 EXPORT_C CTzConverter* CTzConverter::NewL(RTz& aTzServer)
       
   263 	{
       
   264 	CTzConverter* self = new(ELeave) CTzConverter(aTzServer);
       
   265 	CleanupStack::PushL(self);
       
   266 	self->ConstructL();
       
   267 	CleanupStack::Pop(self);
       
   268 	return self;
       
   269 	}
       
   270 
       
   271 /**
       
   272 Destructor.
       
   273 */
       
   274 EXPORT_C CTzConverter::~CTzConverter()
       
   275 	{
       
   276 	}
       
   277 
       
   278 
       
   279 
       
   280 
       
   281 /** 
       
   282 Converts a time from UTC to local (wall-clock) time 
       
   283 for the current system time zone.
       
   284 @param aTime On entry, contains the UTC time to be converted 
       
   285 and the converted value on exit. 
       
   286 @return KErrNone if successful, otherwise another system error code.
       
   287 */
       
   288 EXPORT_C TInt CTzConverter::ConvertToLocalTime(TTime& aTime)
       
   289 	{
       
   290 
       
   291 
       
   292 	// Ensure that caching is enabled. It will be disabled if the TZ server
       
   293 	// has become disconnected since this object was created.
       
   294 	TRAPD( error, iTzServer.StartCachingL() );
       
   295 	if (error == KErrNone)
       
   296 	    {
       
   297 	    return iTzServer.ConvertToLocalTime( aTime );
       
   298 	    }
       
   299 	else
       
   300 	    {
       
   301 	    return error;
       
   302 	    }
       
   303 	}
       
   304 
       
   305 /** 
       
   306 Converts a time from UTC to the local (wall-clock) time 
       
   307 for the specified time zone.
       
   308 
       
   309 @param aTime On entry, contains the UTC time to be converted, 
       
   310 and the converted value on exit.
       
   311 @param aZone Time zone ID.
       
   312 @return KErrNone if successful, otherwise another system error code.
       
   313 */
       
   314 EXPORT_C TInt CTzConverter::ConvertToLocalTime(TTime& aTime,
       
   315 													 const CTzId& aZone)
       
   316 	{
       
   317 	return (iTzServer.ConvertToLocalTime(aTime, aZone));
       
   318 	}
       
   319 
       
   320 /** 
       
   321 Converts a local (wall-clock) time for the current system time zone into UTC.
       
   322 @param aTime On entry, contains the local time to be converted, 
       
   323 and the converted value on exit.
       
   324 @return KErrNone if successful, otherwise another system error code.
       
   325 */
       
   326 EXPORT_C TInt CTzConverter::ConvertToUniversalTime(TTime& aTime)
       
   327 	{
       
   328 
       
   329 
       
   330 	// Ensure that caching is enabled. It will be disabled if the TZ server
       
   331 	// has become disconnected since this object was created.
       
   332 	TRAPD( error, iTzServer.StartCachingL() );
       
   333 	if (error == KErrNone)
       
   334 	    {
       
   335     	return iTzServer.ConvertToUniversalTime( aTime );
       
   336     	}
       
   337     else
       
   338         {
       
   339         return error;
       
   340         }
       
   341 	}
       
   342 
       
   343 /** 
       
   344 Converts a local (wall-clock) time for the specified time zone into UTC.
       
   345 @param aTime On entry, contains the local time to be converted, 
       
   346 and the converted value on exit. 
       
   347 @param aZone The time zone ID.
       
   348 @return KErrNone if successful, otherwise another system error code.
       
   349 */
       
   350 EXPORT_C TInt CTzConverter::ConvertToUniversalTime(TTime& aTime,
       
   351 													const CTzId& aZone)
       
   352 	{
       
   353 
       
   354 	return (iTzServer.ConvertToUniversalTime(aTime, aZone));
       
   355 	}
       
   356 
       
   357 /** 
       
   358 Get the numerical ID of the current time zone.
       
   359 @return The time zone ID.
       
   360 */
       
   361 EXPORT_C TUint16 CTzConverter::CurrentTzId()
       
   362 	{
       
   363 	TUint16 tzId = iTzServer.CurrentCachedTzId();
       
   364 	return tzId;
       
   365 	}