diff -r bd7edf625bdd -r 97232defd20e calendarui/editors/src/KoreanLunarDateUtil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/calendarui/editors/src/KoreanLunarDateUtil.cpp Tue Sep 14 21:17:03 2010 +0300 @@ -0,0 +1,228 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: +* +*/ + + +#include "KoreanLunarDateUtil.h" +// debug +#include "calendarui_debug.h" + +const TInt KMaxLunarYear = 60; + +/** + * Public methods for constructing a CKoreanLunarDateUtil object. + */ +CKoreanLunarDateUtil* CKoreanLunarDateUtil::NewL(MCalenServices* aServices) + { + TRACE_ENTRY_POINT; + CKoreanLunarDateUtil* self = CKoreanLunarDateUtil::NewLC(aServices); + CleanupStack::Pop( self ); + + TRACE_EXIT_POINT; + return self; + } + +CKoreanLunarDateUtil* CKoreanLunarDateUtil::NewLC(MCalenServices* aServices) + { + TRACE_ENTRY_POINT; + CKoreanLunarDateUtil* self = new (ELeave) CKoreanLunarDateUtil(aServices); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +CKoreanLunarDateUtil::CKoreanLunarDateUtil(MCalenServices* aServices):iServices(aServices) + { + TRACE_ENTRY_POINT; + } + + +void CKoreanLunarDateUtil::ConstructL() + { + TRACE_ENTRY_POINT; + iConverter = CKoreanCalConv::NewL(); + } + +CKoreanLunarDateUtil::~CKoreanLunarDateUtil() + { + TRACE_ENTRY_POINT; + delete iConverter; + } + +/** + * Method for getting nearest gregorian date from + * lunar day and month and gregorian reference. + */ +TDateTime CKoreanLunarDateUtil::GetNearestGregorianDateL( const TInt aMonth, + const TInt aDay, + const TBool aLeap, + const TDateTime& aReference ) const + { + TRACE_ENTRY_POINT; + TKoreanDate refLunarDate; + TKoreanDate lunarDate; + TDateTime resDateTime; + TInt err = KErrNone; + + iConverter->DateTimeToKoreanL( aReference, refLunarDate ); + /* Try to convert with the year and cycle we got with the reference */ + lunarDate.iCycle = refLunarDate.iCycle; + lunarDate.iYear = refLunarDate.iYear; + lunarDate.iMonth = aMonth; + lunarDate.iDay = aDay; + lunarDate.iLeapMonth = aLeap; + TRAP( err, iConverter->KoreanToDateTimeL( lunarDate, resDateTime ) ); + if( err == KErrArgument ) + { /* Date is invalid for this year (day 30 on a month + that has only 29 days on selected year or a leap month + not in this year), try to find suitable */ + TKoreanDate lowerLimit; + TKoreanDate upperLimit; + iConverter->DateRange( lowerLimit, upperLimit ); + while( 1 ) + { /* Search by increasing year */ + if( lunarDate.iYear < KMaxLunarYear ) + { + lunarDate.iYear++; + } + else + { + lunarDate.iYear = 1; + lunarDate.iCycle++; + } + if( (lunarDate.iCycle == upperLimit.iCycle && + lunarDate.iYear > upperLimit.iYear) || + lunarDate.iCycle > upperLimit.iCycle ) + { /* Could not find, just break */ + break; + } + TRAP( err, iConverter->KoreanToDateTimeL( lunarDate, resDateTime ) ); + if( err == KErrNone ) + { /* Found suitable */ + break; + } + } + if( err != KErrNone ) + { /* Suitable not found by increasing, + reset values and search by decreasing year */ + lunarDate.iCycle = refLunarDate.iCycle; + lunarDate.iYear = refLunarDate.iYear; + lunarDate.iMonth = aMonth; + lunarDate.iDay = aDay; + while( 1 ) + { /* Search by decreasing year */ + if( lunarDate.iYear > 1 ) + { + lunarDate.iYear--; + } + else + { + if( lunarDate.iCycle == 0 ) + { /* Run out of cycles, break with error */ + break; + } + lunarDate.iYear = KMaxLunarYear; + lunarDate.iCycle--; + } + if( (lunarDate.iCycle == lowerLimit.iCycle && + lunarDate.iYear < lowerLimit.iYear) || + lunarDate.iCycle < lowerLimit.iCycle ) + { /* Could not find, just break */ + break; + } + TRAP( err, iConverter->KoreanToDateTimeL( lunarDate, resDateTime ) ); + if( err == KErrNone ) + { /* Found suitable */ + break; + } + } + } + } + /* If still not found, leave with error */ + User::LeaveIfError( err ); + + TRACE_ENTRY_POINT; + /* Otherwise return the result */ + return resDateTime; + } + +/** +* Method for getting lunar yearly repeats in gregorian dates. +*/ +void CKoreanLunarDateUtil::GetLunarYearlyRepeatsL( RArray& aRDates, + const TDateTime& aEntryDate, + const TBool aFloating ) const + { + TInt err = KErrNone; + TCalTime repeatDate; + TDateTime resDateTime; + TDateTime lowerLimit; + TKoreanDate upperKoreanLimit; + TKoreanDate lunarStartDate; + + /* Get the upper limit for dates in Korean lunar format */ + iConverter->DateRange( lunarStartDate, upperKoreanLimit ); + + /* Get the entry date in Korean lunar format */ + iConverter->DateTimeToKoreanL( aEntryDate, lunarStartDate ); + + /* Get the lower limit for dates in Gregorian format */ + iConverter->DateRange( lowerLimit, resDateTime ); + + /* Get the first occurrence of the event after + the lower limit in Korean lunar format */ + iConverter->DateTimeToKoreanL( GetNearestGregorianDateL( lunarStartDate.iMonth, + lunarStartDate.iDay, + lunarStartDate.iLeapMonth, + lowerLimit ), + lunarStartDate ); + + while( 1 ) + { + TRAP( err, iConverter->KoreanToDateTimeL( lunarStartDate, resDateTime ) ); + if( err == KErrNone ) + { /* Date exists in current year */ + if( aFloating ) + { + repeatDate.SetTimeLocalFloatingL( resDateTime ); + } + else + { + repeatDate.SetTimeLocalL( resDateTime ); + } + aRDates.AppendL( repeatDate ); + } + /* Increase to next lunar year */ + if( lunarStartDate.iYear < KMaxLunarYear ) + { + lunarStartDate.iYear++; + } + else + { + lunarStartDate.iYear = 1; + lunarStartDate.iCycle++; + } + if( (lunarStartDate.iCycle == upperKoreanLimit.iCycle && + lunarStartDate.iYear > upperKoreanLimit.iYear) || + lunarStartDate.iCycle > upperKoreanLimit.iCycle ) + { /* Reached the limit, break */ + break; + } + } + } + +// End of file