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