--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/euser/us_time.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,2526 @@
+// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\euser\us_time.cpp
+// System date and time functions
+//
+//
+
+
+#include "us_std.h"
+
+// Date and time related constants
+
+static const TInt KMinutesToMicroSeconds = 60000000;
+static const TInt KSecondsToMicroSeconds = 1000000;
+static const TInt64 KDaysToMicroSeconds = I64LIT(86400000000);
+static const TInt64 KHoursToMicroSeconds = I64LIT(3600000000);
+
+// Days in each month
+LOCAL_D const TInt8 mTab[2][12]=
+ {
+ {31,28,31,30,31,30,31,31,30,31,30,31}, // 28 days in Feb
+ {31,29,31,30,31,30,31,31,30,31,30,31} // 29 days in Feb
+ };
+
+// Days in year before 1st of each month
+LOCAL_D const TInt cmTab[2][12]=
+ {
+ {0,31,59,90,120,151,181,212,243,273,304,334},
+ {0,31,60,91,121,152,182,213,244,274,305,335}
+ };
+
+//
+// Time::FormatL overflow handler
+//
+#if defined(_UNICODE)
+NONSHARABLE_CLASS(TTimeOverflowLeave) : public TDes16Overflow
+ {
+public:
+ virtual void Overflow(TDes16 &aDes);
+ };
+void TTimeOverflowLeave::Overflow(TDes16 &/*aDes*/)
+ {
+ User::Leave(KErrOverflow);
+ }
+#else
+NONSHARABLE_CLASS(TTimeOverflowLeave) : public TDes8Overflow
+ {
+public:
+ virtual void Overflow(TDes8 &aDes);
+ };
+void TTimeOverflowLeave::Overflow(TDes8 &/*aDes*/)
+ {
+ User::Leave(KErrOverflow);
+ }
+#endif
+//
+
+EXPORT_C TDateTime::TDateTime(TInt aYear,TMonth aMonth,TInt aDay,TInt aHour,TInt aMinute,TInt aSecond,TInt aMicroSecond)
+//
+// always panic on a bad date/time field
+//
+/**
+Constructs the TDateTime object with the seven fields which comprise a date
+and time.
+
+@param aYear The year. No check is made for validity.
+@param aMonth The month. Range is EJanuary to EDecember.
+@param aDay The day. Range is zero to number of days in month minus one.
+@param aHour The hour. Range is 0 to 23.
+@param aMinute The minute. Range is 0 to 59.
+@param aSecond The second. Range is 0 to 59
+@param aMicroSecond The microsecond. Range is 0 to 999999
+
+@panic USER 3, if an attempt is made to set an invalid value for any of
+ the fields, except for the year. No check is made upon the validity
+ of the year.
+*/
+ {
+
+ TInt ret=Set(aYear,aMonth,aDay,aHour,aMinute,aSecond,aMicroSecond);
+ __ASSERT_ALWAYS(ret==KErrNone,Panic(ETDateTimeBadDateTime));
+ }
+
+EXPORT_C TInt TDateTime::Set(TInt aYear,TMonth aMonth,TInt aDay,TInt aHour,TInt aMinute,TInt aSecond,TInt aMicroSecond)
+//
+// set the various time fields checking that each is valid
+// bomb out as soon as invalid field is set to forestall causing a panic
+//
+/**
+Sets all date and time components.
+
+Note:
+
+1. When setting the day and month, subtract one because the ranges are offset
+ from zero.
+
+2. If the function returns an error, only those fields preceding the field which
+ caused the error will be changed. For example, if the hour is out of range,
+ the year, month and day will be set, all other components will remain unchanged.
+
+@param aYear Year. No check is made on its validity, except that if the
+ date is set to February 29th, the year can only be set to a
+ leap year, otherwise an error is returned.
+@param aMonth Month. The valid range is EJanuary to EDecember. If an
+ attempt is made to set an invalid month, or if the current
+ day number in the month is greater than or equal to the
+ number of days in the new month, an error is returned.
+@param aDay The number of the day within the month, offset from zero.
+ If greater than or equal to the total number of days in
+ the month,an error is returned.
+@param aHour Hour. Range is 0 to 23.
+@param aMinute Minute. Range is 0 to 59.
+@param aSecond Second. Range is 0 to 59.
+@param aMicroSecond Microsecond. Range is 0 to 999999.
+
+@return KErrNone if successful, KErrGeneral if not.
+*/
+ {
+
+ iYear=aYear;
+
+ if (aMonth<EJanuary || aMonth>EDecember)
+ return KErrGeneral;
+ iMonth=aMonth;
+
+ if (aDay<0 || aDay>=Time::DaysInMonth(iYear,iMonth))
+ return KErrGeneral;
+ iDay=aDay;
+
+ if (aHour<0 || aHour>=24)
+ return KErrGeneral;
+ iHour=aHour;
+
+ if (aMinute<0 || aMinute>=60)
+ return KErrGeneral;
+ iMinute=aMinute;
+
+ if (aSecond<0 || aSecond>=60)
+ return KErrGeneral;
+ iSecond=aSecond;
+
+ if (aMicroSecond<0 || aMicroSecond>=1000000)
+ return KErrGeneral;
+ iMicroSecond=aMicroSecond;
+
+ return KErrNone;
+ }
+
+EXPORT_C TInt TDateTime::SetYear(TInt aYear)
+//
+// doesnt let you reset 29th February to non-leap year, no check on year range
+//
+/**
+Sets the year without a leap year check.
+
+No check is made on the validity of the year except that if the current date
+is February 29th, the year can only be changed to another leap year, otherwise
+an error is returned.
+
+@param aYear The year.
+
+@return KErrNone if successful, KErrGeneral if not.
+*/
+ {
+
+ if (iDay>=Time::DaysInMonth(aYear,iMonth))
+ return KErrGeneral;
+ iYear=aYear;
+ return KErrNone;
+ }
+
+EXPORT_C TInt TDateTime::SetYearLeapCheck(TInt aYear)
+//
+// lets you reset 29th February to non-leap year(moves date to 28th/Feb), no check on year range
+//
+/**
+Sets the year with a leap year check.
+
+Unlike SetYear(), if the date is the 29th February, this function allows
+the year to be set to a non-leap year. In this case, the date is reset to
+the 28th February.
+
+@param aYear The year.
+
+@return KErrNone if successful, KErrGeneral if not.
+
+@see TDateTime::SetYear
+*/
+ {
+
+ if (iDay>=Time::DaysInMonth(aYear,iMonth))
+ iDay=27;
+ iYear=aYear;
+ return KErrNone;
+ }
+
+EXPORT_C TInt TDateTime::SetMonth(TMonth aMonth)
+/**
+Sets the month component of the date/time.
+
+@param aMonth The month to be set. The range is from EJanuary to EDecember.
+ If an attempt is made to set an invalid month, or if the current
+ day number in the month is greater than or equal to the number of
+ days in the new month, an error is returned.
+
+@return KErrNone if successful, KErrGeneral if not.
+*/
+ {
+
+ if (aMonth<EJanuary || aMonth>EDecember || iDay>=Time::DaysInMonth(iYear,aMonth))
+ return KErrGeneral;
+ iMonth=aMonth;
+ return KErrNone;
+ }
+
+EXPORT_C TInt TDateTime::SetDay(TInt aDay)
+/**
+Sets the day component of the date/time.
+
+@param aDay The number of the day within the month, offset from zero. If equal
+ to or greater than the total number of days in the month, an error
+ is returned.
+
+@return KErrNone if successful, KErrGeneral if not.
+*/
+ {
+
+ if (aDay<0 || aDay>=Time::DaysInMonth(iYear,iMonth))
+ return KErrGeneral;
+ iDay=aDay;
+ return KErrNone;
+ }
+
+EXPORT_C TInt TDateTime::SetHour(TInt aHour)
+/**
+Sets the hour component of the date/time.
+
+@param aHour The hour. Range is 0 to 23.
+
+@return KErrNone if successful, KErrGeneral if not.
+*/
+ {
+
+ if (aHour<0 || aHour>=24) // GC - bug fix
+ return KErrGeneral;
+ iHour=aHour;
+ return KErrNone;
+ }
+
+EXPORT_C TInt TDateTime::SetMinute(TInt aMinute)
+/**
+Sets the minute component of the date/time.
+
+@param aMinute The minute. Range is 0 to 59.
+
+@return KErrNone if successful, KErrGeneral if not.
+*/
+ {
+
+ if (aMinute<0 || aMinute>=60)
+ return KErrGeneral;
+ iMinute=aMinute;
+ return KErrNone;
+ }
+
+EXPORT_C TInt TDateTime::SetSecond(TInt aSecond)
+/**
+Sets the second component of the date/time.
+
+@param aSecond The second. Range is 0 to 59.
+
+@return KErrNone if successful, KErrGeneral if not.
+*/
+ {
+
+ if (aSecond<0 || aSecond>=60)
+ return KErrGeneral;
+ iSecond=aSecond;
+ return KErrNone;
+ }
+
+EXPORT_C TInt TDateTime::SetMicroSecond(TInt aMicroSecond)
+/**
+Sets the microsecond component of the date/time.
+
+@param aMicroSecond The microsecond. Range is 0 to 999999.
+
+@return KErrNone if successful, KErrGeneral if not.
+*/
+ {
+
+ if (aMicroSecond<0 || aMicroSecond>=1000000)
+ return KErrGeneral;
+ iMicroSecond=aMicroSecond;
+ return KErrNone;
+ }
+
+// class TTime
+
+EXPORT_C TTime::TTime(const TDesC &aString)
+/**
+Constructs a TTime object with a text string.
+
+The string consists of up to three components, any or all of which
+may be omitted:
+
+1. year, month and day, followed by a colon
+
+2. hour, minute and second, followed by a dot
+
+3. microsecond
+
+When all three components are present, the string should take the form:
+
+YYYYMMDD:HHMMSS.MMMMMM
+
+The conversion from text to time is carried out in the same manner as that
+used in TTime::Set().
+
+For a list of the range of valid values for date and time components,
+see TDateTime::Set().
+
+@param aString Date and time string for initializing the TTime object.
+
+@panic USER 113, if the string is syntactically incorrect, for example, if
+ neither a colon nor a dot is present, or if any component of
+ the date or time is assigned an invalid value, or the year
+ is negative.
+
+@see TTime::Set
+@see TDateTime::Set
+*/
+ {
+
+ __ASSERT_ALWAYS(Set(aString)==KErrNone,Panic(ETTimeValueOutOfRange));
+ }
+
+EXPORT_C TTime::TTime(const TDateTime &aDateTime) : iTime(Convert(aDateTime).Int64())
+/**
+Constructs a TTime object with the seven fields which comprise a date and time.
+
+@param aDateTime Date and time to which to initialise the TTime object.
+*/
+
+ {}
+
+EXPORT_C TInt TTime::Set(const TDesC &aString)
+//
+// Convert string to time. String is in the format:
+//
+// YYYYMMDD:HHMMSS.MMMMMM
+//
+// Any part may be ommitted, but either the
+// dot or colon or both must be present
+//
+/**
+Assigns a date and time contained in a descriptor to this TTime object.
+
+The string consists of up to three components, any or all of which may
+be omitted:
+
+1. year, month and day, followed by a colon
+
+2. hour, minute and second, followed by a dot
+
+3. microsecond
+
+When all three components are present, the string should take the form:
+
+YYYYMMDD:HHMMSS.MMMMMM
+
+If omitted, the first component is set to January 1st 0 AD nominal Gregorian.
+If either the second or third components are omitted, they are set to zero.
+
+Notes:
+
+1. The month and day values are offset from zero.
+
+2. The only situations in which either the colon or dot may be omitted are as
+ follows:
+
+ 2.1 If the microsecond component is omitted, the preceding dot may also
+ be omitted.
+
+ 2.2 The colon can be omitted only if a dot is located at string position
+ zero (indicating that the first two components are missing), or at
+ string position six (indicating that the first component only is
+ missing).
+
+@param aString The date and time to be assigned to this TTime object.
+
+@return KErrNone if successful,
+ KErrGeneral if the string is syntactically incorrect, for example,
+ if neither a colon nor a dot is present, or if any component of the
+ date or time is given an invalid value, or the year is negative.
+ For a list of valid values for date and time components,
+ see TDateTime::Set().
+ If an error occurs, the date and time will remain unchanged.
+*/
+ {
+
+//
+// Get position of the colon and dot separators
+//
+ TInt colon=aString.Locate(':');
+ TInt dot=aString.Locate('.');
+
+ if(colon==KErrNotFound && dot==KErrNotFound)
+ return(KErrGeneral);
+//
+// Zero parts that aren't supplied
+//
+ TInt yy=0;
+ TInt mm=0;
+ TInt dd=0;
+ TInt hr=0;
+ TInt mi=0;
+ TInt se=0;
+ TInt ms=0;
+//
+// Convert YYYYMMDD if present
+//
+ switch(colon)
+ {
+ case 0:
+ break;
+ case KErrNotFound:
+ if(dot!=0 && dot!=6)
+ return(KErrGeneral);
+ colon=-1;
+ break;
+ case 8:
+ {
+ TLex y=aString.Left(4);
+ TLex m=aString.Mid(4,2);
+ TLex d=aString.Mid(6,2);
+ y.Val(yy);
+ m.Val(mm);
+ d.Val(dd);
+ }
+ break;
+ default: // Colon in wrong position - return error
+ return(KErrGeneral);
+ }
+//
+// Convert HHMMSS if present
+//
+ if(dot==KErrNotFound)
+ dot=aString.Length();
+
+ if(dot==colon+7)
+ {
+ TLex h=aString.Mid(dot-6,2);
+ TLex m=aString.Mid(dot-4,2);
+ TLex s=aString.Mid(dot-2,2);
+ h.Val(hr);
+ m.Val(mi);
+ s.Val(se);
+ }
+ else if(dot!=KErrNotFound && dot!=0 && dot!=colon+1)
+ return(KErrGeneral);
+
+ if(dot!=KErrNotFound)
+ {
+ if(aString.Length()>dot+7)
+ return(KErrGeneral); // microseconds is more than 6 digits
+ if(dot<aString.Length())
+ {
+ TLex m=aString.Mid(dot+1);
+ m.Val(ms);
+ }
+ }
+
+//
+// Set the time! Do not construct newtime using the values or
+// it may cause TTime::Set() to panic rather than return an error
+//
+ TDateTime newtime;
+ if(newtime.Set(yy,TMonth(mm),dd,hr,mi,se,ms)!=KErrNone)
+ return(KErrGeneral);
+ (*this)=newtime;
+ return KErrNone;
+ }
+
+EXPORT_C TInt TTime::HomeTimeSecure()
+/**
+Sets the date and time of this TTime to the secure home time.
+Returns KErrNoSecureTime if there is no secure time source
+*/
+ {
+ TInt utOffset=0;
+ TInt r = Exec::TimeNowSecure(*(TInt64*)this,utOffset);
+ operator+=(TTimeIntervalSeconds(utOffset));
+ return r;
+ }
+
+EXPORT_C TInt TTime::UniversalTimeSecure()
+/**
+Sets the date and time of this TTime to the secure universal time.
+*/
+ {
+ TInt utOffset=0;
+ return Exec::TimeNowSecure(*(TInt64*)this,utOffset);
+ }
+
+EXPORT_C void TTime::HomeTime()
+/**
+Sets the date and time of this TTime to the home time.
+*/
+ {
+ TInt utOffset=0;
+ Exec::TimeNow(*(TInt64*)this,utOffset);
+ operator+=(TTimeIntervalSeconds(utOffset));
+ }
+
+EXPORT_C void TTime::UniversalTime()
+/**
+Sets the date and time of this TTime to the universal time.
+*/
+ {
+ TInt utOffset=0;
+ Exec::TimeNow(*(TInt64*)this,utOffset);
+ }
+
+EXPORT_C void TTime::RoundUpToNextMinute()
+/**
+Rounds this TTime up to the next minute.
+
+Both the seconds and microseconds components are set to zero.
+*/
+ {
+
+ if (iTime>0)
+ iTime+=59999999;
+//* TInt64 remainder;
+//* Int64().DivMod(60000000,remainder);
+//* iTime-=remainder;
+ iTime-=iTime%60000000;
+ }
+
+TTime TTime::Convert(const TDateTime &aDateTime)
+//
+// converts TDateTime into a TTime, doesnt check for overflows
+//
+ {
+
+ TInt days=365*aDateTime.Year()+Time::LeapYearsUpTo(aDateTime.Year());
+ TBool isleap=Time::IsLeapYear(aDateTime.Year());
+ days+=cmTab[isleap][aDateTime.Month()];
+ days+=aDateTime.Day();
+
+ TUint sum=aDateTime.MicroSecond()+aDateTime.Second()*KSecondsToMicroSeconds+aDateTime.Minute()*KMinutesToMicroSeconds;
+ return(((TInt64(days*3)<<3)+TInt64(aDateTime.Hour()))*KHoursToMicroSeconds+TInt64(sum));
+ }
+
+EXPORT_C TTime &TTime::operator=(const TDateTime &aDateTime)
+/**
+Assigns a TDateTime object to this TTime object.
+
+@param aDateTime The date and time to assign to this TTime object.
+
+@return This TTime object.
+*/
+ {
+
+ iTime=Convert(aDateTime).Int64();
+ return(*this);
+ }
+
+EXPORT_C TDateTime TTime::DateTime() const
+//
+// converts iTime back into its TDateTime components
+//
+/**
+Converts the TTime object into a TDateTime object.
+
+This conversion must be done before the seven fields which comprise a date
+and time can be accessed.
+
+@return The components of the time, indicating year, month, day, hour, minute,
+ second, microsecond.
+*/
+ {
+
+ TInt64 rem;
+ TInt64 daysSince0AD64(iTime);
+
+ rem = daysSince0AD64 % KDaysToMicroSeconds;
+ daysSince0AD64 /= KDaysToMicroSeconds;
+
+ TInt daysSince0AD = static_cast<TInt>(daysSince0AD64);
+
+ TInt year;
+ TInt daysLeft;
+ if (iTime<0)
+ { // -1 to make daysLeft +ve and assume leap year every 4 years
+ if (rem!=TInt64(0))
+ {
+ daysSince0AD--;
+ rem=iTime-TInt64(daysSince0AD)*KDaysToMicroSeconds;
+ }
+ year=(4*daysSince0AD)/((4*365)+1);
+ if ((4*daysSince0AD)%((4*365)+1))
+ year--;
+ daysLeft=daysSince0AD-((year*365)+Time::LeapYearsUpTo(year));
+ }
+ else
+ { // after 1600 leap years less than every four years
+ year=(4*daysSince0AD)/((4*365)+1);
+ daysLeft=daysSince0AD-((year*365)+Time::LeapYearsUpTo(year));
+ TInt daysInYear=365+Time::IsLeapYear(year);
+ while (daysLeft>=daysInYear)
+ {
+ year++;
+ daysLeft-=daysInYear;
+ daysInYear=365+Time::IsLeapYear(year);
+ }
+ }
+
+ TDateTime result(0,EJanuary,0,0,0,0,0);
+ result.SetYear(year);
+
+ TBool isleap=Time::IsLeapYear(year);
+ TInt month=11;
+ const TInt* pCM=&(cmTab[isleap][11])+1;
+ while(daysLeft<*--pCM)
+ month--;
+ daysLeft-=*pCM;
+
+ result.SetMonth((TMonth)month);
+ result.SetDay(daysLeft);
+
+ TInt hour = static_cast<TInt>(rem >> 10) / 3515625; // 3515625=KHoursToMicroSeconds/1024
+ result.SetHour(hour);
+ TUint rem32=I64LOW(rem-(TInt64(hour*3515625)<<10));
+ TUint min=rem32/KMinutesToMicroSeconds;
+ result.SetMinute((TInt)min);
+ rem32-=min*KMinutesToMicroSeconds;
+ TUint sec=rem32/KSecondsToMicroSeconds;
+ result.SetSecond((TInt)sec);
+ rem32-=sec*KSecondsToMicroSeconds;
+ result.SetMicroSecond(TInt(rem32));
+ return(result);
+ }
+
+EXPORT_C TTimeIntervalMicroSeconds TTime::MicroSecondsFrom(TTime aTime) const
+//
+// this - aTime
+//
+/**
+Calculates the number of microseconds difference between the specified TTime
+and this TTime.
+
+@param aTime The time to be compared with this TTime.
+
+@return Difference in microseconds between the two times. If the time specified
+ in the argument is later than this TTime, this value is negative.
+*/
+ {
+
+ TInt64 difference=iTime-aTime.Int64();
+ return(difference);
+ }
+
+EXPORT_C TInt TTime::SecondsFrom(TTime aTime,TTimeIntervalSeconds &aInterval) const
+//
+// this - aTime as whole seconds
+// this function may fail if difference > no of seconds that can be represented in a TInt
+//
+/**
+Calculates the number of seconds difference between the specified TTime and
+this TTime.
+
+The difference may be positive or negative.
+
+@param aTime The time to be compared with this TTime.
+@param aInterval On return contains the difference in seconds between the two
+ times. If the time specified in the first argument is later than
+ this TTime, then this returned value is negative.
+
+@return Error code. KErrNone if successful.
+ KErrOverflow, if the calculated interval is too large for
+ a 32-bit integer.
+*/
+ {
+ TInt64 diff;
+ if (iTime>aTime.Int64())
+ {
+ diff= TInt64(TUint64(iTime-aTime.Int64())/KSecondsToMicroSeconds);
+ }
+ else
+ {
+ diff= -TInt64(TUint64(aTime.Int64()-iTime)/KSecondsToMicroSeconds);
+ }
+ if (diff>KMaxTInt || diff<KMinTInt)
+ return KErrOverflow;
+ aInterval = static_cast<TInt>(diff);
+ return KErrNone;
+ }
+
+EXPORT_C TInt TTime::MinutesFrom(TTime aTime,TTimeIntervalMinutes &aInterval) const
+//
+// iTime - aTime as whole minutes
+// function may fail if difference can't be represented as a TInt
+//
+/**
+Calculates the number of minutes difference between the specified TTime and
+this TTime.
+
+The difference may be positive or negative.
+
+@param aTime The time to be compared with this TTime.
+@param aInterval On return contains the difference in minutes between the two
+ times. If the time specified in the first argument is later
+ than this TTime, then this returned value is negative.
+
+@return Error code. KErrNone if successful.
+ KErrOverflow, if the calculated interval is too large for
+ a 32-bit integer.
+*/
+ {
+ TInt64 diff;
+ if (iTime>aTime.Int64())
+ {
+ diff= TInt64(TUint64(iTime-aTime.Int64())/KMinutesToMicroSeconds);
+ }
+ else
+ {
+ diff= -TInt64(TUint64(aTime.Int64()-iTime)/KMinutesToMicroSeconds);
+ }
+ if (diff>KMaxTInt || diff<KMinTInt)
+ return KErrOverflow;
+ aInterval = static_cast<TInt>(diff);
+ return KErrNone;
+ }
+
+EXPORT_C TInt TTime::HoursFrom(TTime aTime,TTimeIntervalHours &aInterval) const
+//
+// iTime - aTime as whole hours
+// function may fail if difference can't be represented as a TInt
+//
+/**
+Calculates the number of hours difference between the specified TTime and
+this TTime.
+
+The difference may be positive or negative.
+
+@param aTime The time to be compared with this TTime.
+@param aInterval On return contains the difference in hours between the two
+ times. If the time specified in the first argument is later
+ than this TTime, then this returned value is negative.
+
+@return Error code. KErrNone if successful.
+ KErrOverflow, if the calculated interval is too large for
+ a 32-bit integer.
+*/
+ {
+ TInt64 diff;
+ if (iTime>aTime.Int64())
+ {
+ diff= TInt64(TUint64(iTime-aTime.Int64())/KHoursToMicroSeconds);
+ }
+ else
+ {
+ diff= -TInt64(TUint64(aTime.Int64()-iTime)/KHoursToMicroSeconds);
+ }
+ if (diff>KMaxTInt || diff<KMinTInt)
+ return KErrOverflow;
+ aInterval = static_cast<TInt>(diff);
+ return KErrNone;
+ }
+
+
+EXPORT_C TTimeIntervalDays TTime::DaysFrom(TTime aTime) const
+//
+// iTime - aTime as whole days
+//
+/**
+Calculates the number of days difference between the specified TTime and
+this TTime.
+
+The difference may be positive or negative.
+
+@param aTime The time to be compared with this TTime.
+
+@return Difference in days between the two times. If the time specified in
+ aTime is later than this TTime, the returned value will be negative.
+*/
+ {
+ if (iTime>aTime.Int64())
+ {
+ return TInt(TUint64(iTime-aTime.Int64())/KDaysToMicroSeconds);
+ }
+ else
+ {
+ return -TInt(TUint64(aTime.Int64()-iTime)/KDaysToMicroSeconds);
+ }
+ }
+
+EXPORT_C TTimeIntervalMonths TTime::MonthsFrom(TTime aTime) const
+//
+// iTime - aTime as whole months - ie aTime must be on a later day in the month and later in that day
+// except for last days etc eg 31st October - 30 November is one month to be consistent with other
+// functions
+//
+/**
+Calculates the number of months between the specified TTime and this TTime.
+
+The result may be positive or negative.
+
+The interval in months between two TTimes is calculated by incrementing it
+by one each time the same day number and time in the previous or following
+month has been reached. Exceptions to this rule occur when this TTime is on
+the last day of the month. In this case, the following rules apply:
+
+When comparing this TTime with a later time:
+
+1. if the following month is shorter, one month is deemed to separate the times
+ when the same time on the last day of the following month is reached. In this
+ case, the two day numbers are not the same.
+
+When comparing this TTime with an earlier time:
+
+1. if the previous month is shorter, one month is deemed to separate the times
+ when the last microsecond of the previous month is reached (23:59:59.999999
+ on the last day of the month).
+
+2. if the previous month is longer, one month is deemed to separate the times
+ when the same time on the last day of previous month is reached. In this case,
+ the two day numbers are not the same.
+
+@param aTime The time to be compared with this TTime.
+
+@return Difference in months between the two times. If the time specified in
+ the argument is later than this TTime, the interval is negative.
+*/
+ {
+
+ TDateTime dateTimei=DateTime();
+ TDateTime dateTimea=aTime.DateTime();
+
+ TInt monthsDifference=(dateTimei.Year()-dateTimea.Year())*12+(dateTimei.Month()-dateTimea.Month());
+
+ if (monthsDifference>0)
+ {
+ if (dateTimei.Day()<=dateTimea.Day())
+ {
+ if (iTime%KDaysToMicroSeconds<aTime.Int64()%KDaysToMicroSeconds || (dateTimei.Day()!=dateTimea.Day() && dateTimei.Day()!=DaysInMonth()-1))
+ monthsDifference--;
+ }
+ }
+ else
+ if (monthsDifference!=0)//monthsDifference<0
+ {
+ if (dateTimei.Day()>=dateTimea.Day())
+ {
+ if (iTime%KDaysToMicroSeconds>aTime.Int64()%KDaysToMicroSeconds || (dateTimei.Day()!=dateTimea.Day() && dateTimea.Day()!=aTime.DaysInMonth()-1))
+ monthsDifference++;
+ }
+ }
+
+ return(monthsDifference);
+ }
+
+EXPORT_C TTimeIntervalYears TTime::YearsFrom(TTime aTime) const
+//
+// as above,but for twelve months
+//
+/**
+Calculates the number of years between the specified TTime and this TTime.
+
+The result may be positive or negative.
+
+Note that the interval in years between two TTimes is calculated by
+incrementing it by one each time the same day number and time in the previous
+or following year has been reached. The exception to this rule occurs when this
+TTime is the last day in February in a leap year. In this case, one year is
+deemed to have passed when the same time of day on the last day in the preceding
+or following February has been reached.
+
+@param aTime The time to be compared with this TTime.
+
+@return Difference in years between the two times. If the time specified in
+ the argument is later than this TTime, the interval is negative.
+*/
+ {
+
+ TTimeIntervalMonths mos= TTime::MonthsFrom(aTime);
+ TTimeIntervalYears ret=mos.Int()/12;
+ return(ret);
+ }
+
+EXPORT_C TTime TTime::operator+(TTimeIntervalYears aYear) const
+/**
+Adds a time interval to this TTime, returning the result
+as a TTime.
+
+Note that in a leap year, when adding one year to the 29th February, the result
+is the 28th February in the following year.
+
+Note also that this TTime object is not changed.
+
+@param aYear A time interval in years. The argument is stored as a 32 bit
+ signed integer. The maximum value which it can represent is
+ 2147483647. Any attempt to add more than this amount will
+ produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return((*this)+TTimeIntervalMonths(aYear.Int()*12));
+ }
+
+EXPORT_C TTime TTime::operator+(TTimeIntervalMonths aMonth) const
+/**
+Adds a time interval to this TTime, returning the result
+as a TTime.
+
+Note that when adding one month to the last day in the month, if the following
+month is shorter, the result is the last day in the following month.
+For example, when adding one month to 31st August, the result is
+the 30th September.
+
+Note also that this TTime object is not changed.
+
+@param aMonth A time interval in months. The argument is stored as a 32 bit
+ signed integer. The maximum value which it can represent is
+ 2147483647. Any attempt to add more than this amount will
+ produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ TDateTime dateTime=DateTime();
+ TInt month=dateTime.Month()+(dateTime.Year()*12)+aMonth.Int();
+ TInt day=dateTime.Day();
+ TInt year=month/12;
+ month%=12;
+ if (month<0)
+ {
+ year--;
+ month+=12;
+ }
+ TInt daysInMonth=(mTab[Time::IsLeapYear(year)][month]-1);
+ if (day>=daysInMonth)
+ day=daysInMonth;
+ __ASSERT_ALWAYS(dateTime.Set(year,TMonth(month),day,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond())==KErrNone,Panic(ETDateTimeBadDateTime));
+ return(dateTime);
+ }
+
+EXPORT_C TTime TTime::operator+(TTimeIntervalDays aDay) const
+/**
+Adds a time interval to this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aDay A time interval in days. The argument is stored as a 32 bit
+ signed integer. The maximum value which it can represent is
+ 2147483647. Any attempt to add more than this amount will
+ produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime+TInt64(aDay.Int())*KDaysToMicroSeconds);
+ }
+
+EXPORT_C TTime TTime::operator+(TTimeIntervalHours aHour) const
+/**
+Adds a time interval to this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aHour A time interval in hours. The argument is stored as a 32 bit
+ signed integer. The maximum value which it can represent is
+ 2147483647. Any attempt to add more than this amount will
+ produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime+TInt64(aHour.Int())*KHoursToMicroSeconds);
+ }
+
+EXPORT_C TTime TTime::operator+(TTimeIntervalMinutes aMinute) const
+/**
+Adds a time interval to this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aMinute A time interval in minutes. The argument is stored as a 32 bit
+ signed integer. The maximum value which it can represent is
+ 2147483647. Any attempt to add more than this amount will
+ produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime+TInt64(aMinute.Int())*KMinutesToMicroSeconds);
+ }
+
+EXPORT_C TTime TTime::operator+(TTimeIntervalSeconds aSecond) const
+/**
+Adds a time interval to this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aSecond A time interval in seconds. The argument is stored as a 32 bit
+ signed integer. The maximum value which it can represent is
+ 2147483647. Any attempt to add more than this amount will
+ produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime+TInt64(aSecond.Int())*KSecondsToMicroSeconds);
+ }
+
+
+EXPORT_C TTime TTime::operator+(TTimeIntervalMicroSeconds aMicroSecond) const
+/**
+Adds a time interval to this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aMicroSecond A time interval in microseconds.
+
+@return The new time.
+*/
+ {
+
+ return(iTime+(aMicroSecond.Int64()));
+ }
+
+EXPORT_C TTime TTime::operator+(TTimeIntervalMicroSeconds32 aMicroSecond) const
+/**
+Adds a time interval to this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aMicroSecond A time interval in microseconds. The argument is stored as
+ a 32 bit signed integer. The maximum value which it can
+ represent is 2147483647. Any attempt to add more than this
+ amount will produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime+aMicroSecond.Int());
+ }
+
+EXPORT_C TTime TTime::operator-(TTimeIntervalYears aYear) const
+/**
+Substracts a time interval from this TTime, returning the result
+as a TTime.
+
+Note that in a leap year, when subtracting one year from the 29th February,
+the result is 28th February in the preceding year.
+
+Note also that this TTime object is not changed.
+
+@param aYear A time interval in years. The argument is stored as
+ a 32 bit signed integer. The maximum value which it can
+ represent is 2147483647. Any attempt to subtract more than this
+ amount will produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return((*this)-TTimeIntervalMonths(aYear.Int()*12));
+ }
+
+EXPORT_C TTime TTime::operator-(TTimeIntervalMonths aMonth) const
+/**
+Substracts a time interval from this TTime, returning the result
+as a TTime.
+
+Note that when subtracting one month from the last day in the month, if the
+preceding month is shorter, the result is the last day in the preceding month.
+For example, when subtracting 1 month from 31st October, the result is
+the 30th September.
+
+Note also that this TTime object is not changed.
+
+@param aMonth A time interval in months. The argument is stored as
+ a 32 bit signed integer. The maximum value which it can
+ represent is 2147483647. Any attempt to subtract more than this
+ amount will produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return((*this)+TTimeIntervalMonths(aMonth.Int()*-1));
+ }
+
+EXPORT_C TTime TTime::operator-(TTimeIntervalDays aDay) const
+/**
+Substracts a time interval from this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aDay A time interval in days. The argument is stored as
+ a 32 bit signed integer. The maximum value which it can
+ represent is 2147483647. Any attempt to subtract more than this
+ amount will produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime-TInt64(aDay.Int())*KDaysToMicroSeconds);
+ }
+
+EXPORT_C TTime TTime::operator-(TTimeIntervalHours aHour) const
+/**
+Substracts a time interval from this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aHour A time interval in hours. The argument is stored as
+ a 32 bit signed integer. The maximum value which it can
+ represent is 2147483647. Any attempt to subtract more than this
+ amount will produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime-TInt64(aHour.Int())*KHoursToMicroSeconds);
+ }
+
+EXPORT_C TTime TTime::operator-(TTimeIntervalMinutes aMinute) const
+/**
+Substracts a time interval from this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aMinute A time interval in minutes. The argument is stored as
+ a 32 bit signed integer. The maximum value which it can
+ represent is 2147483647. Any attempt to subtract more than this
+ amount will produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime-TInt64(aMinute.Int())*KMinutesToMicroSeconds);
+ }
+
+EXPORT_C TTime TTime::operator-(TTimeIntervalSeconds aSecond) const
+/**
+Substracts a time interval from this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aSecond A time interval in seconds. The argument is stored as
+ a 32 bit signed integer. The maximum value which it can
+ represent is 2147483647. Any attempt to subtract more than this
+ amount will produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime-TInt64(aSecond.Int())*KSecondsToMicroSeconds);
+ }
+
+EXPORT_C TTime TTime::operator-(TTimeIntervalMicroSeconds aMicroSecond) const
+/**
+Substracts a time interval from this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aMicroSecond A time interval in microseconds.
+
+@return The new time.
+*/
+ {
+
+ return(iTime-(aMicroSecond.Int64()));
+ }
+
+EXPORT_C TTime TTime::operator-(TTimeIntervalMicroSeconds32 aMicroSecond) const
+/**
+Substracts a time interval from this TTime, returning the result
+as a TTime.
+
+Note that this TTime object is not changed.
+
+@param aMicroSecond A time interval in microseconds. The argument is stored as
+ a 32 bit signed integer. The maximum value which it can
+ represent is 2147483647. Any attempt to subtract more than
+ this amount will produce incorrect results.
+
+@return The new time.
+*/
+ {
+
+ return(iTime-aMicroSecond.Int());
+ }
+
+EXPORT_C TTime &TTime::operator+=(TTimeIntervalYears aYear)
+/**
+Adds a time interval to this TTime, returning a reference to this TTime.
+
+@param aYear A time interval in years.
+
+@return A reference to this TTime.
+*/
+ {
+
+ TTime tim=(*this)+aYear;
+ iTime=tim.Int64();
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator+=(TTimeIntervalMonths aMonth)
+/**
+Adds a time interval to this TTime, returning a reference to this TTime.
+
+@param aMonth A time interval in months.
+
+@return A reference to this TTime.
+*/
+ {
+
+ TTime tim=(*this)+aMonth;
+ iTime=tim.Int64();
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator+=(TTimeIntervalDays aDay)
+/**
+Adds a time interval to this TTime, returning a reference to this TTime.
+
+@param aDay A time interval in days.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime+=TInt64(aDay.Int())*KDaysToMicroSeconds;
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator+=(TTimeIntervalHours aHour)
+/**
+Adds a time interval to this TTime, returning a reference to this TTime.
+
+@param aHour A time interval in hours.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime+=TInt64(aHour.Int())*KHoursToMicroSeconds;
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator+=(TTimeIntervalMinutes aMinute)
+/**
+Adds a time interval to this TTime, returning a reference to this TTime.
+
+@param aMinute A time interval in minutes.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime+=TInt64(aMinute.Int())*KMinutesToMicroSeconds;
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator+=(TTimeIntervalSeconds aSecond)
+/**
+Adds a time interval to this TTime, returning a reference to this TTime.
+
+@param aSecond A time interval in seconds.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime+=TInt64(aSecond.Int())*KSecondsToMicroSeconds;
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator+=(TTimeIntervalMicroSeconds aMicroSecond)
+/**
+Adds a time interval to this TTime, returning a reference to this TTime.
+
+@param aMicroSecond A time interval in microseconds.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime+=aMicroSecond.Int64();
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator+=(TTimeIntervalMicroSeconds32 aMicroSecond)
+/**
+Adds a time interval to this TTime, returning a reference to this TTime.
+
+@param aMicroSecond A time interval in microseconds, as a 32-bit integer.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime+=aMicroSecond.Int();
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator-=(TTimeIntervalYears aYear)
+/**
+Subtracts a time interval from this TTime, returning a reference to this TTime.
+
+@param aYear A time interval in years.
+
+@return A reference to this TTime.
+*/
+ {
+
+ TTime tim=(*this)-aYear;
+ iTime=tim.Int64();
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator-=(TTimeIntervalMonths aMonth)
+/**
+Subtracts a time interval from this TTime, returning a reference to this TTime.
+
+@param aMonth A time interval in months.
+
+@return A reference to this TTime.
+*/
+ {
+
+ TTime tim=(*this)-aMonth;
+ iTime=tim.Int64();
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator-=(TTimeIntervalDays aDay)
+/**
+Subtracts a time interval from this TTime, returning a reference to this TTime.
+
+@param aDay A time interval in days.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime-=TInt64(aDay.Int())*KDaysToMicroSeconds;
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator-=(TTimeIntervalHours aHour)
+/**
+Subtracts a time interval from this TTime, returning a reference to this TTime.
+
+@param aHour A time interval in hours.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime-=TInt64(aHour.Int())*KHoursToMicroSeconds;
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator-=(TTimeIntervalMinutes aMinute)
+/**
+Subtracts a time interval from this TTime, returning a reference to this TTime.
+
+@param aMinute A time interval in minutes.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime-=TInt64(aMinute.Int())*KMinutesToMicroSeconds;
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator-=(TTimeIntervalSeconds aSecond)
+/**
+Subtracts a time interval from this TTime, returning a reference to this TTime.
+
+@param aSecond A time interval in seconds.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime-=TInt64(aSecond.Int())*KSecondsToMicroSeconds;
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator-=(TTimeIntervalMicroSeconds aMicroSecond)
+/**
+Subtracts a time interval from this TTime, returning a reference to this TTime.
+
+@param aMicroSecond A time interval in microseconds.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime-=aMicroSecond.Int64();
+ return(*this);
+ }
+
+EXPORT_C TTime &TTime::operator-=(TTimeIntervalMicroSeconds32 aMicroSecond)
+/**
+Subtracts a time interval from this TTime, returning a reference to this TTime.
+
+@param aMicroSecond A time interval in microseconds, as a 32-bit integer.
+
+@return A reference to this TTime.
+*/
+ {
+
+ iTime-=aMicroSecond.Int();
+ return(*this);
+ }
+
+EXPORT_C TInt TTime::DaysInMonth() const
+/**
+Gets the number of days in the current month.
+
+@return The number of days in the month.
+*/
+ {
+
+ TDateTime dateTime=DateTime();
+ return(Time::DaysInMonth(dateTime.Year(),dateTime.Month()));
+ }
+
+EXPORT_C TDay TTime::DayNoInWeek() const
+//
+// 1st January 0AD was a Monday
+//
+/**
+Gets the day number within the current week.
+
+This is a value in the range zero to six inclusive, and honours the
+setting specified in TLocale::SetStartOfWeek().
+
+By default the first day in the week is Monday.
+
+@return The number of the day within the week. The range is EMonday to ESunday.
+
+@see TLocale::SetStartOfWeek
+*/
+ {
+
+
+ TInt64 fullDays=iTime/KDaysToMicroSeconds;
+ TInt day = static_cast<TInt>(fullDays) % 7;
+ if (iTime<0)
+ {
+ if (fullDays*KDaysToMicroSeconds!=iTime)
+ day+=6;
+ else
+ if (day!=0)
+ day+=7;
+ }
+ return((TDay)day);
+ }
+
+EXPORT_C TInt TTime::DayNoInMonth() const
+/**
+Gets the day number in the month.
+
+@return The day number in the month. The first day in the month is numbered
+ zero.
+*/
+ {
+
+ return(DateTime().Day());
+ }
+
+EXPORT_C TInt TTime::DayNoInYear() const
+//
+// day number in comparison to 1st January
+//
+/**
+Gets the day number in the year.
+
+@return The day number in the year. The first day in the year is day one.
+*/
+ {
+
+ TDateTime dateTime=DateTime();
+ TTime jan1st=TDateTime(dateTime.Year(),EJanuary,0,0,0,0,0);
+ return(DayNoInYear(jan1st));
+ }
+
+EXPORT_C TInt TTime::DayNoInYear(TTime aStartDate) const
+//
+// day number in comparison to given date, check is made to ensure first day is within a year before aDay
+//
+/**
+Gets the day number in the year when the start of the year is aStartDate.
+
+If no start date is specified, the default is January 1st.
+
+@param aStartDate Indicates the date which is to be considered the start of
+ the year. Default is 1st January.
+
+@return The day number in the year. The first day in the year is day one.
+*/
+ {
+
+ TInt y=DateTime().Year();
+ TMonth m=aStartDate.DateTime().Month();
+ TInt d=aStartDate.DateTime().Day();
+ if (d>=Time::DaysInMonth(y,m))
+ d=27;
+ TDateTime yearStart(y,m,d,0,0,0,0); // LEAP YEAR PROBLEMS ???
+ aStartDate=yearStart;
+ if (aStartDate>*this)
+ {
+ yearStart.SetYearLeapCheck(y-1);
+ aStartDate=yearStart;
+ }
+ return((DaysFrom(aStartDate).Int())+1) ;
+ }
+
+EXPORT_C TInt TTime::WeekNoInYear() const
+/**
+Gets the number of the current week in the year.
+
+@return Week number in the year.
+*/
+ {
+
+ return(WeekNoInYear(EFirstFourDayWeek));
+ }
+
+EXPORT_C TInt TTime::WeekNoInYear(TTime aStartDate) const
+/**
+Gets the number of the current week in the year when the year starts
+on aStartDate.
+
+@param aStartDate If specified, indicates the date which is to be considered
+ the start of the year. Default is 1st January.
+
+@return Week number in the year.
+*/
+ {
+
+ return(WeekNoInYear(aStartDate,EFirstFourDayWeek));
+ }
+
+EXPORT_C TInt TTime::WeekNoInYear(TFirstWeekRule aRule) const
+/**
+Finds the number of the current week in the year using the first week rule
+specified in aRule.
+
+@param aRule Determines how the first week in the year is to be calculated.
+ By default EFirstFourDayWeek.
+
+@return Week number in the year.
+*/
+ {
+
+ TInt year=DateTime().Year();
+ TTime startDate=TDateTime(year,EJanuary,0,0,0,0,0);
+ return(WeekNoInYear(startDate,aRule));
+ }
+
+EXPORT_C TInt TTime::WeekNoInYear(TTime aStartDate,TFirstWeekRule aRule) const
+//
+// number of weeks between aTime and aStartDate according to given rule
+// the first week starts either on the week containing the first day (EFirstWeek),
+// the first week having at least four days within the new year (EFirstFourDayWeek,
+// default) or the first full week in the year (EFirstFullWeek)
+//
+/**
+Finds the number of the current week in the year when the year starts from
+aStartDate and when using the start week rule aRule.
+
+@param aStartDate If specified, indicates the date which is to be considered
+ the start of the year. Default is 1st January.
+@param aRule Determines how the first week in the year is to be
+ calculated. By default EFirstFourDayWeek.
+
+@return Week number in the year.
+*/
+ {
+ TInt dayNoInWeek=DayNoInWeek();
+ TInt dayNoInYear=(DayNoInYear(aStartDate))-1; // puts start into correct year
+ TDateTime startDateTime(aStartDate.DateTime());
+ TDateTime nextYearStartDate(startDateTime);
+ nextYearStartDate.SetYearLeapCheck(DateTime().Year()); // find start of next year
+ TTime nextYearStartTime(nextYearStartDate); // makes sure start date for year
+ if (*this>nextYearStartTime) // is in the very next year
+ {
+ nextYearStartDate.SetYearLeapCheck(nextYearStartDate.Year()+1);
+ nextYearStartTime=nextYearStartDate;
+ }
+ nextYearStartTime+=TTimeIntervalMicroSeconds(KDaysToMicroSeconds-1); // avoid problems if the time is not midnight
+ TLocale local;
+ TDay startOfFirstWeek=local.StartOfWeek();
+ // calculate the day-in-week number (0 to 6) based on the locale start-of-week
+ dayNoInWeek -= startOfFirstWeek;
+ if (dayNoInWeek < 0)
+ dayNoInWeek += 7;
+ // calculate the days from the start-of-week to the start-of-next-year
+ TInt daysFrom=nextYearStartTime.DaysFrom(*this).Int()+dayNoInWeek;
+ // calculate the days from start-of-year to start-of-week (note this may be negative, but never < -6)
+ TInt days=dayNoInYear-dayNoInWeek;
+
+ // the rule allows a certain number of week-1 days to lie in the previous year
+ TInt prevyeardays;
+ switch (aRule)
+ {
+ default:
+ return -1;
+ case EFirstWeek:
+ prevyeardays = 6;
+ break;
+ case EFirstFourDayWeek:
+ prevyeardays = 3;
+ break;
+ case EFirstFullWeek:
+ prevyeardays = 0;
+ break;
+ }
+
+ // check for a week which belongs to last year
+ if (days + prevyeardays < 0)
+ {
+ // in week 52 or 53 of last year, find the week # of the first day in the week
+ startDateTime.SetYearLeapCheck(startDateTime.Year()-1);
+ return (*this-TTimeIntervalDays(dayNoInWeek)).WeekNoInYear(TTime(startDateTime),aRule);
+ }
+
+ // check for a week which belongs to next year
+ if (daysFrom <= prevyeardays)
+ return 1;
+
+ // calculate the week number, accounting for the requested week-1 rule
+ return (days + 7 + prevyeardays)/7;
+ }
+
+EXPORT_C void TTime::FormatL(TDes &aDes,const TDesC &aFormat) const
+//
+// Fill aString with current Date and Time according to given aFormat string
+//
+/**
+Puts this TTime into a descriptor and formats it according to the format string
+specified in the second argument.
+
+Many of the formatting commands use the
+system's locale settings for the date and time, for example the characters
+used to separate components of the date and time and the ordering of day,
+month and year. The list of formatting commands below is divided into two
+sections, the first of which lists the commands which operate without reference
+to the locale's date and time settings (see class TLocale) and the second
+table lists the commands which do use these settings.
+
+The following formatting commands do not honour the locale-specific system
+settings:
+
+\%\% : Include a single '%' character in the string
+
+\%* : Abbreviate following item (the following item should not be preceded
+by a '%' character).
+
+\%C : Interpret the argument as the six digit microsecond component of the
+time. In its abbreviated form, ('%*C') this should be followed by an integer
+between zero and six, where the integer indicates the number of digits to display.
+
+\%D : Interpret the argument as the two digit day number in the month. Abbreviation
+suppresses leading zero.
+
+\%E : Interpret the argument as the day name. Abbreviation is language-specific
+(e.g. English uses the first three letters).
+
+\%F : Use this command for locale-independent ordering of date components.
+This orders the following day/month/year component(s) (\%D, \%M, \%Y for example)
+according to the order in which they are specified in the string. This removes
+the need to use \%1 to \%5 (described below).
+
+\%H : Interpret the argument as the one or two digit hour component of the
+time in 24 hour time format. Abbreviation suppresses leading zero. For locale-dependent
+hour formatting, use \%J.
+
+\%I : Interpret the argument as the one or two digit hour component of the
+time in 12 hour time format. The leading zero is automatically suppressed
+so that abbreviation has no effect. For locale-dependent hour formatting,
+use \%J.
+
+\%M : Interpret the argument as the one or two digit month number. Abbreviation
+suppresses leading zero.
+
+\%N : Interpret the argument as the month name. Abbreviation is language specific, e.g.
+English uses the first three letters only. When using locale-dependent formatting,
+(that is, \%F has not previously been specified), specifying \%N causes any
+subsequent occurrence of a month specifier in the string to insert the month
+as text rather than in numeric form. When using locale-independent formatting,
+specifying \%N causes the month to be inserted as text at that position, but
+any subsequent occurrence of \%M will cause the month to be inserted in numeric
+form.
+
+\%S : Interpret the argument as the one or two digit seconds component of the
+time. Abbreviation suppresses leading zero.
+
+\%T : Interpret the argument as the one or two digit minutes component of the
+time. Abbreviation suppresses leading zero.
+
+\%W : Interpret the argument as the one or two digit week number in year. Abbreviation
+suppresses leading zero.
+
+\%X : Interpret the argument as the date suffix. Cannot be abbreviated. When
+using locale-dependent formatting (that is, \%F has not previously been specified),
+\%X causes all further occurrences of the day number to be displayed with the
+date suffix. When using locale-independent formatting, a date suffix will
+be inserted only after the occurrence of the day number which \%X follows in
+the format string. Any further occurrence of \%D without a following \%X will
+insert the day number without a suffix.
+
+\%Y : Interpret the argument as the four digit year number. Abbreviation suppresses
+the first two digits.
+
+\%Z : Interpret the argument as the one, two or three digit day number in the
+year. Abbreviation suppresses leading zeros.
+
+The following formatting commands do honour the locale-specific system settings:
+
+\%. : Interpret the argument as the decimal separator character (as set by
+TLocale::SetDecimalSeparator()). The decimal separator is used to separate
+seconds and microseconds, if present.
+
+\%: : Interpret the argument as one of the four time separator characters (as
+set by TLocale::SetTimeSeparator()). Must be followed by an integer between
+zero and three inclusive to indicate which time separator character is being
+referred to.
+
+\%/ : Interpret the argument as one of the four date separator characters (as
+set by TLocale::SetDateSeparator()). Must be followed by an integer between
+zero and three inclusive to indicate which date separator character is being
+referred to.
+
+\%1 : Interpret the argument as the first component of a three component date
+(i.e. day, month or year) where the order has been set by TLocale::SetDateFormat().
+When the date format is EDateEuropean, this is the day, when EDateAmerican,
+the month, and when EDateJapanese, the year. For more information on this
+and the following four formatting commands, see the Notes section immediately
+below.
+
+\%2 : Interpret the argument as the second component of a three component date
+where the order has been set by TLocale::SetDateFormat(). When the date format
+is EDateEuropean, this is the month, when EDateAmerican, the day and when
+EDateJapanese, the month.
+
+\%3 : Interpret the argument as the third component of a three component date
+where the order has been set by TLocale::SetDateFormat(). When the date format
+is EDateEuropean, or EDateAmerican this is the year and when EDateJapanese,
+the day.
+
+\%4 : Interpret the argument as the first component of a two component date
+(day and month) where the order has been set by TLocale::SetDateFormat().
+When the date format is EDateEuropean this is the day, and when EDateAmerican
+or EDateJapanese, the month.
+
+\%5 : Interpret the argument as the second component of a two component date
+(day and month) where the order has been set by TLocale::SetDateFormat().
+When the date format is EDateEuropean this is the month, and when EDateAmerican
+or EDateJapanese, the day.
+
+\%A : Interpret the argument as "am" or "pm" text according to the current
+language and time of day. Unlike the \%B formatting command (described below),
+\%A disregards the locale's 12 or 24 hour clock setting, so that when used
+without an inserted + or - sign, am/pm text will always be displayed. Whether
+a space is inserted between the am/pm text and the time depends on the locale-specific
+settings. However, if abbreviated (\%*A), no space is inserted, regardless
+of the locale's settings. The am/pm text appears before or after the time,
+according to the position of the \%A, regardless of the locale-specific settings.
+For example, the following ordering of formatting commands causes am/pm text
+to be printed after the time: \%H \%T \%S \%A. Optionally, a minus or plus sign
+may be inserted between the "%" and the "A". This operates as follows:
+
+\%-A causes am/pm text to be inserted into the descriptor only if the am/pm
+symbol position has been set in the locale to ELocaleBefore. Cannot be abbreviated
+using asterisk.
+
+\%+A causes am/pm text to be inserted into the descriptor only if the am/pm
+symbol position has been set in the locale to ELocaleAfter. Cannot be abbreviated
+using asterisk. For example, the following formatting commands will cause
+am/pm text to be displayed after the time if the am/pm position has been set
+in the locale to ELocaleAfter or before the time if ELocaleBefore: \%-A \%H
+\%T \%S \%+A.
+
+\%B Interpret the argument as am or pm text according to the current language
+and time of day. Unlike the \%A command, when using \%B, am/pm text is displayed
+only if the clock setting in the locale is 12-hour. Whether a space is inserted
+between the am/pm text and the time depends on the locale-specific settings.
+However, if abbreviated (\%*B), no space is inserted, regardless of the locale's
+settings. The am/pm text appears before or after the time, according to the
+location of the "%B", regardless of the locale-specific settings. For example,
+the following formatting commands cause am/pm text to be printed after the
+time: \%H \%T \%S \%B. Optionally, a minus or plus sign may be inserted between
+the "%" and the "B". This operates as follows:
+
+\%-B causes am/pm text to be inserted into the descriptor only if using a 12
+hour clock and the am/pm symbol position has been set in the locale to ELocaleBefore.
+Cannot be abbreviated using asterisk.
+
+\%+B causes am/pm text to be inserted into the descriptor only if using a 12
+hour clock and the am/pm symbol position has been set in the locale to ELocaleAfter.
+Cannot be abbreviated using asterisk. For example, the following formatting
+commands cause am/pm text to be printed after the time if the am/pm position
+has been set in the locale to ELocaleAfter or before the time if ELocaleBefore:
+\%-B \%H \%T \%S \%+B.
+
+\%J Interpret the argument as the hour component of the time in either 12 or
+24 hour clock format depending on the locale's clock format setting. When
+the clock format has been set to 12 hour, leading zeros are automatically
+suppressed so that abbreviation has no effect. Abbreviation suppresses leading
+zero only when using a 24 hour clock.
+
+Notes:
+
+The \%1, \%2, \%3, \%4 and \%5 formatting commands are used in conjunction with
+\%D, \%M and \%Y to format the date locale-dependently. When formatting the date
+locale-dependently, the order of the day, month and year components within
+the string is determined by the order of the \%1 to \%5 formatting commands,
+not that of \%D, \%M, \%Y.
+
+When formatting the date locale-independently (that is, \%F has been specified
+in the format string), the \%1 to \%5 formatting commands are not required,
+and should be omitted. In this case, the order of the date components is determined
+by the order of the \%D, \%M, \%Y format commands within aFormat.
+
+Up to four date separators and up to four time separators can be used to separate
+the components of a date or time. When formatting a numerical date consisting
+of the day, month and year or a time containing hours, minutes and seconds,
+all four separators should always be specified in the format command string.
+Usually, the leading and trailing separators should not be displayed. In this
+case, the first and fourth separators should still be specified, but should
+be represented by a null character.
+
+The date format follows the pattern:
+
+DateSeparator[0] DateComponent1 DateSeparator[1] DateComponent2 DateSeparator[2]
+DateComponent3 DateSeparator[3]
+
+where the ordering of date components is determined by the locale's date format
+setting.
+
+The time format follows the pattern:
+
+TimeSeparator[0] Hours TimeSeparator[1] Minutes TimeSeparator[2] Seconds TimeSeparator[3]
+
+If the time includes a microseconds component, the third separator should
+occur after the microseconds, and the seconds and microseconds should be separated
+by the decimal separator. When formatting a two component time, the following
+rules apply:
+
+if the time consists of hours and minutes, the third time delimiter should
+be omitted
+
+if the time consists of minutes and seconds, the second time delimiter should
+be omitted
+
+@param aDes Descriptor, which, on return contains the formatted date/time string.
+@param aFormat Format string which determines the format of the date and time.
+
+@leave KErrOverflow The date/time string is too long for the descriptor aDes.
+@leave KErrGeneral A formatting error has occurred.
+*/
+ {
+ TLocale local;
+ FormatL(aDes,aFormat,local);
+ }
+
+EXPORT_C void TTime::FormatL(TDes &aDes,const TDesC &aFormat,const TLocale &aLocale) const
+//
+// Fill aString with current Date and Time according to given aFormat string
+//
+/**
+Puts this TTime into a descriptor and formats it according to the format string
+specified in the second argument.
+
+Many of the formatting commands use the
+system's locale settings for the date and time, for example the characters
+used to separate components of the date and time and the ordering of day,
+month and year. The list of formatting commands below is divided into two
+sections, the first of which lists the commands which operate without reference
+to the locale's date and time settings (see class TLocale) and the second
+table lists the commands which do use these settings.
+
+The following formatting commands do not honour the locale-specific system
+settings:
+
+\%\% : Include a single '%' character in the string
+
+\%* : Abbreviate following item (the following item should not be preceded
+by a '%' character).
+
+\%C : Interpret the argument as the six digit microsecond component of the
+time. In its abbreviated form, ('%*C') this should be followed by an integer
+between zero and six, where the integer indicates the number of digits to display.
+
+\%D : Interpret the argument as the two digit day number in the month. Abbreviation
+suppresses leading zero.
+
+\%E : Interpret the argument as the day name. Abbreviation is language-specific
+(e.g. English uses the first three letters).
+
+\%F : Use this command for locale-independent ordering of date components.
+This orders the following day/month/year component(s) (\%D, \%M, \%Y for example)
+according to the order in which they are specified in the string. This removes
+the need to use \%1 to \%5 (described below).
+
+\%H : Interpret the argument as the one or two digit hour component of the
+time in 24 hour time format. Abbreviation suppresses leading zero. For locale-dependent
+hour formatting, use \%J.
+
+\%I : Interpret the argument as the one or two digit hour component of the
+time in 12 hour time format. The leading zero is automatically suppressed
+so that abbreviation has no effect. For locale-dependent hour formatting,
+use \%J.
+
+\%M : Interpret the argument as the one or two digit month number. Abbreviation
+suppresses leading zero.
+
+\%N : Interpret the argument as the month name. Abbreviation is language specific, e.g.
+English uses the first three letters only. When using locale-dependent formatting,
+(that is, \%F has not previously been specified), specifying \%N causes any
+subsequent occurrence of a month specifier in the string to insert the month
+as text rather than in numeric form. When using locale-independent formatting,
+specifying \%N causes the month to be inserted as text at that position, but
+any subsequent occurrence of \%M will cause the month to be inserted in numeric
+form.
+
+\%S : Interpret the argument as the one or two digit seconds component of the
+time. Abbreviation suppresses leading zero.
+
+\%T : Interpret the argument as the one or two digit minutes component of the
+time. Abbreviation suppresses leading zero.
+
+\%W : Interpret the argument as the one or two digit week number in year. Abbreviation
+suppresses leading zero.
+
+\%X : Interpret the argument as the date suffix. Cannot be abbreviated. When
+using locale-dependent formatting (that is, \%F has not previously been specified),
+\%X causes all further occurrences of the day number to be displayed with the
+date suffix. When using locale-independent formatting, a date suffix will
+be inserted only after the occurrence of the day number which \%X follows in
+the format string. Any further occurrence of \%D without a following \%X will
+insert the day number without a suffix.
+
+\%Y : Interpret the argument as the four digit year number. Abbreviation suppresses
+the first two digits.
+
+\%Z : Interpret the argument as the one, two or three digit day number in the
+year. Abbreviation suppresses leading zeros.
+
+The following formatting commands do honour the locale-specific system settings:
+
+\%. : Interpret the argument as the decimal separator character (as set by
+TLocale::SetDecimalSeparator()). The decimal separator is used to separate
+seconds and microseconds, if present.
+
+\%: : Interpret the argument as one of the four time separator characters (as
+set by TLocale::SetTimeSeparator()). Must be followed by an integer between
+zero and three inclusive to indicate which time separator character is being
+referred to.
+
+\%/ : Interpret the argument as one of the four date separator characters (as
+set by TLocale::SetDateSeparator()). Must be followed by an integer between
+zero and three inclusive to indicate which date separator character is being
+referred to.
+
+\%1 : Interpret the argument as the first component of a three component date
+(i.e. day, month or year) where the order has been set by TLocale::SetDateFormat().
+When the date format is EDateEuropean, this is the day, when EDateAmerican,
+the month, and when EDateJapanese, the year. For more information on this
+and the following four formatting commands, see the Notes section immediately
+below.
+
+\%2 : Interpret the argument as the second component of a three component date
+where the order has been set by TLocale::SetDateFormat(). When the date format
+is EDateEuropean, this is the month, when EDateAmerican, the day and when
+EDateJapanese, the month.
+
+\%3 : Interpret the argument as the third component of a three component date
+where the order has been set by TLocale::SetDateFormat(). When the date format
+is EDateEuropean, or EDateAmerican this is the year and when EDateJapanese,
+the day.
+
+\%4 : Interpret the argument as the first component of a two component date
+(day and month) where the order has been set by TLocale::SetDateFormat().
+When the date format is EDateEuropean this is the day, and when EDateAmerican
+or EDateJapanese, the month.
+
+\%5 : Interpret the argument as the second component of a two component date
+(day and month) where the order has been set by TLocale::SetDateFormat().
+When the date format is EDateEuropean this is the month, and when EDateAmerican
+or EDateJapanese, the day.
+
+\%A : Interpret the argument as "am" or "pm" text according to the current
+language and time of day. Unlike the \%B formatting command (described below),
+\%A disregards the locale's 12 or 24 hour clock setting, so that when used
+without an inserted + or - sign, am/pm text will always be displayed. Whether
+a space is inserted between the am/pm text and the time depends on the locale-specific
+settings. However, if abbreviated (\%*A), no space is inserted, regardless
+of the locale's settings. The am/pm text appears before or after the time,
+according to the position of the \%A, regardless of the locale-specific settings.
+For example, the following ordering of formatting commands causes am/pm text
+to be printed after the time: \%H \%T \%S \%A. Optionally, a minus or plus sign
+may be inserted between the "%" and the "A". This operates as follows:
+
+\%-A causes am/pm text to be inserted into the descriptor only if the am/pm
+symbol position has been set in the locale to ELocaleBefore. Cannot be abbreviated
+using asterisk.
+
+\%+A causes am/pm text to be inserted into the descriptor only if the am/pm
+symbol position has been set in the locale to ELocaleAfter. Cannot be abbreviated
+using asterisk. For example, the following formatting commands will cause
+am/pm text to be displayed after the time if the am/pm position has been set
+in the locale to ELocaleAfter or before the time if ELocaleBefore: \%-A \%H
+\%T \%S \%+A.
+
+\%B Interpret the argument as am or pm text according to the current language
+and time of day. Unlike the \%A command, when using \%B, am/pm text is displayed
+only if the clock setting in the locale is 12-hour. Whether a space is inserted
+between the am/pm text and the time depends on the locale-specific settings.
+However, if abbreviated (\%*B), no space is inserted, regardless of the locale's
+settings. The am/pm text appears before or after the time, according to the
+location of the "%B", regardless of the locale-specific settings. For example,
+the following formatting commands cause am/pm text to be printed after the
+time: \%H \%T \%S \%B. Optionally, a minus or plus sign may be inserted between
+the "%" and the "B". This operates as follows:
+
+\%-B causes am/pm text to be inserted into the descriptor only if using a 12
+hour clock and the am/pm symbol position has been set in the locale to ELocaleBefore.
+Cannot be abbreviated using asterisk.
+
+\%+B causes am/pm text to be inserted into the descriptor only if using a 12
+hour clock and the am/pm symbol position has been set in the locale to ELocaleAfter.
+Cannot be abbreviated using asterisk. For example, the following formatting
+commands cause am/pm text to be printed after the time if the am/pm position
+has been set in the locale to ELocaleAfter or before the time if ELocaleBefore:
+\%-B \%H \%T \%S \%+B.
+
+\%J Interpret the argument as the hour component of the time in either 12 or
+24 hour clock format depending on the locale's clock format setting. When
+the clock format has been set to 12 hour, leading zeros are automatically
+suppressed so that abbreviation has no effect. Abbreviation suppresses leading
+zero only when using a 24 hour clock.
+
+Notes:
+
+The \%1, \%2, \%3, \%4 and \%5 formatting commands are used in conjunction with
+\%D, \%M and \%Y to format the date locale-dependently. When formatting the date
+locale-dependently, the order of the day, month and year components within
+the string is determined by the order of the \%1 to \%5 formatting commands,
+not that of \%D, \%M, \%Y.
+
+When formatting the date locale-independently (that is, \%F has been specified
+in the format string), the \%1 to \%5 formatting commands are not required,
+and should be omitted. In this case, the order of the date components is determined
+by the order of the \%D, \%M, \%Y format commands within aFormat.
+
+Up to four date separators and up to four time separators can be used to separate
+the components of a date or time. When formatting a numerical date consisting
+of the day, month and year or a time containing hours, minutes and seconds,
+all four separators should always be specified in the format command string.
+Usually, the leading and trailing separators should not be displayed. In this
+case, the first and fourth separators should still be specified, but should
+be represented by a null character.
+
+The date format follows the pattern:
+
+DateSeparator[0] DateComponent1 DateSeparator[1] DateComponent2 DateSeparator[2]
+DateComponent3 DateSeparator[3]
+
+where the ordering of date components is determined by the locale's date format
+setting.
+
+The time format follows the pattern:
+
+TimeSeparator[0] Hours TimeSeparator[1] Minutes TimeSeparator[2] Seconds TimeSeparator[3]
+
+If the time includes a microseconds component, the third separator should
+occur after the microseconds, and the seconds and microseconds should be separated
+by the decimal separator. When formatting a two component time, the following
+rules apply:
+
+if the time consists of hours and minutes, the third time delimiter should
+be omitted
+
+if the time consists of minutes and seconds, the second time delimiter should
+be omitted
+
+@param aDes Descriptor, which, on return contains the formatted date/time string.
+@param aFormat Format string which determines the format of the date and time.
+@param aLocale Specific locale which formatting will be based on.
+
+@leave KErrOverflow The date/time string is too long for the descriptor aDes.
+@leave KErrGeneral A formatting error has occurred.
+*/
+ {
+
+ TDateTime dateTime=DateTime();
+ aDes.Zero(); // ensure string is empty at start
+
+ TLex aFmt(aFormat);
+ TBool fix=EFalse; // fixed date format
+ TBool da=EFalse; // day unabreviated
+ TBool ma=EFalse; // month unabreviated
+ TBool ya=EFalse; // year unabreviated
+ TBool suff=EFalse; // default no suffix
+ TBool mnam=EFalse; // default month as a number
+ TTimeOverflowLeave overflowLeave;
+
+ while (!aFmt.Eos())
+ {
+ TChar ch=aFmt.Get();
+ TBool abb=EFalse;
+ const TInt NoPosSpecified=-1;
+ TInt pos=NoPosSpecified;
+ if (ch=='%')
+ ch=aFmt.Get();
+ else // not formatting,just want to add some characters to string
+ goto doAppend;
+ if (ch=='*') // => abbreviate next field
+ {
+ abb=ETrue;
+ ch=aFmt.Get();
+ }
+ else if (ch=='+' || ch=='-') // => leading or following Am/Pm
+ {
+ pos= ((ch=='+') ? ELocaleAfter : ELocaleBefore);
+ ch=aFmt.Get();
+ if (ch!='A' && ch!='B')
+ User::Leave(KErrGeneral);
+ }
+ switch (ch)
+ {
+ case ':': // local time separator
+ {
+ if (aDes.Length()==aDes.MaxLength())
+ User::Leave(KErrOverflow);
+ ch=aFmt.Get();//Which separator?
+ if (ch<'0' || ch>='0'+KMaxTimeSeparators)
+ User::Leave(KErrGeneral);
+ ch-='0';
+ TChar separator=aLocale.TimeSeparator(ch);
+ if (separator!=0)
+ aDes.Append(separator);
+ }
+ break;
+ case '/': // local date separator
+ {
+ if (aDes.Length()==aDes.MaxLength())
+ User::Leave(KErrOverflow);
+ ch=aFmt.Get();//Which separator?
+ if (ch<'0' || ch>='0'+KMaxDateSeparators)
+ User::Leave(KErrGeneral);
+ ch-='0';
+ TChar separator=aLocale.DateSeparator(ch);
+ if (separator!=0)
+ aDes.Append(separator);
+ }
+ break;
+ case '.': // local decimal separator
+ {
+ if (aDes.Length()==aDes.MaxLength())
+ User::Leave(KErrOverflow);
+ aDes.Append(aLocale.DecimalSeparator());
+ }
+ break;
+ case '1': // 1st element of date,local order
+ switch (aLocale.DateFormat())
+ {
+ case EDateAmerican:
+ goto doMonth;
+ case EDateJapanese:
+ goto doYear;
+ default: // European
+ goto doDay;
+ }
+ case '2': // 2nd element of date,local order
+ switch (aLocale.DateFormat())
+ {
+ case EDateAmerican:
+ goto doDay;
+ default: // European and Japanese have month second
+ goto doMonth;
+ }
+ case '3': // 3rd element of date,local order
+ switch (aLocale.DateFormat())
+ {
+ case EDateJapanese:
+ goto doDay;
+ default: // European and American have year last
+ goto doYear;
+ }
+ case '4': // 1st element of date (no year),local order
+ switch (aLocale.DateFormat())
+ {
+ case EDateEuropean:
+ goto doDay;
+ default:
+ goto doMonth;
+ }
+ case '5': // 2nd element of date (no year),local order
+ switch (aLocale.DateFormat())
+ {
+ case EDateEuropean:
+ goto doMonth;
+ default:
+ goto doDay;
+ }
+ case 'A': // am/pm text
+doAmPm:
+ {
+ if (pos==NoPosSpecified || pos==aLocale.AmPmSymbolPosition())
+ {
+ TBuf<KMaxAmPmName+1> format(_S("%S"));
+ if (!abb && aLocale.AmPmSpaceBetween())
+ {
+ if (aLocale.AmPmSymbolPosition()==ELocaleBefore)
+ format.Append(' ');
+ else
+ {
+ if (aDes.Length()==aDes.MaxLength())
+ User::Leave(KErrOverflow);
+ aDes.Append(' ');
+ }
+ }
+ TAmPmName amPm((dateTime.Hour()<12) ? EAm : EPm);
+ aDes.AppendFormat(format,&overflowLeave,&amPm);
+ }
+ break;
+ }
+ case 'B': // am/pm text if local time format is 12 hour clock
+ if (aLocale.TimeFormat()==ETime24)
+ break;
+ else
+ goto doAmPm;
+ case 'C':
+ {
+ TBuf<6> digits;
+ digits.AppendFormat(_L("%06d"),dateTime.MicroSecond());
+ TUint numChars=6; // Default length
+ if (abb)
+ {
+ ch=aFmt.Get();
+ if (ch>='0' && ch<='6')
+ {
+ numChars=ch;
+ numChars-='0';
+ }
+ }
+ if (aDes.Length()>(TInt)(aDes.MaxLength()-numChars))
+ User::Leave(KErrOverflow);
+ aDes.Append(digits.Left(numChars));
+ }
+ break;
+ case 'D': // day in date
+ if (abb)
+ da=ETrue;
+ if (!fix)
+ break;
+ else
+ {
+doDay:
+ aDes.AppendFormat((da||abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Day()+1);
+ if (suff)
+doSuffix:
+ {
+ TDateSuffix day(dateTime.Day());
+ aDes.AppendFormat(_L("%S"),&overflowLeave,&day);
+ }
+ break;
+ }
+ case 'E': // Day name
+ {
+ TDay day=DayNoInWeek();
+ if (abb)
+ {
+ TDayNameAbb nameAbb(day);
+ aDes.AppendFormat(_L("%S"),&overflowLeave,&nameAbb);
+ }
+ else
+ {
+ TDayName name(day);
+ aDes.AppendFormat(_L("%S"),&overflowLeave,&name);
+ }
+ break;
+ }
+ case 'F': // => user wants day,month,year order fixed
+ fix=ETrue;
+ break;
+ case 'H': // hour in 24 hour time format
+do24:
+ aDes.AppendFormat((abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Hour());
+ break;
+ case 'I': // hour in 12 hour time format
+do12:
+ {
+ TInt hour=dateTime.Hour();
+ if (hour==0)
+ hour=12;
+ else if (hour>12)
+ hour-=12;
+ aDes.AppendFormat(_L("%d"),&overflowLeave,hour);
+ break;
+ }
+ case 'J': //default time format for hour
+ if (aLocale.TimeFormat()==ETime12)
+ goto do12;
+ else
+ goto do24;
+ case 'M': // month as a number (default value)
+ if (abb)
+ ma=ETrue;
+ if (fix)
+ goto doMonth;
+ break;
+ case 'N': // month as a name
+ mnam=ETrue;
+ if (abb)
+ ma=ETrue;
+ if (!fix)
+ break;
+ else
+ {
+doMonth:
+ if (mnam)
+ {
+ TMonth month=dateTime.Month();
+ if (ma || abb)
+ {
+ TMonthNameAbb nameAbb(month);
+ aDes.AppendFormat(_L("%S"),&overflowLeave,&nameAbb);
+ }
+ else
+ {
+ TMonthName name(month);
+ aDes.AppendFormat(_L("%S"),&overflowLeave,&name);
+ }
+ }
+ else
+ aDes.AppendFormat((ma||abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Month()+1);
+ break;
+ }
+ case 'S': // seconds
+ aDes.AppendFormat((abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Second());
+ break;
+ case 'T': // minutes
+ aDes.AppendFormat((abb) ? _L("%d"):_L("%02d"),&overflowLeave,dateTime.Minute());
+ break;
+ case 'W': // week no in year
+ aDes.AppendFormat((abb) ? _L("%d"):_L("%02d"),&overflowLeave,WeekNoInYear());
+ break;
+ case 'X': // => wants day suffix
+ if (fix)
+ goto doSuffix;
+ else
+ {
+ suff=ETrue;
+ break;
+ }
+ case 'Y': // year
+ if (abb)
+ ya=ETrue;
+ if (!fix)
+ break;
+ else
+ {
+doYear:
+ if (ya || abb)
+ aDes.AppendFormat(_L("%02d"),&overflowLeave,((dateTime.Year())%100));
+ else
+ aDes.AppendFormat(_L("%04d"),&overflowLeave,dateTime.Year());
+ break;
+ }
+ case 'Z': // day no in year
+ aDes.AppendFormat((abb) ? _L("%d"):_L("%03d"),&overflowLeave,DayNoInYear());
+ break;
+ default:
+doAppend:
+ if (aDes.Length()==aDes.MaxLength())
+ User::Leave(KErrOverflow);
+ aDes.Append(ch);
+ break;
+ }
+ }
+ }
+
+
+
+
+EXPORT_C TTime Time::NullTTime()
+/**
+Gets a TTime with a null value.
+
+@return TTime object with a null value.
+*/
+ {
+ return UI64LIT(0x8000000000000000);
+ }
+
+EXPORT_C TTime Time::MaxTTime()
+/**
+Gets the maximum time value which can be held in a TTime object.
+
+@return The maximum TTime value.
+*/
+ {
+ return I64LIT(0x7fffffffffffffff);
+ }
+
+EXPORT_C TTime Time::MinTTime()
+/**
+Gets the minimum time value which can be held in a TTime object.
+
+@return The minimum TTime value.
+*/
+ {
+ return UI64LIT(0x8000000000000001);
+ }
+
+EXPORT_C TInt Time::DaysInMonth(TInt aYear,TMonth aMonth)
+/**
+Gets the number of days in a month.
+
+@param aYear The year. Must be specified because of leap years.
+@param aMonth Month, from EJanuary to EDecember.
+
+@return The number of days in the month.
+*/
+ {
+
+ __ASSERT_DEBUG(aMonth<=EDecember && aMonth>=EJanuary,::Panic(ETTimeValueOutOfRange));
+ return(mTab[IsLeapYear(aYear)][aMonth]);
+ }
+
+EXPORT_C TBool Time::IsLeapYear(TInt aYear)
+//
+// up to and including 1600 leap years were every 4 years,since then leap years are every 4 years unless
+// the year falls on a century which is not divisible by 4 (ie 1900 wasnt,2000 will be)
+// for simplicity define year 0 as a leap year
+//
+/**
+Tests whether a year is a leap year.
+
+@param aYear The year of interest.
+
+@return True if leap year, False if not.
+*/
+ {
+
+ if (aYear>1600)
+ return(!(aYear%4) && (aYear%100 || !(aYear%400)));
+ return(!(aYear%4));
+ }
+
+EXPORT_C TInt Time::LeapYearsUpTo(TInt aYear)
+//
+// from 0AD to present year according to the rule above
+//
+/**
+Gets the number of leap years between 0 AD nominal Gregorian and the specified
+year - inclusive.
+
+@param aYear The final year in the range to search. If negative, the function
+ will return a negative number of leap years.
+
+@return The number of leap years between 0 AD nominal Gregorian and aYear.
+*/
+ {
+
+ if (aYear<=0)
+ return(aYear/4);
+ if (aYear<=1600)
+ return(1+((aYear-1)/4));
+ TInt num=401; // 1600/4+1
+ aYear-=1601;
+ TInt century=aYear/100;
+ num+=(aYear/4-century+century/4);
+ return(num);
+ }
+