--- /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<TCalTime>& 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