os/kernelhwsrv/kernel/eka/euser/us_time.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1995-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 the License "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 // e32\euser\us_time.cpp
    15 // System date and time functions
    16 // 
    17 //
    18 
    19 
    20 #include "us_std.h"
    21 
    22 // Date and time related constants
    23 
    24 static const TInt KMinutesToMicroSeconds = 60000000;
    25 static const TInt KSecondsToMicroSeconds = 1000000;
    26 static const TInt64 KDaysToMicroSeconds = I64LIT(86400000000);
    27 static const TInt64 KHoursToMicroSeconds = I64LIT(3600000000);
    28 
    29 // Days in each month
    30 LOCAL_D const TInt8 mTab[2][12]=
    31     {
    32     {31,28,31,30,31,30,31,31,30,31,30,31}, // 28 days in Feb
    33     {31,29,31,30,31,30,31,31,30,31,30,31}  // 29 days in Feb
    34     };
    35 
    36 // Days in year before 1st of each month
    37 LOCAL_D const TInt cmTab[2][12]=
    38 	{
    39 	{0,31,59,90,120,151,181,212,243,273,304,334},
    40 	{0,31,60,91,121,152,182,213,244,274,305,335}
    41 	};
    42 
    43 //
    44 // Time::FormatL overflow handler
    45 //
    46 #if defined(_UNICODE)
    47 NONSHARABLE_CLASS(TTimeOverflowLeave) : public TDes16Overflow
    48 	{
    49 public:
    50 	virtual void Overflow(TDes16 &aDes);
    51 	};
    52 void TTimeOverflowLeave::Overflow(TDes16 &/*aDes*/)
    53 	{
    54 	User::Leave(KErrOverflow);
    55 	}
    56 #else
    57 NONSHARABLE_CLASS(TTimeOverflowLeave) : public TDes8Overflow
    58 	{
    59 public:
    60 	virtual void Overflow(TDes8 &aDes);
    61 	};
    62 void TTimeOverflowLeave::Overflow(TDes8 &/*aDes*/)
    63 	{
    64 	User::Leave(KErrOverflow);
    65 	}
    66 #endif
    67 //
    68 
    69 EXPORT_C TDateTime::TDateTime(TInt aYear,TMonth aMonth,TInt aDay,TInt aHour,TInt aMinute,TInt aSecond,TInt aMicroSecond)
    70 //
    71 // always panic on a bad date/time field
    72 //
    73 /**
    74 Constructs the TDateTime object with the seven fields which comprise a date 
    75 and time.
    76 
    77 @param aYear        The year. No check is made for validity.
    78 @param aMonth       The month. Range is EJanuary to EDecember.
    79 @param aDay         The day. Range is zero to number of days in month minus one.
    80 @param aHour        The hour. Range is 0 to 23.
    81 @param aMinute      The minute. Range is 0 to 59.
    82 @param aSecond      The second. Range is 0 to 59
    83 @param aMicroSecond The microsecond. Range is 0 to 999999
    84 
    85 @panic USER 3, if an attempt is made to set an invalid value for any of 
    86        the fields, except for the year. No check is made upon the validity
    87        of the year.
    88 */
    89 	{
    90 
    91 	TInt ret=Set(aYear,aMonth,aDay,aHour,aMinute,aSecond,aMicroSecond);
    92 	__ASSERT_ALWAYS(ret==KErrNone,Panic(ETDateTimeBadDateTime));
    93 	}
    94 
    95 EXPORT_C TInt TDateTime::Set(TInt aYear,TMonth aMonth,TInt aDay,TInt aHour,TInt aMinute,TInt aSecond,TInt aMicroSecond)
    96 //
    97 // set the various time fields checking that each is valid
    98 // bomb out as soon as invalid field is set to forestall causing a panic
    99 //
   100 /**
   101 Sets all date and time components.
   102 
   103 Note:
   104 
   105 1. When setting the day and month, subtract one because the ranges are offset 
   106    from zero. 
   107 
   108 2. If the function returns an error, only those fields preceding the field which 
   109    caused the error will be changed. For example, if the hour is out of range, 
   110    the year, month and day will be set, all other components will remain unchanged.
   111 
   112 @param aYear        Year. No check is made on its validity, except that if the
   113                     date is set to February 29th, the year can only be set to a
   114                     leap year, otherwise  an error is returned.
   115 @param aMonth       Month. The valid range is EJanuary to EDecember. If an
   116                     attempt is made to set an invalid month, or if the current
   117                     day number in the month is greater than or equal to the
   118                     number of days in the new month, an error is returned.
   119 @param aDay         The number of the day within the month, offset from zero.
   120                     If greater than or equal to the total number of days in
   121                     the month,an error is returned.
   122 @param aHour        Hour. Range is 0 to 23.
   123 @param aMinute      Minute. Range is 0 to 59.
   124 @param aSecond      Second. Range is 0 to 59.
   125 @param aMicroSecond Microsecond. Range is 0 to 999999.
   126 
   127 @return KErrNone if successful, KErrGeneral if not.
   128 */
   129 	{
   130 
   131 	iYear=aYear;
   132 
   133 	if (aMonth<EJanuary || aMonth>EDecember)
   134 		return KErrGeneral;
   135 	iMonth=aMonth;
   136 
   137 	if (aDay<0 || aDay>=Time::DaysInMonth(iYear,iMonth))
   138 		return KErrGeneral;
   139 	iDay=aDay;
   140 
   141 	if (aHour<0 || aHour>=24)
   142 		return KErrGeneral;
   143 	iHour=aHour;
   144 
   145 	if (aMinute<0 || aMinute>=60)
   146 		return KErrGeneral;
   147 	iMinute=aMinute;
   148 
   149 	if (aSecond<0 || aSecond>=60)
   150 		return KErrGeneral;
   151 	iSecond=aSecond;
   152 
   153 	if (aMicroSecond<0 || aMicroSecond>=1000000)
   154 		return KErrGeneral;
   155 	iMicroSecond=aMicroSecond;
   156 
   157 	return KErrNone;
   158 	}
   159 
   160 EXPORT_C TInt TDateTime::SetYear(TInt aYear)
   161 //
   162 // doesnt let you reset 29th February to non-leap year, no check on year range
   163 //
   164 /**
   165 Sets the year without a leap year check.
   166 
   167 No check is made on the validity of the year except that if the current date
   168 is February 29th, the year can only be changed to another leap year, otherwise
   169 an error is returned.
   170 
   171 @param aYear The year.
   172 
   173 @return KErrNone if successful, KErrGeneral if not.
   174 */
   175 	{
   176 
   177 	if (iDay>=Time::DaysInMonth(aYear,iMonth))
   178 		return KErrGeneral;
   179 	iYear=aYear;
   180 	return KErrNone;
   181 	}
   182 
   183 EXPORT_C TInt TDateTime::SetYearLeapCheck(TInt aYear)
   184 //
   185 // lets you reset 29th February to non-leap year(moves date to 28th/Feb), no check on year range
   186 //
   187 /**
   188 Sets the year with a leap year check.
   189 
   190 Unlike SetYear(), if the date is the 29th February, this function allows
   191 the year to be set to a non-leap year. In this case, the date is reset to
   192 the 28th February.
   193 
   194 @param aYear The year.
   195 
   196 @return KErrNone if successful, KErrGeneral if not.
   197 
   198 @see TDateTime::SetYear
   199 */
   200 	{
   201 
   202 	if (iDay>=Time::DaysInMonth(aYear,iMonth))
   203         iDay=27;
   204     iYear=aYear;
   205 	return KErrNone;
   206 	}
   207 
   208 EXPORT_C TInt TDateTime::SetMonth(TMonth aMonth)
   209 /**
   210 Sets the month component of the date/time.
   211 
   212 @param aMonth The month to be set. The range is from EJanuary to EDecember.
   213               If an attempt is made to set an invalid month, or if the current
   214               day number in the month is greater than or equal to the number of
   215               days in the new month, an error is returned.
   216               
   217 @return KErrNone if successful, KErrGeneral if not.
   218 */
   219 	{
   220 
   221 	if (aMonth<EJanuary || aMonth>EDecember || iDay>=Time::DaysInMonth(iYear,aMonth))
   222 		return KErrGeneral;
   223 	iMonth=aMonth;
   224 	return KErrNone;
   225 	}
   226 
   227 EXPORT_C TInt TDateTime::SetDay(TInt aDay)
   228 /**
   229 Sets the day component of the date/time.
   230 
   231 @param aDay The number of the day within the month, offset from zero. If equal 
   232             to or greater than the total number of days in the month, an error
   233             is returned.
   234             
   235 @return KErrNone if successful, KErrGeneral if not.
   236 */
   237 	{
   238 
   239 	if (aDay<0 || aDay>=Time::DaysInMonth(iYear,iMonth))
   240 		return KErrGeneral;
   241 	iDay=aDay;
   242 	return KErrNone;
   243 	}
   244 
   245 EXPORT_C TInt TDateTime::SetHour(TInt aHour)
   246 /**
   247 Sets the hour component of the date/time.
   248 
   249 @param aHour The hour. Range is 0 to 23.
   250 
   251 @return KErrNone if successful, KErrGeneral if not.
   252 */
   253 	{
   254 
   255 	if (aHour<0 || aHour>=24) // GC - bug fix
   256 		return KErrGeneral;
   257 	iHour=aHour;
   258 	return KErrNone;
   259 	}
   260 
   261 EXPORT_C TInt TDateTime::SetMinute(TInt aMinute)
   262 /**
   263 Sets the minute component of the date/time.
   264 
   265 @param aMinute The minute. Range is 0 to 59.
   266 
   267 @return KErrNone if successful, KErrGeneral if not.
   268 */
   269 	{
   270 
   271 	if (aMinute<0 || aMinute>=60)
   272 		return KErrGeneral;
   273 	iMinute=aMinute;
   274 	return KErrNone;
   275 	}
   276 
   277 EXPORT_C TInt TDateTime::SetSecond(TInt aSecond)
   278 /**
   279 Sets the second component of the date/time.
   280 
   281 @param aSecond The second. Range is 0 to 59.
   282 
   283 @return KErrNone if successful, KErrGeneral if not.
   284 */
   285 	{
   286 
   287 	if (aSecond<0 || aSecond>=60)
   288 		return KErrGeneral;
   289 	iSecond=aSecond;
   290 	return KErrNone;
   291 	}
   292 
   293 EXPORT_C TInt TDateTime::SetMicroSecond(TInt aMicroSecond)
   294 /**
   295 Sets the microsecond component of the date/time.
   296 
   297 @param aMicroSecond The microsecond. Range is 0 to 999999.
   298 
   299 @return KErrNone if successful, KErrGeneral if not.
   300 */
   301 	{
   302 
   303 	if (aMicroSecond<0 || aMicroSecond>=1000000)
   304 		return KErrGeneral;
   305 	iMicroSecond=aMicroSecond;
   306 	return KErrNone;
   307 	}
   308 
   309 // class TTime
   310 
   311 EXPORT_C TTime::TTime(const TDesC &aString)
   312 /**
   313 Constructs a TTime object with a text string.
   314 
   315 The string consists of up to three components, any or all of which
   316 may be omitted:
   317 
   318 1. year, month and day, followed by a colon
   319 
   320 2. hour, minute and second, followed by a dot
   321 
   322 3. microsecond
   323 
   324 When all three components are present, the string should take the form:
   325 
   326 YYYYMMDD:HHMMSS.MMMMMM
   327 
   328 The conversion from text to time is carried out in the same manner as that 
   329 used in TTime::Set().
   330 
   331 For a list of the range of valid values for date and time components,
   332 see TDateTime::Set().
   333 
   334 @param aString Date and time string for initializing the TTime object. 
   335 
   336 @panic USER 113, if the string is syntactically incorrect, for example, if 
   337                  neither a colon nor a dot is present, or if any component of
   338                  the date or time is assigned an invalid value, or the year
   339                  is negative.
   340 
   341 @see TTime::Set
   342 @see TDateTime::Set
   343 */
   344 	{
   345 
   346 	__ASSERT_ALWAYS(Set(aString)==KErrNone,Panic(ETTimeValueOutOfRange));
   347 	}
   348 
   349 EXPORT_C TTime::TTime(const TDateTime &aDateTime) : iTime(Convert(aDateTime).Int64())
   350 /**
   351 Constructs a TTime object with the seven fields which comprise a date and time.
   352 
   353 @param aDateTime Date and time to which to initialise the TTime object.
   354 */
   355 
   356     {}
   357 
   358 EXPORT_C TInt TTime::Set(const TDesC &aString)
   359 //
   360 // Convert string to time. String is in the format:
   361 //
   362 // YYYYMMDD:HHMMSS.MMMMMM
   363 //
   364 // Any part may be ommitted, but either the
   365 // dot or colon or both must be present
   366 //
   367 /**
   368 Assigns a date and time contained in a descriptor to this TTime object.
   369 
   370 The string consists of up to three components, any or all of which may
   371 be omitted:
   372 
   373 1. year, month and day, followed by a colon 
   374 
   375 2. hour, minute and second, followed by a dot 
   376 
   377 3. microsecond
   378 
   379 When all three components are present, the string should take the form:
   380 
   381 YYYYMMDD:HHMMSS.MMMMMM
   382 
   383 If omitted, the first component is set to January 1st 0 AD nominal Gregorian. 
   384 If either the second or third components are omitted, they are set to zero.
   385 
   386 Notes:
   387 
   388 1. The month and day values are offset from zero.
   389 
   390 2. The only situations in which either the colon or dot may be omitted are as 
   391    follows:
   392    
   393    2.1 If the microsecond component is omitted, the preceding dot may also
   394        be omitted.
   395 
   396    2.2 The colon can be omitted only if a dot is located at string position
   397        zero (indicating that the first two components are missing), or at
   398        string position six (indicating that the first component only is
   399        missing).
   400 
   401 @param aString The date and time to be assigned to this TTime object.
   402        
   403 @return KErrNone if successful,
   404         KErrGeneral if the string is syntactically incorrect, for example,
   405         if neither a colon nor a dot is present, or if any component of the
   406         date or time is given an invalid value, or the year is negative.
   407         For a list of valid values for date and time components,
   408         see TDateTime::Set().
   409         If an error occurs, the date and time will remain unchanged.
   410 */
   411 	{
   412 
   413 //
   414 // Get position of the colon and dot separators
   415 //
   416     TInt colon=aString.Locate(':');
   417     TInt dot=aString.Locate('.');
   418 
   419     if(colon==KErrNotFound && dot==KErrNotFound)
   420         return(KErrGeneral);
   421 //
   422 // Zero parts that aren't supplied
   423 //
   424     TInt yy=0;
   425     TInt mm=0;
   426     TInt dd=0;
   427     TInt hr=0;
   428     TInt mi=0;
   429     TInt se=0;
   430     TInt ms=0;
   431 //
   432 // Convert YYYYMMDD if present
   433 //
   434     switch(colon)
   435         {
   436         case 0:
   437        	    break;
   438         case KErrNotFound:
   439             if(dot!=0 && dot!=6)
   440                 return(KErrGeneral);
   441             colon=-1;
   442             break;
   443         case 8:
   444 	   		{
   445             TLex y=aString.Left(4);
   446             TLex m=aString.Mid(4,2);
   447             TLex d=aString.Mid(6,2);
   448             y.Val(yy);
   449             m.Val(mm);
   450             d.Val(dd);
   451 	    	}
   452             break;
   453         default: // Colon in wrong position - return error
   454             return(KErrGeneral);
   455         }
   456 //
   457 // Convert HHMMSS if present
   458 //
   459     if(dot==KErrNotFound)
   460         dot=aString.Length();
   461      
   462     if(dot==colon+7)
   463         {
   464         TLex h=aString.Mid(dot-6,2);
   465         TLex m=aString.Mid(dot-4,2);
   466         TLex s=aString.Mid(dot-2,2);
   467         h.Val(hr);
   468         m.Val(mi);
   469         s.Val(se);
   470         }
   471     else if(dot!=KErrNotFound && dot!=0 && dot!=colon+1)
   472     	return(KErrGeneral);
   473 
   474     if(dot!=KErrNotFound)
   475         {
   476         if(aString.Length()>dot+7)
   477             return(KErrGeneral); // microseconds is more than 6 digits
   478         if(dot<aString.Length())
   479         	{
   480         	TLex m=aString.Mid(dot+1);
   481         	m.Val(ms);
   482         	}
   483         }
   484         
   485 //
   486 // Set the time! Do not construct newtime using the values or
   487 // it may cause TTime::Set() to panic rather than return an error
   488 //
   489 	TDateTime newtime;
   490 	if(newtime.Set(yy,TMonth(mm),dd,hr,mi,se,ms)!=KErrNone)
   491 		return(KErrGeneral);
   492     (*this)=newtime;
   493 	return KErrNone;
   494 	}
   495 
   496 EXPORT_C TInt TTime::HomeTimeSecure()
   497 /**
   498 Sets the date and time of this TTime to the secure home time. 
   499 Returns KErrNoSecureTime if there is no secure time source
   500 */
   501 	{
   502 	TInt utOffset=0;
   503 	TInt r = Exec::TimeNowSecure(*(TInt64*)this,utOffset);
   504     operator+=(TTimeIntervalSeconds(utOffset));
   505 	return r;
   506 	}
   507 
   508 EXPORT_C TInt TTime::UniversalTimeSecure()
   509 /**
   510 Sets the date and time of this TTime to the secure universal time.
   511 */
   512 	{
   513 	TInt utOffset=0;
   514 	return Exec::TimeNowSecure(*(TInt64*)this,utOffset);
   515 	}
   516 
   517 EXPORT_C void TTime::HomeTime()
   518 /**
   519 Sets the date and time of this TTime to the home time.
   520 */
   521 	{
   522 	TInt utOffset=0;
   523 	Exec::TimeNow(*(TInt64*)this,utOffset);
   524     operator+=(TTimeIntervalSeconds(utOffset));
   525 	}
   526 
   527 EXPORT_C void TTime::UniversalTime()
   528 /**
   529 Sets the date and time of this TTime to the universal time.
   530 */
   531 	{
   532 	TInt utOffset=0;
   533 	Exec::TimeNow(*(TInt64*)this,utOffset);
   534 	}
   535 
   536 EXPORT_C void TTime::RoundUpToNextMinute()
   537 /**
   538 Rounds this TTime up to the next minute.
   539 
   540 Both the seconds and microseconds components are set to zero.
   541 */
   542 	{
   543 
   544 	if (iTime>0)
   545 		iTime+=59999999;
   546 //*	TInt64 remainder;
   547 //*	Int64().DivMod(60000000,remainder);
   548 //*	iTime-=remainder;	
   549 	iTime-=iTime%60000000;
   550 	}
   551 
   552 TTime TTime::Convert(const TDateTime &aDateTime)
   553 //
   554 // converts TDateTime into a TTime, doesnt check for overflows
   555 //
   556 	{
   557 	
   558 	TInt days=365*aDateTime.Year()+Time::LeapYearsUpTo(aDateTime.Year());
   559 	TBool isleap=Time::IsLeapYear(aDateTime.Year());
   560 	days+=cmTab[isleap][aDateTime.Month()];
   561 	days+=aDateTime.Day();
   562 
   563 	TUint sum=aDateTime.MicroSecond()+aDateTime.Second()*KSecondsToMicroSeconds+aDateTime.Minute()*KMinutesToMicroSeconds;
   564 	return(((TInt64(days*3)<<3)+TInt64(aDateTime.Hour()))*KHoursToMicroSeconds+TInt64(sum));
   565 	}
   566 
   567 EXPORT_C TTime &TTime::operator=(const TDateTime &aDateTime)
   568 /**
   569 Assigns a TDateTime object to this TTime object.
   570 
   571 @param aDateTime The date and time to assign to this TTime object.
   572 
   573 @return This TTime object.
   574 */
   575 	{
   576 
   577 	iTime=Convert(aDateTime).Int64();
   578 	return(*this);
   579 	}
   580 
   581 EXPORT_C TDateTime TTime::DateTime() const
   582 //
   583 // converts iTime back into its TDateTime components
   584 //
   585 /**
   586 Converts the TTime object into a TDateTime object.
   587 
   588 This conversion must be done before the seven fields which comprise a date
   589 and time can be accessed.
   590 
   591 @return The components of the time, indicating year, month, day, hour, minute, 
   592         second, microsecond.
   593 */
   594 	{
   595 
   596 	TInt64 rem;
   597 	TInt64 daysSince0AD64(iTime);
   598 	
   599 	rem = daysSince0AD64 % KDaysToMicroSeconds;
   600 	daysSince0AD64 /= KDaysToMicroSeconds;
   601 
   602 	TInt daysSince0AD = static_cast<TInt>(daysSince0AD64);
   603 
   604 	TInt year;
   605 	TInt daysLeft;
   606 	if (iTime<0)
   607 		{ // -1 to make daysLeft +ve and assume leap year every 4 years
   608 		if (rem!=TInt64(0))
   609 			{
   610 			daysSince0AD--;
   611 			rem=iTime-TInt64(daysSince0AD)*KDaysToMicroSeconds;
   612 			}
   613 		year=(4*daysSince0AD)/((4*365)+1);
   614 		if ((4*daysSince0AD)%((4*365)+1))
   615 			year--;
   616 		daysLeft=daysSince0AD-((year*365)+Time::LeapYearsUpTo(year));
   617 		}
   618 	else
   619 		{ // after 1600 leap years less than every four years
   620 		year=(4*daysSince0AD)/((4*365)+1);
   621 		daysLeft=daysSince0AD-((year*365)+Time::LeapYearsUpTo(year));
   622 		TInt daysInYear=365+Time::IsLeapYear(year);
   623 	    while (daysLeft>=daysInYear)
   624 		    {
   625 			year++;
   626 	        daysLeft-=daysInYear;
   627 			daysInYear=365+Time::IsLeapYear(year);
   628 			}
   629 		}
   630 
   631 	TDateTime result(0,EJanuary,0,0,0,0,0);
   632 	result.SetYear(year);
   633 
   634    	TBool isleap=Time::IsLeapYear(year);
   635     TInt month=11;
   636 	const TInt* pCM=&(cmTab[isleap][11])+1;
   637 	while(daysLeft<*--pCM)
   638 		month--;
   639 	daysLeft-=*pCM;
   640 
   641 	result.SetMonth((TMonth)month);
   642 	result.SetDay(daysLeft);
   643 
   644 	TInt hour = static_cast<TInt>(rem >> 10) / 3515625;	// 3515625=KHoursToMicroSeconds/1024
   645 	result.SetHour(hour);
   646 	TUint rem32=I64LOW(rem-(TInt64(hour*3515625)<<10));
   647 	TUint min=rem32/KMinutesToMicroSeconds;
   648 	result.SetMinute((TInt)min);
   649 	rem32-=min*KMinutesToMicroSeconds;
   650 	TUint sec=rem32/KSecondsToMicroSeconds;
   651 	result.SetSecond((TInt)sec);
   652 	rem32-=sec*KSecondsToMicroSeconds;
   653 	result.SetMicroSecond(TInt(rem32));
   654 	return(result);
   655 	}
   656 
   657 EXPORT_C TTimeIntervalMicroSeconds TTime::MicroSecondsFrom(TTime aTime) const
   658 //
   659 // this - aTime
   660 //
   661 /**
   662 Calculates the number of microseconds difference between the specified TTime
   663 and this TTime.
   664 
   665 @param aTime The time to be compared with this TTime.
   666 
   667 @return Difference in microseconds between the two times. If the time specified 
   668         in the argument is later than this TTime, this value is negative.
   669 */
   670 	{
   671 
   672 	TInt64 difference=iTime-aTime.Int64();
   673 	return(difference);
   674 	}
   675 
   676 EXPORT_C TInt TTime::SecondsFrom(TTime aTime,TTimeIntervalSeconds &aInterval) const
   677 //
   678 // this - aTime as whole seconds
   679 // this function may fail if difference > no of seconds that can be represented in a TInt
   680 //
   681 /**
   682 Calculates the number of seconds difference between the specified TTime and
   683 this TTime.
   684 
   685 The difference may be positive or negative.
   686 
   687 @param aTime     The time to be compared with this TTime.
   688 @param aInterval On return contains the difference in seconds between the two 
   689                  times. If the time specified in the first argument is later than
   690                  this TTime, then this returned value is negative.
   691                  
   692 @return Error code. KErrNone if successful. 
   693                     KErrOverflow, if the calculated interval is too large for
   694                     a 32-bit integer.
   695 */
   696 	{
   697 	TInt64 diff;
   698 	if (iTime>aTime.Int64())
   699 		{
   700 		diff= TInt64(TUint64(iTime-aTime.Int64())/KSecondsToMicroSeconds);	
   701 		}
   702 	else 
   703 		{
   704 		diff= -TInt64(TUint64(aTime.Int64()-iTime)/KSecondsToMicroSeconds);
   705 		}	
   706 	if (diff>KMaxTInt || diff<KMinTInt)	
   707 	    return KErrOverflow; 
   708 	aInterval = static_cast<TInt>(diff);
   709 	return KErrNone;
   710 	}
   711 	
   712 EXPORT_C TInt TTime::MinutesFrom(TTime aTime,TTimeIntervalMinutes &aInterval) const
   713 //
   714 // iTime - aTime as whole minutes
   715 // function may fail if difference can't be represented as a TInt
   716 //
   717 /**
   718 Calculates the number of minutes difference between the specified TTime and
   719 this TTime.
   720 
   721 The difference may be positive or negative.
   722 
   723 @param aTime     The time to be compared with this TTime.
   724 @param aInterval On return contains the difference in minutes between the two 
   725                  times. If the time specified in the first argument is later
   726                  than this TTime, then this returned value is negative.
   727                  
   728 @return Error code. KErrNone if successful. 
   729                     KErrOverflow, if the calculated interval is too large for
   730                     a 32-bit integer.
   731 */
   732 	{
   733 	TInt64 diff;
   734 	if (iTime>aTime.Int64())
   735 		{
   736 		diff= TInt64(TUint64(iTime-aTime.Int64())/KMinutesToMicroSeconds);	
   737 		}
   738 	else 
   739 		{
   740 		diff= -TInt64(TUint64(aTime.Int64()-iTime)/KMinutesToMicroSeconds);
   741 		}	
   742 	if (diff>KMaxTInt || diff<KMinTInt)	
   743 	    return KErrOverflow; 
   744 	aInterval = static_cast<TInt>(diff);
   745 	return KErrNone; 
   746 	}
   747 
   748 EXPORT_C TInt TTime::HoursFrom(TTime aTime,TTimeIntervalHours &aInterval) const
   749 //
   750 // iTime - aTime as whole hours
   751 // function may fail if difference can't be represented as a TInt
   752 //
   753 /**
   754 Calculates the number of hours difference between the specified TTime and
   755 this TTime. 
   756 
   757 The difference may be positive or negative.
   758 
   759 @param aTime     The time to be compared with this TTime.
   760 @param aInterval On return contains the difference in hours between the two 
   761                  times. If the time specified in the first argument is later
   762                  than this TTime, then this returned value is negative.
   763                  
   764 @return Error code. KErrNone if successful. 
   765                     KErrOverflow, if the calculated interval is too large for
   766                     a 32-bit integer.
   767 */
   768 	{
   769 	TInt64 diff;
   770 	if (iTime>aTime.Int64())
   771 		{
   772 		diff= TInt64(TUint64(iTime-aTime.Int64())/KHoursToMicroSeconds);	
   773 		}
   774 	else 
   775 		{
   776 		diff= -TInt64(TUint64(aTime.Int64()-iTime)/KHoursToMicroSeconds);
   777 		}
   778 	if (diff>KMaxTInt || diff<KMinTInt)	
   779 	    return KErrOverflow; 
   780 	aInterval = static_cast<TInt>(diff);
   781 	return KErrNone;
   782 	}  
   783 
   784 
   785 EXPORT_C TTimeIntervalDays TTime::DaysFrom(TTime aTime) const
   786 //
   787 // iTime - aTime as whole days
   788 //
   789 /**
   790 Calculates the number of days difference between the specified TTime and
   791 this TTime. 
   792 
   793 The difference may be positive or negative.
   794 
   795 @param aTime  The time to be compared with this TTime.
   796 
   797 @return Difference in days between the two times. If the time specified in 
   798         aTime is later than this TTime, the returned value will be negative.
   799 */
   800 	{
   801 	if (iTime>aTime.Int64())
   802 		{
   803 		return TInt(TUint64(iTime-aTime.Int64())/KDaysToMicroSeconds);	
   804 		}
   805 	else 
   806 		{
   807 		return -TInt(TUint64(aTime.Int64()-iTime)/KDaysToMicroSeconds);
   808 		}	
   809 	}
   810 
   811 EXPORT_C TTimeIntervalMonths TTime::MonthsFrom(TTime aTime) const
   812 //
   813 // iTime - aTime as whole months - ie aTime must be on a later day in the month and later in that day
   814 // except for last days etc eg 31st October - 30 November is one month to be consistent with other
   815 // functions
   816 //
   817 /**
   818 Calculates the number of months between the specified TTime and this TTime.
   819 
   820 The result may be positive or negative.
   821 
   822 The interval in months between two TTimes is calculated by incrementing it 
   823 by one each time the same day number and time in the previous or following 
   824 month has been reached. Exceptions to this rule occur when this TTime is on 
   825 the last day of the month. In this case, the following rules apply:
   826 
   827 When comparing this TTime with a later time:
   828 
   829 1. if the following month is shorter, one month is deemed to separate the times 
   830    when the same time on the last day of the following month is reached. In this 
   831    case, the two day numbers are not the same.
   832 
   833 When comparing this TTime with an earlier time:
   834 
   835 1. if the previous month is shorter, one month is deemed to separate the times 
   836    when the last microsecond of the previous month is reached (23:59:59.999999 
   837    on the last day of the month).
   838 
   839 2. if the previous month is longer, one month is deemed to separate the times 
   840    when the same time on the last day of previous month is reached. In this case, 
   841    the two day numbers are not the same.
   842 
   843 @param aTime The time to be compared with this TTime.
   844 
   845 @return Difference in months between the two times. If the time specified in 
   846         the argument is later than this TTime, the interval is negative.
   847 */
   848 	{
   849 
   850 	TDateTime dateTimei=DateTime();
   851 	TDateTime dateTimea=aTime.DateTime();
   852 	
   853 	TInt monthsDifference=(dateTimei.Year()-dateTimea.Year())*12+(dateTimei.Month()-dateTimea.Month());
   854 
   855 	if (monthsDifference>0)
   856 		{
   857 		if (dateTimei.Day()<=dateTimea.Day())
   858 			{
   859 			if (iTime%KDaysToMicroSeconds<aTime.Int64()%KDaysToMicroSeconds || (dateTimei.Day()!=dateTimea.Day() && dateTimei.Day()!=DaysInMonth()-1))
   860 				monthsDifference--;
   861 			}
   862 		}
   863 	else
   864 		if (monthsDifference!=0)//monthsDifference<0
   865 			{
   866 			if (dateTimei.Day()>=dateTimea.Day())
   867 				{
   868 				if (iTime%KDaysToMicroSeconds>aTime.Int64()%KDaysToMicroSeconds || (dateTimei.Day()!=dateTimea.Day() && dateTimea.Day()!=aTime.DaysInMonth()-1))
   869 					monthsDifference++;
   870 				}
   871 			}
   872 
   873 	return(monthsDifference);			
   874 	}
   875 
   876 EXPORT_C TTimeIntervalYears TTime::YearsFrom(TTime aTime) const
   877 //
   878 // as above,but for twelve months
   879 //
   880 /**
   881 Calculates the number of years between the specified TTime and this TTime.
   882 
   883 The result may be positive or negative.
   884 
   885 Note that the interval in years between two TTimes is calculated by
   886 incrementing it by one each time the same day number and time in the previous
   887 or following year has been reached. The exception to this rule occurs when this
   888 TTime is the last day in February in a leap year. In this case, one year is
   889 deemed to have passed when the same time of day on the last day in the preceding 
   890 or following February has been reached.
   891 
   892 @param aTime The time to be compared with this TTime.
   893 
   894 @return Difference in years between the two times. If the time specified in 
   895         the argument is later than this TTime, the interval is negative.
   896 */
   897 	{
   898 
   899 	TTimeIntervalMonths mos= TTime::MonthsFrom(aTime);
   900 	TTimeIntervalYears ret=mos.Int()/12;
   901 	return(ret);			
   902 	}
   903 
   904 EXPORT_C TTime TTime::operator+(TTimeIntervalYears aYear) const
   905 /**
   906 Adds a time interval to this TTime, returning the result
   907 as a TTime.
   908 
   909 Note that in a leap year, when adding one year to the 29th February, the result
   910 is the 28th February in the following year.
   911 
   912 Note also that this TTime object is not changed.
   913 
   914 @param aYear A time interval in years. The argument is stored as a 32 bit
   915              signed integer. The maximum value which it can represent is
   916              2147483647. Any attempt to add more than this amount will
   917              produce incorrect results.
   918 
   919 @return The new time.
   920 */
   921 	{
   922 
   923 	return((*this)+TTimeIntervalMonths(aYear.Int()*12));
   924 	}
   925 
   926 EXPORT_C TTime TTime::operator+(TTimeIntervalMonths aMonth) const
   927 /**
   928 Adds a time interval to this TTime, returning the result
   929 as a TTime.
   930 
   931 Note that when adding one month to the last day in the month, if the following
   932 month is shorter, the result is the last day in the following month.
   933 For example, when adding one month to 31st August, the result is
   934 the 30th September.
   935 
   936 Note also that this TTime object is not changed.
   937 
   938 @param aMonth A time interval in months. The argument is stored as a 32 bit
   939               signed integer. The maximum value which it can represent is
   940               2147483647. Any attempt to add more than this amount will
   941               produce incorrect results.
   942 
   943 @return The new time.
   944 */
   945 	{
   946 
   947 	TDateTime dateTime=DateTime();
   948 	TInt month=dateTime.Month()+(dateTime.Year()*12)+aMonth.Int();
   949 	TInt day=dateTime.Day();
   950 	TInt year=month/12;
   951 	month%=12;
   952 	if (month<0)
   953 		{
   954 		year--;
   955 		month+=12;
   956 		}
   957 	TInt daysInMonth=(mTab[Time::IsLeapYear(year)][month]-1); 
   958 	if (day>=daysInMonth)
   959 		day=daysInMonth;
   960 	__ASSERT_ALWAYS(dateTime.Set(year,TMonth(month),day,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond())==KErrNone,Panic(ETDateTimeBadDateTime));
   961 	return(dateTime);
   962 	}
   963 							 
   964 EXPORT_C TTime TTime::operator+(TTimeIntervalDays aDay) const
   965 /**
   966 Adds a time interval to this TTime, returning the result
   967 as a TTime.
   968 
   969 Note that this TTime object is not changed.
   970 
   971 @param aDay A time interval in days. The argument is stored as a 32 bit
   972             signed integer. The maximum value which it can represent is
   973             2147483647. Any attempt to add more than this amount will
   974             produce incorrect results.
   975 
   976 @return The new time.
   977 */
   978 	{ 
   979 
   980 	return(iTime+TInt64(aDay.Int())*KDaysToMicroSeconds);
   981 	}
   982 
   983 EXPORT_C TTime TTime::operator+(TTimeIntervalHours aHour) const
   984 /**
   985 Adds a time interval to this TTime, returning the result
   986 as a TTime.
   987 
   988 Note that this TTime object is not changed.
   989 
   990 @param aHour A time interval in hours. The argument is stored as a 32 bit
   991              signed integer. The maximum value which it can represent is
   992              2147483647. Any attempt to add more than this amount will
   993              produce incorrect results.
   994 
   995 @return The new time.
   996 */
   997 	{
   998 
   999 	return(iTime+TInt64(aHour.Int())*KHoursToMicroSeconds);
  1000 	}
  1001 
  1002 EXPORT_C TTime TTime::operator+(TTimeIntervalMinutes aMinute) const
  1003 /**
  1004 Adds a time interval to this TTime, returning the result
  1005 as a TTime.
  1006 
  1007 Note that this TTime object is not changed.
  1008 
  1009 @param aMinute A time interval in minutes. The argument is stored as a 32 bit
  1010                signed integer. The maximum value which it can represent is
  1011                2147483647. Any attempt to add more than this amount will
  1012                produce incorrect results.
  1013 
  1014 @return The new time.
  1015 */
  1016 	{
  1017 
  1018 	return(iTime+TInt64(aMinute.Int())*KMinutesToMicroSeconds);
  1019 	}
  1020 
  1021 EXPORT_C TTime TTime::operator+(TTimeIntervalSeconds aSecond) const
  1022 /**
  1023 Adds a time interval to this TTime, returning the result
  1024 as a TTime.
  1025 
  1026 Note that this TTime object is not changed.
  1027 
  1028 @param aSecond A time interval in seconds. The argument is stored as a 32 bit
  1029                signed integer. The maximum value which it can represent is
  1030                2147483647. Any attempt to add more than this amount will
  1031                produce incorrect results.
  1032 
  1033 @return The new time.
  1034 */
  1035 	{
  1036 
  1037 	return(iTime+TInt64(aSecond.Int())*KSecondsToMicroSeconds);
  1038 	}
  1039 
  1040  
  1041 EXPORT_C TTime TTime::operator+(TTimeIntervalMicroSeconds aMicroSecond) const
  1042 /**
  1043 Adds a time interval to this TTime, returning the result
  1044 as a TTime.
  1045 
  1046 Note that this TTime object is not changed.
  1047 
  1048 @param aMicroSecond A time interval in microseconds.
  1049 
  1050 @return The new time.
  1051 */
  1052 	{
  1053 
  1054 	return(iTime+(aMicroSecond.Int64()));
  1055 	}
  1056 
  1057 EXPORT_C TTime TTime::operator+(TTimeIntervalMicroSeconds32 aMicroSecond) const
  1058 /**
  1059 Adds a time interval to this TTime, returning the result
  1060 as a TTime.
  1061 
  1062 Note that this TTime object is not changed.
  1063 
  1064 @param aMicroSecond A time interval in microseconds. The argument is stored as
  1065                     a 32 bit signed integer. The maximum value which it can
  1066                     represent is 2147483647. Any attempt to add more than this
  1067                     amount will produce incorrect results.
  1068 
  1069 @return The new time.
  1070 */
  1071 	{
  1072 
  1073 	return(iTime+aMicroSecond.Int());
  1074 	}
  1075 
  1076 EXPORT_C TTime TTime::operator-(TTimeIntervalYears aYear) const
  1077 /**
  1078 Substracts a time interval from this TTime, returning the result
  1079 as a TTime.
  1080 
  1081 Note that in a leap year, when subtracting one year from the 29th February,
  1082 the result is 28th February in the preceding year.
  1083 
  1084 Note also that this TTime object is not changed.
  1085 
  1086 @param aYear A time interval in years. The argument is stored as
  1087              a 32 bit signed integer. The maximum value which it can
  1088              represent is 2147483647. Any attempt to subtract more than this
  1089              amount will produce incorrect results.
  1090 
  1091 @return The new time.
  1092 */
  1093 	{
  1094 
  1095 	return((*this)-TTimeIntervalMonths(aYear.Int()*12));
  1096 	}
  1097 
  1098 EXPORT_C TTime TTime::operator-(TTimeIntervalMonths aMonth) const
  1099 /**
  1100 Substracts a time interval from this TTime, returning the result
  1101 as a TTime.
  1102 
  1103 Note that when subtracting one month from the last day in the month, if the
  1104 preceding month is shorter, the result is the last day in the preceding month.
  1105 For example, when subtracting 1 month from 31st October, the result is
  1106 the 30th September.
  1107 
  1108 Note also that this TTime object is not changed.
  1109 
  1110 @param aMonth A time interval in months. The argument is stored as
  1111               a 32 bit signed integer. The maximum value which it can
  1112               represent is 2147483647. Any attempt to subtract more than this
  1113               amount will produce incorrect results.
  1114 
  1115 @return The new time.
  1116 */
  1117 	{
  1118 
  1119 	return((*this)+TTimeIntervalMonths(aMonth.Int()*-1));
  1120 	}
  1121 							 
  1122 EXPORT_C TTime TTime::operator-(TTimeIntervalDays aDay) const
  1123 /**
  1124 Substracts a time interval from this TTime, returning the result
  1125 as a TTime.
  1126 
  1127 Note that this TTime object is not changed.
  1128 
  1129 @param aDay A time interval in days. The argument is stored as
  1130             a 32 bit signed integer. The maximum value which it can
  1131             represent is 2147483647. Any attempt to subtract more than this
  1132             amount will produce incorrect results.
  1133 
  1134 @return The new time.
  1135 */
  1136 	{ 
  1137 
  1138 	return(iTime-TInt64(aDay.Int())*KDaysToMicroSeconds);
  1139 	}
  1140 
  1141 EXPORT_C TTime TTime::operator-(TTimeIntervalHours aHour) const
  1142 /**
  1143 Substracts a time interval from this TTime, returning the result
  1144 as a TTime.
  1145 
  1146 Note that this TTime object is not changed.
  1147 
  1148 @param aHour A time interval in hours. The argument is stored as
  1149              a 32 bit signed integer. The maximum value which it can
  1150              represent is 2147483647. Any attempt to subtract more than this
  1151              amount will produce incorrect results.
  1152 
  1153 @return The new time.
  1154 */
  1155 	{
  1156 
  1157 	return(iTime-TInt64(aHour.Int())*KHoursToMicroSeconds);
  1158 	}
  1159 
  1160 EXPORT_C TTime TTime::operator-(TTimeIntervalMinutes aMinute) const
  1161 /**
  1162 Substracts a time interval from this TTime, returning the result
  1163 as a TTime.
  1164 
  1165 Note that this TTime object is not changed.
  1166 
  1167 @param aMinute A time interval in minutes. The argument is stored as
  1168                a 32 bit signed integer. The maximum value which it can
  1169                represent is 2147483647. Any attempt to subtract more than this
  1170                amount will produce incorrect results.
  1171 
  1172 @return The new time.
  1173 */
  1174 	{
  1175 
  1176 	return(iTime-TInt64(aMinute.Int())*KMinutesToMicroSeconds);
  1177 	}
  1178 
  1179 EXPORT_C TTime TTime::operator-(TTimeIntervalSeconds aSecond) const
  1180 /**
  1181 Substracts a time interval from this TTime, returning the result
  1182 as a TTime.
  1183 
  1184 Note that this TTime object is not changed.
  1185 
  1186 @param aSecond A time interval in seconds. The argument is stored as
  1187                a 32 bit signed integer. The maximum value which it can
  1188                represent is 2147483647. Any attempt to subtract more than this
  1189                amount will produce incorrect results.
  1190 
  1191 @return The new time.
  1192 */
  1193 	{
  1194 
  1195 	return(iTime-TInt64(aSecond.Int())*KSecondsToMicroSeconds);
  1196 	}
  1197 
  1198 EXPORT_C TTime TTime::operator-(TTimeIntervalMicroSeconds aMicroSecond) const
  1199 /**
  1200 Substracts a time interval from this TTime, returning the result
  1201 as a TTime.
  1202 
  1203 Note that this TTime object is not changed.
  1204 
  1205 @param aMicroSecond A time interval in microseconds.
  1206 
  1207 @return The new time.
  1208 */
  1209 	{
  1210 
  1211 	return(iTime-(aMicroSecond.Int64()));
  1212 	}
  1213 
  1214 EXPORT_C TTime TTime::operator-(TTimeIntervalMicroSeconds32 aMicroSecond) const
  1215 /**
  1216 Substracts a time interval from this TTime, returning the result
  1217 as a TTime.
  1218 
  1219 Note that this TTime object is not changed.
  1220 
  1221 @param aMicroSecond A time interval in microseconds. The argument is stored as
  1222                     a 32 bit signed integer. The maximum value which it can
  1223                     represent is 2147483647. Any attempt to subtract more than
  1224                     this amount will produce incorrect results.
  1225 
  1226 @return The new time.
  1227 */
  1228 	{
  1229 
  1230 	return(iTime-aMicroSecond.Int());
  1231 	}
  1232 
  1233 EXPORT_C TTime &TTime::operator+=(TTimeIntervalYears aYear)
  1234 /**
  1235 Adds a time interval to this TTime, returning a reference to this TTime.
  1236 
  1237 @param aYear A time interval in years.
  1238 
  1239 @return A reference to this TTime.
  1240 */
  1241 	{	
  1242 
  1243 	TTime tim=(*this)+aYear;
  1244 	iTime=tim.Int64();
  1245 	return(*this);
  1246 	}
  1247 
  1248 EXPORT_C TTime &TTime::operator+=(TTimeIntervalMonths aMonth)
  1249 /**
  1250 Adds a time interval to this TTime, returning a reference to this TTime.
  1251 
  1252 @param aMonth A time interval in months.
  1253 
  1254 @return A reference to this TTime.
  1255 */
  1256 	{
  1257 
  1258 	TTime tim=(*this)+aMonth;
  1259 	iTime=tim.Int64();
  1260 	return(*this);
  1261 	}
  1262 
  1263 EXPORT_C TTime &TTime::operator+=(TTimeIntervalDays aDay)
  1264 /**
  1265 Adds a time interval to this TTime, returning a reference to this TTime.
  1266 
  1267 @param aDay A time interval in days.
  1268 
  1269 @return A reference to this TTime.
  1270 */
  1271 	{
  1272 
  1273 	iTime+=TInt64(aDay.Int())*KDaysToMicroSeconds;
  1274 	return(*this);
  1275 	}
  1276 
  1277 EXPORT_C TTime &TTime::operator+=(TTimeIntervalHours aHour)
  1278 /**
  1279 Adds a time interval to this TTime, returning a reference to this TTime.
  1280 
  1281 @param aHour A time interval in hours.
  1282 
  1283 @return A reference to this TTime.
  1284 */
  1285 	{
  1286 
  1287 	iTime+=TInt64(aHour.Int())*KHoursToMicroSeconds;
  1288 	return(*this);
  1289 	}
  1290 
  1291 EXPORT_C TTime &TTime::operator+=(TTimeIntervalMinutes aMinute)
  1292 /**
  1293 Adds a time interval to this TTime, returning a reference to this TTime.
  1294 
  1295 @param aMinute A time interval in minutes.
  1296 
  1297 @return A reference to this TTime.
  1298 */
  1299 	{
  1300 
  1301 	iTime+=TInt64(aMinute.Int())*KMinutesToMicroSeconds;
  1302 	return(*this);
  1303 	}
  1304 
  1305 EXPORT_C TTime &TTime::operator+=(TTimeIntervalSeconds aSecond)
  1306 /**
  1307 Adds a time interval to this TTime, returning a reference to this TTime.
  1308 
  1309 @param aSecond A time interval in seconds.
  1310 
  1311 @return A reference to this TTime.
  1312 */
  1313 	{
  1314 
  1315 	iTime+=TInt64(aSecond.Int())*KSecondsToMicroSeconds;
  1316 	return(*this);
  1317 	}
  1318 
  1319 EXPORT_C TTime &TTime::operator+=(TTimeIntervalMicroSeconds aMicroSecond)
  1320 /**
  1321 Adds a time interval to this TTime, returning a reference to this TTime.
  1322 
  1323 @param aMicroSecond A time interval in microseconds.
  1324 
  1325 @return A reference to this TTime.
  1326 */
  1327 	{
  1328 
  1329 	iTime+=aMicroSecond.Int64();
  1330 	return(*this);
  1331 	}
  1332  
  1333 EXPORT_C TTime &TTime::operator+=(TTimeIntervalMicroSeconds32 aMicroSecond)
  1334 /**
  1335 Adds a time interval to this TTime, returning a reference to this TTime.
  1336 
  1337 @param aMicroSecond A time interval in microseconds, as a 32-bit integer.
  1338 
  1339 @return A reference to this TTime.
  1340 */
  1341 	{
  1342 
  1343 	iTime+=aMicroSecond.Int();
  1344 	return(*this);
  1345 	}
  1346  
  1347 EXPORT_C TTime &TTime::operator-=(TTimeIntervalYears aYear)
  1348 /**
  1349 Subtracts a time interval from this TTime, returning a reference to this TTime.
  1350 
  1351 @param aYear A time interval in years.
  1352 
  1353 @return A reference to this TTime.
  1354 */
  1355 	{	
  1356 
  1357 	TTime tim=(*this)-aYear;
  1358 	iTime=tim.Int64();
  1359 	return(*this);
  1360 	}
  1361 
  1362 EXPORT_C TTime &TTime::operator-=(TTimeIntervalMonths aMonth)
  1363 /**
  1364 Subtracts a time interval from this TTime, returning a reference to this TTime.
  1365 
  1366 @param aMonth A time interval in months.
  1367 
  1368 @return A reference to this TTime.
  1369 */
  1370 	{
  1371 
  1372 	TTime tim=(*this)-aMonth;
  1373 	iTime=tim.Int64();
  1374 	return(*this);
  1375 	}
  1376 
  1377 EXPORT_C TTime &TTime::operator-=(TTimeIntervalDays aDay)
  1378 /**
  1379 Subtracts a time interval from this TTime, returning a reference to this TTime.
  1380 
  1381 @param aDay A time interval in days.
  1382 
  1383 @return A reference to this TTime.
  1384 */
  1385 	{
  1386 
  1387 	iTime-=TInt64(aDay.Int())*KDaysToMicroSeconds;
  1388 	return(*this);
  1389 	}
  1390 
  1391 EXPORT_C TTime &TTime::operator-=(TTimeIntervalHours aHour)
  1392 /**
  1393 Subtracts a time interval from this TTime, returning a reference to this TTime.
  1394 
  1395 @param aHour A time interval in hours.
  1396 
  1397 @return A reference to this TTime.
  1398 */
  1399 	{
  1400 
  1401 	iTime-=TInt64(aHour.Int())*KHoursToMicroSeconds;
  1402 	return(*this);
  1403 	}
  1404 
  1405 EXPORT_C TTime &TTime::operator-=(TTimeIntervalMinutes aMinute)
  1406 /**
  1407 Subtracts a time interval from this TTime, returning a reference to this TTime.
  1408 
  1409 @param aMinute A time interval in minutes.
  1410 
  1411 @return A reference to this TTime.
  1412 */
  1413 	{
  1414 
  1415 	iTime-=TInt64(aMinute.Int())*KMinutesToMicroSeconds;
  1416 	return(*this);
  1417 	}
  1418 
  1419 EXPORT_C TTime &TTime::operator-=(TTimeIntervalSeconds aSecond)
  1420 /**
  1421 Subtracts a time interval from this TTime, returning a reference to this TTime.
  1422 
  1423 @param aSecond A time interval in seconds.
  1424 
  1425 @return A reference to this TTime.
  1426 */
  1427 	{
  1428 
  1429 	iTime-=TInt64(aSecond.Int())*KSecondsToMicroSeconds;
  1430 	return(*this);
  1431 	}
  1432 
  1433 EXPORT_C TTime &TTime::operator-=(TTimeIntervalMicroSeconds aMicroSecond)
  1434 /**
  1435 Subtracts a time interval from this TTime, returning a reference to this TTime.
  1436 
  1437 @param aMicroSecond A time interval in microseconds.
  1438 
  1439 @return A reference to this TTime.
  1440 */
  1441 	{
  1442 
  1443 	iTime-=aMicroSecond.Int64();
  1444 	return(*this);
  1445 	}
  1446 
  1447 EXPORT_C TTime &TTime::operator-=(TTimeIntervalMicroSeconds32 aMicroSecond)
  1448 /**
  1449 Subtracts a time interval from this TTime, returning a reference to this TTime.
  1450 
  1451 @param aMicroSecond A time interval in microseconds, as a 32-bit integer.
  1452 
  1453 @return A reference to this TTime.
  1454 */
  1455 	{
  1456 
  1457 	iTime-=aMicroSecond.Int();
  1458 	return(*this);
  1459 	}
  1460  
  1461 EXPORT_C TInt TTime::DaysInMonth() const
  1462 /**
  1463 Gets the number of days in the current month.
  1464 
  1465 @return The number of days in the month.
  1466 */
  1467 	{
  1468 
  1469 	TDateTime dateTime=DateTime();
  1470 	return(Time::DaysInMonth(dateTime.Year(),dateTime.Month()));
  1471 	}
  1472 
  1473 EXPORT_C TDay TTime::DayNoInWeek() const
  1474 //
  1475 // 1st January 0AD was a Monday
  1476 //
  1477 /**
  1478 Gets the day number within the current week.
  1479 
  1480 This is a value in the range zero to six inclusive, and honours the 
  1481 setting specified in TLocale::SetStartOfWeek().
  1482 
  1483 By default the first day in the week is Monday.
  1484 
  1485 @return The number of the day within the week. The range is EMonday to ESunday.
  1486 
  1487 @see TLocale::SetStartOfWeek
  1488 */
  1489 	{
  1490 
  1491 
  1492 	TInt64 fullDays=iTime/KDaysToMicroSeconds;
  1493 	TInt day = static_cast<TInt>(fullDays) % 7;
  1494 	if (iTime<0)
  1495 		{
  1496 		if (fullDays*KDaysToMicroSeconds!=iTime)
  1497 			day+=6;
  1498 		else
  1499 			if (day!=0)
  1500 				day+=7;
  1501 		}
  1502 	return((TDay)day);
  1503 	}
  1504 
  1505 EXPORT_C TInt TTime::DayNoInMonth() const
  1506 /**
  1507 Gets the day number in the month.
  1508 
  1509 @return The day number in the month. The first day in the month is numbered 
  1510         zero.
  1511 */
  1512 	{
  1513 
  1514 	return(DateTime().Day());
  1515 	}
  1516 
  1517 EXPORT_C TInt TTime::DayNoInYear() const
  1518 //
  1519 // day number in comparison to 1st January
  1520 //
  1521 /**
  1522 Gets the day number in the year. 
  1523 
  1524 @return The day number in the year. The first day in the year is day one.
  1525 */
  1526 	{
  1527 
  1528 	TDateTime dateTime=DateTime();
  1529 	TTime jan1st=TDateTime(dateTime.Year(),EJanuary,0,0,0,0,0);
  1530 	return(DayNoInYear(jan1st));
  1531 	}
  1532 
  1533 EXPORT_C TInt TTime::DayNoInYear(TTime aStartDate) const
  1534 //
  1535 // day number in comparison to given date, check is made to ensure first day is within a year before aDay
  1536 //
  1537 /**
  1538 Gets the day number in the year when the start of the year is aStartDate. 
  1539 
  1540 If no start date is specified, the default is January 1st.
  1541 
  1542 @param aStartDate Indicates the date which is to be considered the start of 
  1543                   the year. Default is 1st January.
  1544                   
  1545 @return The day number in the year. The first day in the year is day one.
  1546 */
  1547 	{
  1548 
  1549 	TInt y=DateTime().Year();
  1550 	TMonth m=aStartDate.DateTime().Month();
  1551 	TInt d=aStartDate.DateTime().Day();
  1552     if (d>=Time::DaysInMonth(y,m))
  1553         d=27;
  1554     TDateTime yearStart(y,m,d,0,0,0,0);              // LEAP YEAR PROBLEMS ???
  1555 	aStartDate=yearStart;
  1556 	if (aStartDate>*this)
  1557 		{
  1558 		yearStart.SetYearLeapCheck(y-1);
  1559 		aStartDate=yearStart;
  1560 		}
  1561     return((DaysFrom(aStartDate).Int())+1) ;
  1562     }
  1563 
  1564 EXPORT_C TInt TTime::WeekNoInYear() const
  1565 /**
  1566 Gets the number of the current week in the year.
  1567 
  1568 @return Week number in the year.
  1569 */
  1570 	{
  1571 
  1572 	return(WeekNoInYear(EFirstFourDayWeek));
  1573 	}
  1574 
  1575 EXPORT_C TInt TTime::WeekNoInYear(TTime aStartDate) const
  1576 /**
  1577 Gets the number of the current week in the year when the year starts
  1578 on aStartDate. 
  1579 
  1580 @param aStartDate If specified, indicates the date which is to be considered 
  1581                   the start of the year. Default is 1st January.
  1582                   
  1583 @return Week number in the year.
  1584 */
  1585 	{
  1586     
  1587     return(WeekNoInYear(aStartDate,EFirstFourDayWeek));
  1588 	}
  1589 
  1590 EXPORT_C TInt TTime::WeekNoInYear(TFirstWeekRule aRule) const
  1591 /**
  1592 Finds the number of the current week in the year using the first week rule 
  1593 specified in aRule. 
  1594 
  1595 @param aRule Determines how the first week in the year is to be calculated. 
  1596              By default EFirstFourDayWeek.
  1597              
  1598 @return Week number in the year.
  1599 */
  1600 	{
  1601 	
  1602 	TInt year=DateTime().Year();
  1603 	TTime startDate=TDateTime(year,EJanuary,0,0,0,0,0);
  1604 	return(WeekNoInYear(startDate,aRule));
  1605 	}
  1606 
  1607 EXPORT_C TInt TTime::WeekNoInYear(TTime aStartDate,TFirstWeekRule aRule) const
  1608 //
  1609 // number of weeks between aTime and aStartDate according to given rule
  1610 // the first week starts either on the week containing the first day (EFirstWeek), 
  1611 // the first week having at least four days within the new year (EFirstFourDayWeek,
  1612 //  default) or the first full week in the year (EFirstFullWeek)
  1613 //
  1614 /**
  1615 Finds the number of the current week in the year when the year starts from 
  1616 aStartDate and when using the start week rule aRule.
  1617 
  1618 @param aStartDate If specified, indicates the date which is to be considered 
  1619                   the start of the year. Default is 1st January.
  1620 @param aRule      Determines how the first week in the year is to be
  1621                   calculated. By default EFirstFourDayWeek.
  1622                   
  1623 @return Week number in the year.
  1624 */
  1625 	{                    
  1626 	TInt dayNoInWeek=DayNoInWeek();
  1627 	TInt dayNoInYear=(DayNoInYear(aStartDate))-1;    // puts start into correct year
  1628 	TDateTime startDateTime(aStartDate.DateTime());
  1629 	TDateTime nextYearStartDate(startDateTime);
  1630 	nextYearStartDate.SetYearLeapCheck(DateTime().Year());    // find start of next year
  1631 	TTime nextYearStartTime(nextYearStartDate);            // makes sure start date for year
  1632 	if (*this>nextYearStartTime)                           // is in the very next year
  1633 		{
  1634 		nextYearStartDate.SetYearLeapCheck(nextYearStartDate.Year()+1);
  1635 		nextYearStartTime=nextYearStartDate;
  1636 		}
  1637 	nextYearStartTime+=TTimeIntervalMicroSeconds(KDaysToMicroSeconds-1); // avoid problems if the time is not midnight
  1638 	TLocale local;
  1639 	TDay startOfFirstWeek=local.StartOfWeek();
  1640 	// calculate the day-in-week number (0 to 6) based on the locale start-of-week
  1641 	dayNoInWeek -= startOfFirstWeek;
  1642 	if (dayNoInWeek < 0)
  1643 		dayNoInWeek += 7;
  1644 	// calculate the days from the start-of-week to the start-of-next-year
  1645 	TInt daysFrom=nextYearStartTime.DaysFrom(*this).Int()+dayNoInWeek;
  1646 	// calculate the days from start-of-year to start-of-week (note this may be negative, but never < -6)
  1647 	TInt days=dayNoInYear-dayNoInWeek;
  1648 
  1649 	// the rule allows a certain number of week-1 days to lie in the previous year
  1650 	TInt prevyeardays;
  1651 	switch (aRule)
  1652 		{
  1653 	default:
  1654 		return -1;
  1655 	case EFirstWeek:
  1656 		prevyeardays = 6;
  1657 		break;
  1658 	case EFirstFourDayWeek:
  1659 		prevyeardays = 3;
  1660 		break;
  1661 	case EFirstFullWeek:
  1662 		prevyeardays = 0;
  1663 		break;
  1664 		}
  1665 
  1666 	// check for a week which belongs to last year
  1667 	if (days + prevyeardays < 0)
  1668 		{
  1669 		// in week 52 or 53 of last year, find the week # of the first day in the week
  1670 		startDateTime.SetYearLeapCheck(startDateTime.Year()-1);
  1671 		return (*this-TTimeIntervalDays(dayNoInWeek)).WeekNoInYear(TTime(startDateTime),aRule);
  1672 		}
  1673 
  1674 	// check for a week which belongs to next year
  1675 	if (daysFrom <= prevyeardays)
  1676 		return 1;
  1677 
  1678 	// calculate the week number, accounting for the requested week-1 rule
  1679 	return (days + 7 + prevyeardays)/7;
  1680 	}
  1681 
  1682 EXPORT_C void TTime::FormatL(TDes &aDes,const TDesC &aFormat) const
  1683 //
  1684 // Fill aString with current Date and Time according to given aFormat string
  1685 //
  1686 /**
  1687 Puts this TTime into a descriptor and formats it according to the format string 
  1688 specified in the second argument.
  1689 
  1690 Many of the formatting commands use the 
  1691 system's locale settings for the date and time, for example the characters 
  1692 used to separate components of the date and time and the ordering of day, 
  1693 month and year. The list of formatting commands below is divided into two 
  1694 sections, the first of which lists the commands which operate without reference 
  1695 to the locale's date and time settings (see class TLocale) and the second 
  1696 table lists the commands which do use these settings.
  1697 
  1698 The following formatting commands do not honour the locale-specific system 
  1699 settings:
  1700 
  1701 \%\% : Include a single '%' character in the string
  1702 
  1703 \%* : Abbreviate following item (the following item should not be preceded 
  1704 by a '%' character).
  1705 
  1706 \%C : Interpret the argument as the six digit microsecond component of the 
  1707 time. In its abbreviated form, ('%*C') this should be followed by an integer 
  1708 between zero and six, where the integer indicates the number of digits to display.
  1709 
  1710 \%D : Interpret the argument as the two digit day number in the month. Abbreviation 
  1711 suppresses leading zero.
  1712 
  1713 \%E : Interpret the argument as the day name. Abbreviation is language-specific 
  1714 (e.g. English uses the first three letters).
  1715 
  1716 \%F : Use this command for locale-independent ordering of date components. 
  1717 This orders the following day/month/year component(s) (\%D, \%M, \%Y for example) 
  1718 according to the order in which they are specified in the string. This removes 
  1719 the need to use \%1 to \%5 (described below).
  1720 
  1721 \%H : Interpret the argument as the one or two digit hour component of the 
  1722 time in 24 hour time format. Abbreviation suppresses leading zero. For locale-dependent 
  1723 hour formatting, use \%J.
  1724 
  1725 \%I : Interpret the argument as the one or two digit hour component of the 
  1726 time in 12 hour time format. The leading zero is automatically suppressed 
  1727 so that abbreviation has no effect. For locale-dependent hour formatting, 
  1728 use \%J.
  1729 
  1730 \%M : Interpret the argument as the one or two digit month number. Abbreviation 
  1731 suppresses leading zero.
  1732 
  1733 \%N : Interpret the argument as the month name. Abbreviation is language specific, e.g. 
  1734 English uses the first three letters only. When using locale-dependent formatting, 
  1735 (that is, \%F has not previously been specified), specifying \%N causes any 
  1736 subsequent occurrence of a month specifier in the string to insert the month 
  1737 as text rather than in numeric form. When using locale-independent formatting, 
  1738 specifying \%N causes the month to be inserted as text at that position, but 
  1739 any subsequent occurrence of \%M will cause the month to be inserted in numeric 
  1740 form.
  1741 
  1742 \%S : Interpret the argument as the one or two digit seconds component of the 
  1743 time. Abbreviation suppresses leading zero.
  1744 
  1745 \%T : Interpret the argument as the one or two digit minutes component of the 
  1746 time. Abbreviation suppresses leading zero.
  1747 
  1748 \%W : Interpret the argument as the one or two digit week number in year. Abbreviation 
  1749 suppresses leading zero.
  1750 
  1751 \%X : Interpret the argument as the date suffix. Cannot be abbreviated. When 
  1752 using locale-dependent formatting (that is, \%F has not previously been specified), 
  1753 \%X causes all further occurrences of the day number to be displayed with the 
  1754 date suffix. When using locale-independent formatting, a date suffix will 
  1755 be inserted only after the occurrence of the day number which \%X follows in 
  1756 the format string. Any further occurrence of \%D without a following \%X will 
  1757 insert the day number without a suffix.
  1758 
  1759 \%Y : Interpret the argument as the four digit year number. Abbreviation suppresses 
  1760 the first two digits.
  1761 
  1762 \%Z : Interpret the argument as the one, two or three digit day number in the 
  1763 year. Abbreviation suppresses leading zeros.
  1764 
  1765 The following formatting commands do honour the locale-specific system settings:
  1766 
  1767 \%. : Interpret the argument as the decimal separator character (as set by 
  1768 TLocale::SetDecimalSeparator()). The decimal separator is used to separate 
  1769 seconds and microseconds, if present.
  1770 
  1771 \%: : Interpret the argument as one of the four time separator characters (as 
  1772 set by TLocale::SetTimeSeparator()). Must be followed by an integer between 
  1773 zero and three inclusive to indicate which time separator character is being 
  1774 referred to.
  1775 
  1776 \%/ : Interpret the argument as one of the four date separator characters (as 
  1777 set by TLocale::SetDateSeparator()). Must be followed by an integer between 
  1778 zero and three inclusive to indicate which date separator character is being 
  1779 referred to.
  1780 
  1781 \%1 : Interpret the argument as the first component of a three component date 
  1782 (i.e. day, month or year) where the order has been set by TLocale::SetDateFormat(). 
  1783 When the date format is EDateEuropean, this is the day, when EDateAmerican, 
  1784 the month, and when EDateJapanese, the year. For more information on this 
  1785 and the following four formatting commands, see the Notes section immediately 
  1786 below.
  1787 
  1788 \%2 : Interpret the argument as the second component of a three component date 
  1789 where the order has been set by TLocale::SetDateFormat(). When the date format 
  1790 is EDateEuropean, this is the month, when EDateAmerican, the day and when 
  1791 EDateJapanese, the month.
  1792 
  1793 \%3 : Interpret the argument as the third component of a three component date 
  1794 where the order has been set by TLocale::SetDateFormat(). When the date format 
  1795 is EDateEuropean, or EDateAmerican this is the year and when EDateJapanese, 
  1796 the day.
  1797 
  1798 \%4 : Interpret the argument as the first component of a two component date 
  1799 (day and month) where the order has been set by TLocale::SetDateFormat(). 
  1800 When the date format is EDateEuropean this is the day, and when EDateAmerican 
  1801 or EDateJapanese, the month.
  1802 
  1803 \%5 : Interpret the argument as the second component of a two component date 
  1804 (day and month) where the order has been set by TLocale::SetDateFormat(). 
  1805 When the date format is EDateEuropean this is the month, and when EDateAmerican 
  1806 or EDateJapanese, the day.
  1807 
  1808 \%A : Interpret the argument as "am" or "pm" text according to the current 
  1809 language and time of day. Unlike the \%B formatting command (described below), 
  1810 \%A disregards the locale's 12 or 24 hour clock setting, so that when used 
  1811 without an inserted + or - sign, am/pm text will always be displayed. Whether 
  1812 a space is inserted between the am/pm text and the time depends on the locale-specific 
  1813 settings. However, if abbreviated (\%*A), no space is inserted, regardless 
  1814 of the locale's settings. The am/pm text appears before or after the time, 
  1815 according to the position of the \%A, regardless of the locale-specific settings. 
  1816 For example, the following ordering of formatting commands causes am/pm text 
  1817 to be printed after the time: \%H \%T \%S \%A. Optionally, a minus or plus sign 
  1818 may be inserted between the "%" and the "A". This operates as follows:
  1819 
  1820 \%-A causes am/pm text to be inserted into the descriptor only if the am/pm 
  1821 symbol position has been set in the locale to ELocaleBefore. Cannot be abbreviated 
  1822 using asterisk.
  1823 
  1824 \%+A causes am/pm text to be inserted into the descriptor only if the am/pm 
  1825 symbol position has been set in the locale to ELocaleAfter. Cannot be abbreviated 
  1826 using asterisk. For example, the following formatting commands will cause 
  1827 am/pm text to be displayed after the time if the am/pm position has been set 
  1828 in the locale to ELocaleAfter or before the time if ELocaleBefore: \%-A \%H 
  1829 \%T \%S \%+A.
  1830 
  1831 \%B Interpret the argument as am or pm text according to the current language 
  1832 and time of day. Unlike the \%A command, when using \%B, am/pm text is displayed 
  1833 only if the clock setting in the locale is 12-hour. Whether a space is inserted 
  1834 between the am/pm text and the time depends on the locale-specific settings. 
  1835 However, if abbreviated (\%*B), no space is inserted, regardless of the locale's 
  1836 settings. The am/pm text appears before or after the time, according to the 
  1837 location of the "%B", regardless of the locale-specific settings. For example, 
  1838 the following formatting commands cause am/pm text to be printed after the 
  1839 time: \%H \%T \%S \%B. Optionally, a minus or plus sign may be inserted between 
  1840 the "%" and the "B". This operates as follows:
  1841 
  1842 \%-B causes am/pm text to be inserted into the descriptor only if using a 12 
  1843 hour clock and the am/pm symbol position has been set in the locale to ELocaleBefore. 
  1844 Cannot be abbreviated using asterisk.
  1845 
  1846 \%+B causes am/pm text to be inserted into the descriptor only if using a 12 
  1847 hour clock and the am/pm symbol position has been set in the locale to ELocaleAfter. 
  1848 Cannot be abbreviated using asterisk. For example, the following formatting 
  1849 commands cause am/pm text to be printed after the time if the am/pm position 
  1850 has been set in the locale to ELocaleAfter or before the time if ELocaleBefore: 
  1851 \%-B \%H \%T \%S \%+B.
  1852 
  1853 \%J Interpret the argument as the hour component of the time in either 12 or 
  1854 24 hour clock format depending on the locale's clock format setting. When 
  1855 the clock format has been set to 12 hour, leading zeros are automatically 
  1856 suppressed so that abbreviation has no effect. Abbreviation suppresses leading 
  1857 zero only when using a 24 hour clock.
  1858 
  1859 Notes:
  1860 
  1861 The \%1, \%2, \%3, \%4 and \%5 formatting commands are used in conjunction with 
  1862 \%D, \%M and \%Y to format the date locale-dependently. When formatting the date 
  1863 locale-dependently, the order of the day, month and year components within 
  1864 the string is determined by the order of the \%1 to \%5 formatting commands, 
  1865 not that of \%D, \%M, \%Y.
  1866 
  1867 When formatting the date locale-independently (that is, \%F has been specified 
  1868 in the format string), the \%1 to \%5 formatting commands are not required, 
  1869 and should be omitted. In this case, the order of the date components is determined 
  1870 by the order of the \%D, \%M, \%Y format commands within aFormat.
  1871 
  1872 Up to four date separators and up to four time separators can be used to separate 
  1873 the components of a date or time. When formatting a numerical date consisting 
  1874 of the day, month and year or a time containing hours, minutes and seconds, 
  1875 all four separators should always be specified in the format command string. 
  1876 Usually, the leading and trailing separators should not be displayed. In this 
  1877 case, the first and fourth separators should still be specified, but should 
  1878 be represented by a null character.
  1879 
  1880 The date format follows the pattern:
  1881 
  1882 DateSeparator[0] DateComponent1 DateSeparator[1] DateComponent2 DateSeparator[2] 
  1883 DateComponent3 DateSeparator[3]
  1884 
  1885 where the ordering of date components is determined by the locale's date format 
  1886 setting.
  1887 
  1888 The time format follows the pattern:
  1889 
  1890 TimeSeparator[0] Hours TimeSeparator[1] Minutes TimeSeparator[2] Seconds TimeSeparator[3]
  1891 
  1892 If the time includes a microseconds component, the third separator should 
  1893 occur after the microseconds, and the seconds and microseconds should be separated 
  1894 by the decimal separator. When formatting a two component time, the following 
  1895 rules apply:
  1896 
  1897 if the time consists of hours and minutes, the third time delimiter should 
  1898 be omitted 
  1899 
  1900 if the time consists of minutes and seconds, the second time delimiter should 
  1901 be omitted
  1902 
  1903 @param aDes    Descriptor, which,  on return contains the formatted date/time string.
  1904 @param aFormat Format string which determines the format of the date and time.
  1905 
  1906 @leave KErrOverflow The date/time string is too long for the descriptor aDes.
  1907 @leave KErrGeneral  A formatting error has occurred.
  1908 */
  1909 	{
  1910 	TLocale local;
  1911 	FormatL(aDes,aFormat,local);
  1912 	}
  1913 
  1914 EXPORT_C void TTime::FormatL(TDes &aDes,const TDesC &aFormat,const TLocale &aLocale) const
  1915 //
  1916 // Fill aString with current Date and Time according to given aFormat string
  1917 //
  1918 /**
  1919 Puts this TTime into a descriptor and formats it according to the format string 
  1920 specified in the second argument.
  1921 
  1922 Many of the formatting commands use the 
  1923 system's locale settings for the date and time, for example the characters 
  1924 used to separate components of the date and time and the ordering of day, 
  1925 month and year. The list of formatting commands below is divided into two 
  1926 sections, the first of which lists the commands which operate without reference 
  1927 to the locale's date and time settings (see class TLocale) and the second 
  1928 table lists the commands which do use these settings.
  1929 
  1930 The following formatting commands do not honour the locale-specific system 
  1931 settings:
  1932 
  1933 \%\% : Include a single '%' character in the string
  1934 
  1935 \%* : Abbreviate following item (the following item should not be preceded 
  1936 by a '%' character).
  1937 
  1938 \%C : Interpret the argument as the six digit microsecond component of the 
  1939 time. In its abbreviated form, ('%*C') this should be followed by an integer 
  1940 between zero and six, where the integer indicates the number of digits to display.
  1941 
  1942 \%D : Interpret the argument as the two digit day number in the month. Abbreviation 
  1943 suppresses leading zero.
  1944 
  1945 \%E : Interpret the argument as the day name. Abbreviation is language-specific 
  1946 (e.g. English uses the first three letters).
  1947 
  1948 \%F : Use this command for locale-independent ordering of date components. 
  1949 This orders the following day/month/year component(s) (\%D, \%M, \%Y for example) 
  1950 according to the order in which they are specified in the string. This removes 
  1951 the need to use \%1 to \%5 (described below).
  1952 
  1953 \%H : Interpret the argument as the one or two digit hour component of the 
  1954 time in 24 hour time format. Abbreviation suppresses leading zero. For locale-dependent 
  1955 hour formatting, use \%J.
  1956 
  1957 \%I : Interpret the argument as the one or two digit hour component of the 
  1958 time in 12 hour time format. The leading zero is automatically suppressed 
  1959 so that abbreviation has no effect. For locale-dependent hour formatting, 
  1960 use \%J.
  1961 
  1962 \%M : Interpret the argument as the one or two digit month number. Abbreviation 
  1963 suppresses leading zero.
  1964 
  1965 \%N : Interpret the argument as the month name. Abbreviation is language specific, e.g. 
  1966 English uses the first three letters only. When using locale-dependent formatting, 
  1967 (that is, \%F has not previously been specified), specifying \%N causes any 
  1968 subsequent occurrence of a month specifier in the string to insert the month 
  1969 as text rather than in numeric form. When using locale-independent formatting, 
  1970 specifying \%N causes the month to be inserted as text at that position, but 
  1971 any subsequent occurrence of \%M will cause the month to be inserted in numeric 
  1972 form.
  1973 
  1974 \%S : Interpret the argument as the one or two digit seconds component of the 
  1975 time. Abbreviation suppresses leading zero.
  1976 
  1977 \%T : Interpret the argument as the one or two digit minutes component of the 
  1978 time. Abbreviation suppresses leading zero.
  1979 
  1980 \%W : Interpret the argument as the one or two digit week number in year. Abbreviation 
  1981 suppresses leading zero.
  1982 
  1983 \%X : Interpret the argument as the date suffix. Cannot be abbreviated. When 
  1984 using locale-dependent formatting (that is, \%F has not previously been specified), 
  1985 \%X causes all further occurrences of the day number to be displayed with the 
  1986 date suffix. When using locale-independent formatting, a date suffix will 
  1987 be inserted only after the occurrence of the day number which \%X follows in 
  1988 the format string. Any further occurrence of \%D without a following \%X will 
  1989 insert the day number without a suffix.
  1990 
  1991 \%Y : Interpret the argument as the four digit year number. Abbreviation suppresses 
  1992 the first two digits.
  1993 
  1994 \%Z : Interpret the argument as the one, two or three digit day number in the 
  1995 year. Abbreviation suppresses leading zeros.
  1996 
  1997 The following formatting commands do honour the locale-specific system settings:
  1998 
  1999 \%. : Interpret the argument as the decimal separator character (as set by 
  2000 TLocale::SetDecimalSeparator()). The decimal separator is used to separate 
  2001 seconds and microseconds, if present.
  2002 
  2003 \%: : Interpret the argument as one of the four time separator characters (as 
  2004 set by TLocale::SetTimeSeparator()). Must be followed by an integer between 
  2005 zero and three inclusive to indicate which time separator character is being 
  2006 referred to.
  2007 
  2008 \%/ : Interpret the argument as one of the four date separator characters (as 
  2009 set by TLocale::SetDateSeparator()). Must be followed by an integer between 
  2010 zero and three inclusive to indicate which date separator character is being 
  2011 referred to.
  2012 
  2013 \%1 : Interpret the argument as the first component of a three component date 
  2014 (i.e. day, month or year) where the order has been set by TLocale::SetDateFormat(). 
  2015 When the date format is EDateEuropean, this is the day, when EDateAmerican, 
  2016 the month, and when EDateJapanese, the year. For more information on this 
  2017 and the following four formatting commands, see the Notes section immediately 
  2018 below.
  2019 
  2020 \%2 : Interpret the argument as the second component of a three component date 
  2021 where the order has been set by TLocale::SetDateFormat(). When the date format 
  2022 is EDateEuropean, this is the month, when EDateAmerican, the day and when 
  2023 EDateJapanese, the month.
  2024 
  2025 \%3 : Interpret the argument as the third component of a three component date 
  2026 where the order has been set by TLocale::SetDateFormat(). When the date format 
  2027 is EDateEuropean, or EDateAmerican this is the year and when EDateJapanese, 
  2028 the day.
  2029 
  2030 \%4 : Interpret the argument as the first component of a two component date 
  2031 (day and month) where the order has been set by TLocale::SetDateFormat(). 
  2032 When the date format is EDateEuropean this is the day, and when EDateAmerican 
  2033 or EDateJapanese, the month.
  2034 
  2035 \%5 : Interpret the argument as the second component of a two component date 
  2036 (day and month) where the order has been set by TLocale::SetDateFormat(). 
  2037 When the date format is EDateEuropean this is the month, and when EDateAmerican 
  2038 or EDateJapanese, the day.
  2039 
  2040 \%A : Interpret the argument as "am" or "pm" text according to the current 
  2041 language and time of day. Unlike the \%B formatting command (described below), 
  2042 \%A disregards the locale's 12 or 24 hour clock setting, so that when used 
  2043 without an inserted + or - sign, am/pm text will always be displayed. Whether 
  2044 a space is inserted between the am/pm text and the time depends on the locale-specific 
  2045 settings. However, if abbreviated (\%*A), no space is inserted, regardless 
  2046 of the locale's settings. The am/pm text appears before or after the time, 
  2047 according to the position of the \%A, regardless of the locale-specific settings. 
  2048 For example, the following ordering of formatting commands causes am/pm text 
  2049 to be printed after the time: \%H \%T \%S \%A. Optionally, a minus or plus sign 
  2050 may be inserted between the "%" and the "A". This operates as follows:
  2051 
  2052 \%-A causes am/pm text to be inserted into the descriptor only if the am/pm 
  2053 symbol position has been set in the locale to ELocaleBefore. Cannot be abbreviated 
  2054 using asterisk.
  2055 
  2056 \%+A causes am/pm text to be inserted into the descriptor only if the am/pm 
  2057 symbol position has been set in the locale to ELocaleAfter. Cannot be abbreviated 
  2058 using asterisk. For example, the following formatting commands will cause 
  2059 am/pm text to be displayed after the time if the am/pm position has been set 
  2060 in the locale to ELocaleAfter or before the time if ELocaleBefore: \%-A \%H 
  2061 \%T \%S \%+A.
  2062 
  2063 \%B Interpret the argument as am or pm text according to the current language 
  2064 and time of day. Unlike the \%A command, when using \%B, am/pm text is displayed 
  2065 only if the clock setting in the locale is 12-hour. Whether a space is inserted 
  2066 between the am/pm text and the time depends on the locale-specific settings. 
  2067 However, if abbreviated (\%*B), no space is inserted, regardless of the locale's 
  2068 settings. The am/pm text appears before or after the time, according to the 
  2069 location of the "%B", regardless of the locale-specific settings. For example, 
  2070 the following formatting commands cause am/pm text to be printed after the 
  2071 time: \%H \%T \%S \%B. Optionally, a minus or plus sign may be inserted between 
  2072 the "%" and the "B". This operates as follows:
  2073 
  2074 \%-B causes am/pm text to be inserted into the descriptor only if using a 12 
  2075 hour clock and the am/pm symbol position has been set in the locale to ELocaleBefore. 
  2076 Cannot be abbreviated using asterisk.
  2077 
  2078 \%+B causes am/pm text to be inserted into the descriptor only if using a 12 
  2079 hour clock and the am/pm symbol position has been set in the locale to ELocaleAfter. 
  2080 Cannot be abbreviated using asterisk. For example, the following formatting 
  2081 commands cause am/pm text to be printed after the time if the am/pm position 
  2082 has been set in the locale to ELocaleAfter or before the time if ELocaleBefore: 
  2083 \%-B \%H \%T \%S \%+B.
  2084 
  2085 \%J Interpret the argument as the hour component of the time in either 12 or 
  2086 24 hour clock format depending on the locale's clock format setting. When 
  2087 the clock format has been set to 12 hour, leading zeros are automatically 
  2088 suppressed so that abbreviation has no effect. Abbreviation suppresses leading 
  2089 zero only when using a 24 hour clock.
  2090 
  2091 Notes:
  2092 
  2093 The \%1, \%2, \%3, \%4 and \%5 formatting commands are used in conjunction with 
  2094 \%D, \%M and \%Y to format the date locale-dependently. When formatting the date 
  2095 locale-dependently, the order of the day, month and year components within 
  2096 the string is determined by the order of the \%1 to \%5 formatting commands, 
  2097 not that of \%D, \%M, \%Y.
  2098 
  2099 When formatting the date locale-independently (that is, \%F has been specified 
  2100 in the format string), the \%1 to \%5 formatting commands are not required, 
  2101 and should be omitted. In this case, the order of the date components is determined 
  2102 by the order of the \%D, \%M, \%Y format commands within aFormat.
  2103 
  2104 Up to four date separators and up to four time separators can be used to separate 
  2105 the components of a date or time. When formatting a numerical date consisting 
  2106 of the day, month and year or a time containing hours, minutes and seconds, 
  2107 all four separators should always be specified in the format command string. 
  2108 Usually, the leading and trailing separators should not be displayed. In this 
  2109 case, the first and fourth separators should still be specified, but should 
  2110 be represented by a null character.
  2111 
  2112 The date format follows the pattern:
  2113 
  2114 DateSeparator[0] DateComponent1 DateSeparator[1] DateComponent2 DateSeparator[2] 
  2115 DateComponent3 DateSeparator[3]
  2116 
  2117 where the ordering of date components is determined by the locale's date format 
  2118 setting.
  2119 
  2120 The time format follows the pattern:
  2121 
  2122 TimeSeparator[0] Hours TimeSeparator[1] Minutes TimeSeparator[2] Seconds TimeSeparator[3]
  2123 
  2124 If the time includes a microseconds component, the third separator should 
  2125 occur after the microseconds, and the seconds and microseconds should be separated 
  2126 by the decimal separator. When formatting a two component time, the following 
  2127 rules apply:
  2128 
  2129 if the time consists of hours and minutes, the third time delimiter should 
  2130 be omitted 
  2131 
  2132 if the time consists of minutes and seconds, the second time delimiter should 
  2133 be omitted
  2134 
  2135 @param aDes    Descriptor, which,  on return contains the formatted date/time string.
  2136 @param aFormat Format string which determines the format of the date and time.
  2137 @param aLocale Specific locale which formatting will be based on.
  2138 
  2139 @leave KErrOverflow The date/time string is too long for the descriptor aDes.
  2140 @leave KErrGeneral  A formatting error has occurred.
  2141 */
  2142 	{
  2143 
  2144 	TDateTime dateTime=DateTime();
  2145 	aDes.Zero(); // ensure string is empty at start
  2146 
  2147  	TLex aFmt(aFormat);
  2148 	TBool fix=EFalse; // fixed date format
  2149 	TBool da=EFalse; // day unabreviated
  2150 	TBool ma=EFalse; // month unabreviated
  2151 	TBool ya=EFalse; // year unabreviated
  2152 	TBool suff=EFalse; // default no suffix
  2153 	TBool mnam=EFalse; // default month as a number
  2154 	TTimeOverflowLeave overflowLeave;
  2155 
  2156    	while (!aFmt.Eos())
  2157 		{
  2158 		TChar ch=aFmt.Get();
  2159 		TBool abb=EFalse;
  2160 		const TInt NoPosSpecified=-1;
  2161 		TInt pos=NoPosSpecified;
  2162 		if (ch=='%')
  2163 			ch=aFmt.Get();
  2164 		else // not formatting,just want to add some characters to string
  2165 			goto doAppend; 
  2166 		if (ch=='*') // => abbreviate next field
  2167 			{
  2168 			abb=ETrue;
  2169 			ch=aFmt.Get();
  2170 			}
  2171 		else if (ch=='+' || ch=='-') // => leading or following Am/Pm
  2172 			{
  2173 			pos= ((ch=='+') ? ELocaleAfter : ELocaleBefore);
  2174 			ch=aFmt.Get();
  2175 			if (ch!='A' && ch!='B')
  2176 				User::Leave(KErrGeneral);
  2177 			}
  2178 		switch (ch)
  2179 			{
  2180 		case ':': // local time separator
  2181 				{
  2182 				if (aDes.Length()==aDes.MaxLength())
  2183 					User::Leave(KErrOverflow);
  2184 				ch=aFmt.Get();//Which separator?
  2185 				if (ch<'0' || ch>='0'+KMaxTimeSeparators)
  2186 					User::Leave(KErrGeneral);
  2187 				ch-='0';
  2188 				TChar separator=aLocale.TimeSeparator(ch);
  2189 				if (separator!=0)
  2190 					aDes.Append(separator);
  2191 				}
  2192 			break;
  2193 		case '/': // local date separator
  2194 				{
  2195 				if (aDes.Length()==aDes.MaxLength())
  2196 					User::Leave(KErrOverflow);
  2197 				ch=aFmt.Get();//Which separator?
  2198 				if (ch<'0' || ch>='0'+KMaxDateSeparators)
  2199 					User::Leave(KErrGeneral);
  2200 				ch-='0';
  2201 				TChar separator=aLocale.DateSeparator(ch);
  2202 				if (separator!=0)
  2203 					aDes.Append(separator);
  2204 				}
  2205 			break;
  2206 		case '.': // local decimal separator
  2207 				{
  2208 				if (aDes.Length()==aDes.MaxLength())
  2209 					User::Leave(KErrOverflow);
  2210 				aDes.Append(aLocale.DecimalSeparator());
  2211 				}
  2212 			break;
  2213 		case '1': // 1st element of date,local order
  2214 			switch (aLocale.DateFormat())
  2215 				{
  2216 			case EDateAmerican:
  2217 				goto doMonth;
  2218 			case EDateJapanese:
  2219 				goto doYear;
  2220 			default: // European
  2221 				goto doDay;
  2222 				}
  2223 		case '2': // 2nd element of date,local order
  2224 			switch (aLocale.DateFormat())
  2225 				{
  2226 			case EDateAmerican:
  2227 				goto doDay;
  2228 			default: // European and Japanese have month second
  2229 				goto doMonth;
  2230 				}
  2231 		case '3': // 3rd element of date,local order
  2232 			switch (aLocale.DateFormat())
  2233 				{
  2234 			case EDateJapanese:
  2235 				goto doDay;
  2236 			default: // European and American have year last
  2237 				goto doYear;
  2238 				}
  2239 		case '4': // 1st element of date (no year),local order
  2240 			switch (aLocale.DateFormat())
  2241 				{
  2242 			case EDateEuropean:
  2243 				goto doDay;
  2244 			default:
  2245 				goto doMonth;
  2246 				}
  2247 		case '5': // 2nd element of date (no year),local order
  2248 			switch (aLocale.DateFormat())
  2249 				{
  2250 			case EDateEuropean:
  2251 				goto doMonth;
  2252 			default:
  2253 				goto doDay;
  2254 				}
  2255 		case 'A': // am/pm text
  2256 doAmPm:
  2257             {
  2258             if (pos==NoPosSpecified || pos==aLocale.AmPmSymbolPosition())
  2259 				{
  2260 				TBuf<KMaxAmPmName+1> format(_S("%S"));
  2261 				if (!abb && aLocale.AmPmSpaceBetween())
  2262 					{
  2263 					if (aLocale.AmPmSymbolPosition()==ELocaleBefore)
  2264 						format.Append(' ');
  2265 					else
  2266 						{
  2267 						if (aDes.Length()==aDes.MaxLength())
  2268 							User::Leave(KErrOverflow);
  2269 						aDes.Append(' ');
  2270 						}
  2271 					}
  2272 				TAmPmName amPm((dateTime.Hour()<12) ? EAm : EPm);
  2273 				aDes.AppendFormat(format,&overflowLeave,&amPm);
  2274 				}
  2275 			break;
  2276             }
  2277 		case 'B': // am/pm text if local time format is 12 hour clock
  2278 			if (aLocale.TimeFormat()==ETime24)
  2279 				break;
  2280 			else
  2281 				goto doAmPm;
  2282 		case 'C':
  2283 			{
  2284 			TBuf<6> digits;
  2285 			digits.AppendFormat(_L("%06d"),dateTime.MicroSecond());
  2286 			TUint numChars=6;	// Default length
  2287 			if (abb)
  2288 				{
  2289 				ch=aFmt.Get();
  2290 				if (ch>='0' && ch<='6')
  2291 					{
  2292 					numChars=ch;
  2293 					numChars-='0';
  2294 					}
  2295 				}
  2296 			if (aDes.Length()>(TInt)(aDes.MaxLength()-numChars))
  2297 			    User::Leave(KErrOverflow);
  2298 			aDes.Append(digits.Left(numChars));
  2299 			}	
  2300 			break;
  2301 		case 'D': // day in date
  2302 			if (abb)
  2303 				da=ETrue;
  2304 			if (!fix)
  2305 				break;
  2306 			else
  2307 				{
  2308 doDay:
  2309 				aDes.AppendFormat((da||abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Day()+1);
  2310 				if (suff)
  2311 doSuffix:
  2312                     {
  2313                     TDateSuffix day(dateTime.Day());
  2314 					aDes.AppendFormat(_L("%S"),&overflowLeave,&day);
  2315                     }
  2316 				break;
  2317 				}
  2318 		case 'E': // Day name
  2319             {
  2320 			TDay day=DayNoInWeek();
  2321 			if (abb)
  2322 				{
  2323 	            TDayNameAbb nameAbb(day);
  2324 				aDes.AppendFormat(_L("%S"),&overflowLeave,&nameAbb);
  2325 				}
  2326 			else
  2327 				{
  2328 	            TDayName name(day);
  2329 				aDes.AppendFormat(_L("%S"),&overflowLeave,&name);
  2330 				}
  2331 			break;
  2332             }
  2333 		case 'F': // => user wants day,month,year order fixed
  2334 			fix=ETrue;
  2335 			break;
  2336 		case 'H': // hour in 24 hour time format
  2337 do24:
  2338 			aDes.AppendFormat((abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Hour());
  2339 			break;
  2340 		case 'I': // hour in 12 hour time format
  2341 do12:
  2342 			{
  2343 			TInt hour=dateTime.Hour();
  2344 			if (hour==0)
  2345 				hour=12;
  2346 			else if (hour>12)
  2347 				hour-=12;
  2348 			aDes.AppendFormat(_L("%d"),&overflowLeave,hour);
  2349 			break;
  2350 			}
  2351 		case 'J': //default time format for hour
  2352 			if (aLocale.TimeFormat()==ETime12)
  2353 				goto do12;
  2354 			else
  2355 				goto do24;
  2356 		case 'M': // month as a number (default value)
  2357 			if (abb)
  2358 				ma=ETrue;
  2359 			if (fix)
  2360 				goto doMonth;
  2361 			break;
  2362 		case 'N': // month as a name
  2363 			mnam=ETrue;
  2364 			if (abb)
  2365 				ma=ETrue;
  2366 			if (!fix)
  2367 				break;
  2368 			else
  2369 				{
  2370 doMonth:
  2371 				if (mnam)
  2372 					{
  2373 					TMonth month=dateTime.Month();
  2374 					if (ma || abb)
  2375 						{
  2376 		                TMonthNameAbb nameAbb(month);
  2377 						aDes.AppendFormat(_L("%S"),&overflowLeave,&nameAbb);
  2378 						}
  2379 					else
  2380 						{
  2381 	                    TMonthName name(month);
  2382 						aDes.AppendFormat(_L("%S"),&overflowLeave,&name);
  2383 						}
  2384 					}
  2385 				else
  2386 					aDes.AppendFormat((ma||abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Month()+1);
  2387 				break;
  2388 				}
  2389 		case 'S': // seconds
  2390 			aDes.AppendFormat((abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Second());
  2391 			break;	
  2392 		case 'T': // minutes	
  2393 			aDes.AppendFormat((abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Minute());
  2394 			break;
  2395 		case 'W': // week no in year
  2396 			aDes.AppendFormat((abb) ? _L("%d"):_L("%02d"),&overflowLeave,WeekNoInYear());
  2397 			break;
  2398 		case 'X': // => wants day suffix
  2399 			if (fix)
  2400 				goto doSuffix;
  2401 			else
  2402 				{
  2403 				suff=ETrue;
  2404 				break;
  2405 				}
  2406 		case 'Y': // year
  2407 			if (abb)
  2408 				ya=ETrue;
  2409 			if (!fix)
  2410 				break;
  2411 			else
  2412 				{
  2413 doYear:
  2414 				if (ya || abb)
  2415 					aDes.AppendFormat(_L("%02d"),&overflowLeave,((dateTime.Year())%100));
  2416 				else
  2417 					aDes.AppendFormat(_L("%04d"),&overflowLeave,dateTime.Year());
  2418 				break;
  2419 				}
  2420 		case 'Z': // day no in year
  2421 			aDes.AppendFormat((abb) ? _L("%d"):_L("%03d"),&overflowLeave,DayNoInYear());
  2422 			break;
  2423 		default:
  2424 doAppend:
  2425 			if (aDes.Length()==aDes.MaxLength())
  2426 				User::Leave(KErrOverflow);
  2427 			aDes.Append(ch);
  2428 			break;
  2429 			}
  2430 		}
  2431 	}
  2432 
  2433 
  2434 
  2435 
  2436 EXPORT_C TTime Time::NullTTime()
  2437 /**
  2438 Gets a TTime with a null value.
  2439 
  2440 @return TTime object with a null value.
  2441 */
  2442 	{
  2443 	return UI64LIT(0x8000000000000000);
  2444 	}
  2445 
  2446 EXPORT_C TTime Time::MaxTTime()
  2447 /**
  2448 Gets the maximum time value which can be held in a TTime object.
  2449 
  2450 @return The maximum TTime value.
  2451 */
  2452 	{
  2453 	return I64LIT(0x7fffffffffffffff);
  2454 	}
  2455 
  2456 EXPORT_C TTime Time::MinTTime()
  2457 /**
  2458 Gets the minimum time value which can be held in a TTime object.
  2459 
  2460 @return The minimum TTime value.
  2461 */
  2462 	{
  2463 	return UI64LIT(0x8000000000000001);
  2464 	}
  2465 
  2466 EXPORT_C TInt Time::DaysInMonth(TInt aYear,TMonth aMonth)
  2467 /**
  2468 Gets the number of days in a month.
  2469 
  2470 @param aYear  The year. Must be specified because of leap years.
  2471 @param aMonth Month, from EJanuary to EDecember.
  2472 
  2473 @return The number of days in the month.
  2474 */
  2475 	{
  2476 
  2477     __ASSERT_DEBUG(aMonth<=EDecember && aMonth>=EJanuary,::Panic(ETTimeValueOutOfRange));
  2478     return(mTab[IsLeapYear(aYear)][aMonth]);
  2479 	}
  2480 
  2481 EXPORT_C TBool Time::IsLeapYear(TInt aYear)
  2482 //
  2483 // up to and including 1600 leap years were every 4 years,since then leap years are every 4 years unless
  2484 // the year falls on a century which is not divisible by 4 (ie 1900 wasnt,2000 will be)
  2485 // for simplicity define year 0 as a leap year
  2486 //
  2487 /**
  2488 Tests whether a year is a leap year.
  2489 
  2490 @param aYear The year of interest.
  2491 
  2492 @return True if leap year, False if not.
  2493 */
  2494 	{
  2495 
  2496 	if (aYear>1600)
  2497     	return(!(aYear%4) && (aYear%100 || !(aYear%400)));
  2498 	return(!(aYear%4));
  2499 	}
  2500 
  2501 EXPORT_C TInt Time::LeapYearsUpTo(TInt aYear)
  2502 //
  2503 // from 0AD to present year according to the rule above
  2504 //
  2505 /**
  2506 Gets the number of leap years between 0 AD nominal Gregorian and the specified 
  2507 year - inclusive.
  2508 
  2509 @param aYear The final year in the range to search. If negative, the function 
  2510              will return a negative number of leap years.
  2511 
  2512 @return The number of leap years between 0 AD nominal Gregorian and aYear.
  2513 */
  2514 	{
  2515 
  2516 	if (aYear<=0)
  2517 		return(aYear/4);
  2518 	if (aYear<=1600)
  2519 		return(1+((aYear-1)/4));
  2520 	TInt num=401; // 1600/4+1
  2521 	aYear-=1601;
  2522 	TInt century=aYear/100;
  2523 	num+=(aYear/4-century+century/4);
  2524 	return(num);
  2525 	}
  2526