symport/e32/euser/us_time.cpp
changeset 1 0a7b44b10206
child 2 806186ab5e14
equal deleted inserted replaced
0:c55016431358 1:0a7b44b10206
       
     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 "Symbian Foundation License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.symbianfoundation.org/legal/sfl-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 	dateTime.Set(year,TMonth(month),day,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond());
       
   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