--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/calendarui/commonutils/src/KoreanCalConv.cpp Tue Sep 14 21:17:03 2010 +0300
@@ -0,0 +1,528 @@
+/*
+* Copyright (c) 2007 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: Implementation of View Utils
+*
+*/
+
+#include "KoreanCalConv.h"
+
+//debug
+#include "calendarui_debug.h"
+
+/* Leap month exceptions for fixing conversion result
+ to match Korean lunar calendar:
+
+ year cycle, year, Chinese leap month, Korean leap month
+*/
+typedef struct
+{
+ TInt cycle;
+ TInt year;
+ TInt chineseLeapMonth;
+ TInt koreanLeapMonth;
+} TLeapExceptions;
+
+//CONSTANTS
+const TLeapExceptions KLeapExceptions[] = { {78, 29, 4, 3},
+ {78, 34, 6, 5},
+ {79, 56, 2, 3} };
+
+const TInt KLeapExceptionCnt = (sizeof( KLeapExceptions ) / sizeof( TLeapExceptions ));
+
+/* Month length exceptions for fixing conversion result
+ to match Korean lunar calendar. Corresponding months
+ have 30 days in Korean lunar calendar and 29 days
+ in Chinese lunar calendar. The next month always contains
+ 30 days in Chinese lunar calendar and 29 days in Korean
+ lunar calendar:
+
+ year cycle, year, korean month, flag indicating leap month, flag indicating next month is leap
+*/
+typedef struct
+{
+ TInt cycle;
+ TInt year;
+ TInt koreanMonth;
+ TBool isLeapMonth;
+ TBool nextIsLeapMonth;
+} TMonthExceptions;
+
+const TMonthExceptions KMonthExceptions[] = { {76, 43, 3, EFalse, EFalse },
+ {76, 51, 5, EFalse, ETrue },
+ {76, 51, 9, EFalse, EFalse },
+ {76, 52, 12, EFalse, EFalse },
+ {76, 55, 10, EFalse, EFalse },
+ {76, 56, 7, EFalse, ETrue },
+ {76, 56, 9, EFalse, EFalse },
+ {76, 57, 9, EFalse, EFalse },
+ {76, 60, 9, EFalse, EFalse },
+ {77, 1, 1, EFalse, EFalse },
+ {77, 2, 4, EFalse, ETrue },
+ {77, 4, 9, EFalse, EFalse },
+ {77, 5, 8, EFalse, EFalse },
+ {77, 8, 3, EFalse, EFalse },
+ {77, 11, 8, EFalse, EFalse },
+ {77, 13, 5, EFalse, EFalse },
+ {77, 19, 7, EFalse, EFalse },
+ {77, 19, 9, EFalse, EFalse },
+ {77, 20, 10, EFalse, EFalse },
+ {77, 20, 12, EFalse, EFalse },
+ {77, 26, 2, EFalse, EFalse },
+ {77, 27, 1, EFalse, EFalse },
+ {77, 27, 4, EFalse, EFalse },
+ {77, 29, 6, EFalse, EFalse },
+ {77, 30, 12, EFalse, EFalse },
+ {77, 32, 1, EFalse, EFalse },
+ {77, 34, 12, EFalse, EFalse },
+ {77, 45, 3, EFalse, EFalse },
+ {77, 47, 5, EFalse, EFalse },
+ {77, 49, 11, EFalse, EFalse },
+ {77, 50, 11, EFalse, EFalse },
+ {77, 53, 9, EFalse, EFalse },
+ {77, 55, 2, EFalse, EFalse },
+ {77, 59, 9, EFalse, EFalse },
+ {78, 4, 4, EFalse, EFalse },
+ {78, 4, 12, EFalse, EFalse },
+ {78, 6, 9, EFalse, EFalse },
+ {78, 12, 6, EFalse, EFalse },
+ {78, 12, 9, EFalse, EFalse },
+ {78, 13, 12, EFalse, EFalse },
+ {78, 15, 11, EFalse, EFalse },
+ {78, 18, 3, EFalse, EFalse },
+ {78, 22, 10, EFalse, EFalse },
+ {78, 29, 4, EFalse, EFalse },
+ {78, 29, 6, EFalse, EFalse },
+ {78, 30, 4, EFalse, EFalse },
+ {78, 36, 10, EFalse, EFalse },
+ {78, 37, 1, EFalse, EFalse },
+ {78, 40, 3, EFalse, EFalse },
+ {78, 43, 8, EFalse, EFalse },
+ {78, 43, 12, EFalse, EFalse },
+ {78, 44, 12, EFalse, EFalse },
+ {78, 46, 5, EFalse, EFalse },
+ {78, 48, 1, EFalse, EFalse },
+ {78, 52, 11, EFalse, EFalse },
+ {78, 53, 10, EFalse, EFalse },
+ {78, 57, 7, EFalse, EFalse },
+ {78, 58, 1, EFalse, EFalse },
+ {78, 59, 10, EFalse, EFalse },
+ {79, 3, 4, EFalse, EFalse },
+ {79, 5, 10, EFalse, EFalse },
+ {79, 7, 1, EFalse, EFalse },
+ {79, 8, 6, EFalse, EFalse },
+ {79, 8, 9, EFalse, EFalse },
+ {79, 9, 8, ETrue, EFalse },
+ {79, 15, 5, EFalse, EFalse },
+ {79, 16, 8, EFalse, EFalse },
+ {79, 17, 8, EFalse, EFalse },
+ {79, 17, 12, EFalse, EFalse },
+ {79, 20, 3, EFalse, EFalse },
+ {79, 25, 5, EFalse, EFalse },
+ {79, 26, 1, EFalse, EFalse },
+ {79, 27, 1, EFalse, EFalse },
+ {79, 28, 2, EFalse, EFalse },
+ {79, 31, 6, ETrue, EFalse },
+ {79, 37, 9, EFalse, EFalse },
+ {79, 38, 1, EFalse, EFalse },
+ {79, 39, 6, EFalse, EFalse },
+ {79, 45, 12, EFalse, EFalse },
+ {79, 46, 7, EFalse, EFalse },
+ {79, 51, 1, EFalse, EFalse },
+ {79, 53, 7, EFalse, EFalse },
+ {79, 54, 6, EFalse, EFalse },
+ {79, 55, 7, EFalse, EFalse },
+ {79, 55, 11, EFalse, EFalse },
+ {79, 56, 3, EFalse, ETrue } };
+
+const TInt KMonthExceptionCnt = (sizeof( KMonthExceptions ) / sizeof( TMonthExceptions ));
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::NewL
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CKoreanCalConv* CKoreanCalConv::NewL()
+ {
+ TRACE_ENTRY_POINT;
+ CKoreanCalConv* self = CKoreanCalConv::NewLC();
+ CleanupStack::Pop( self );
+
+ TRACE_EXIT_POINT;
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::NewLC
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CKoreanCalConv* CKoreanCalConv::NewLC()
+ {
+ TRACE_ENTRY_POINT;
+ CKoreanCalConv* self = new (ELeave) CKoreanCalConv();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+ TRACE_EXIT_POINT;
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::CKoreanCalConv
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CKoreanCalConv::CKoreanCalConv()
+ {
+ TRACE_ENTRY_POINT;
+ TRACE_EXIT_POINT;
+ }
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::ConstructL
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CKoreanCalConv::ConstructL()
+ {
+ TRACE_ENTRY_POINT;
+ chineseConv = CChineseCalendarConverter::NewL();
+ TRACE_EXIT_POINT;
+ }
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::~CKoreanCalConv
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CKoreanCalConv::~CKoreanCalConv()
+ {
+ TRACE_ENTRY_POINT;
+ delete chineseConv;
+ TRACE_EXIT_POINT;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::DateTimeToKoreanL
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CKoreanCalConv::DateTimeToKoreanL( const TDateTime& aDateTime, TKoreanDate& aKoreanDate )
+ {
+ TRACE_ENTRY_POINT;
+ TInt i;
+
+ /* Use the chinese converter for initial result */
+ chineseConv->DateTimeToChineseL( aDateTime, aKoreanDate );
+
+ /* Check if leap month fix is needed */
+ for( i = 0 ; i < KLeapExceptionCnt ; i++ )
+ {
+ if( KLeapExceptions[i].cycle == aKoreanDate.iCycle &&
+ KLeapExceptions[i].year == aKoreanDate.iYear )
+ { /* Year contains an exception */
+ if( KLeapExceptions[i].koreanLeapMonth < KLeapExceptions[i].chineseLeapMonth )
+ {
+ if( aKoreanDate.iLeapMonth )
+ { /* Resulted month is leap month in Chinese but not in Korean,
+ fix by unsetting the leap month flag */
+ aKoreanDate.iLeapMonth = EFalse;
+ }
+ else
+ {
+ if( aKoreanDate.iMonth == (KLeapExceptions[i].koreanLeapMonth + 1) )
+ { /* Resulted month is actually a leap month on Korean Calendar,
+ fix by setting the leap month flag and decreasing month by one */
+ aKoreanDate.iLeapMonth = ETrue;
+ aKoreanDate.iMonth -= 1;
+ }
+
+ /* See if month needs an offset fix */
+ if( aKoreanDate.iMonth > KLeapExceptions[i].koreanLeapMonth &&
+ aKoreanDate.iMonth <= KLeapExceptions[i].chineseLeapMonth )
+ { /* Between the leap months, fix by decreasing the month by one */
+ aKoreanDate.iMonth -= 1;
+ }
+ }
+ }
+ else if( KLeapExceptions[i].koreanLeapMonth > KLeapExceptions[i].chineseLeapMonth )
+ {
+ if( aKoreanDate.iLeapMonth )
+ { /* Resulted month is leap month in Chinese but not in Korean,
+ fix by unsetting the leap month flag and increase the month by one */
+ aKoreanDate.iLeapMonth = EFalse;
+ aKoreanDate.iMonth += 1;
+ }
+ else
+ {
+ if( aKoreanDate.iMonth == KLeapExceptions[i].koreanLeapMonth )
+ { /* Resulted month is actually a leap month on Korean Calendar,
+ fix by setting the leap month flag */
+ aKoreanDate.iLeapMonth = ETrue;
+ }
+
+ /* See if month needs an offset fix */
+ if( aKoreanDate.iMonth > KLeapExceptions[i].chineseLeapMonth &&
+ aKoreanDate.iMonth < KLeapExceptions[i].koreanLeapMonth )
+ { /* Between the leap months, fix by increasing the month by one */
+ aKoreanDate.iMonth += 1;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ /* Check if month length fix is needed */
+ for( i = 0 ; i < KMonthExceptionCnt ; i++ )
+ {
+ if( (KMonthExceptions[i].cycle == aKoreanDate.iCycle &&
+ KMonthExceptions[i].year == aKoreanDate.iYear &&
+ KMonthExceptions[i].koreanMonth != 12 &&
+ aKoreanDate.iMonth != 1) ||
+ (KMonthExceptions[i].koreanMonth == 12 && aKoreanDate.iMonth == 1 &&
+ (KMonthExceptions[i].year == (aKoreanDate.iYear - 1) &&
+ KMonthExceptions[i].cycle == aKoreanDate.iCycle) ||
+ (KMonthExceptions[i].year == 60 && aKoreanDate.iYear == 1 &&
+ KMonthExceptions[i].cycle == (aKoreanDate.iCycle - 1))) )
+ { /* Year may contain an exception */
+ if( (KMonthExceptions[i].koreanMonth == (aKoreanDate.iMonth - 1) &&
+ !(KMonthExceptions[i].nextIsLeapMonth || aKoreanDate.iLeapMonth)) ||
+ (KMonthExceptions[i].koreanMonth == 12 && aKoreanDate.iMonth == 1) ||
+ (KMonthExceptions[i].koreanMonth == aKoreanDate.iMonth &&
+ KMonthExceptions[i].nextIsLeapMonth && aKoreanDate.iLeapMonth) )
+ { /* Month contains an exception, decrease the day by one */
+ if( aKoreanDate.iDay == 1 )
+ {
+ aKoreanDate.iDay = 30;
+ if( aKoreanDate.iMonth == 1 )
+ {
+ aKoreanDate.iMonth = 12;
+ if( aKoreanDate.iYear == 1 )
+ {
+ aKoreanDate.iYear = 60;
+ aKoreanDate.iCycle -= 1;
+ }
+ else
+ {
+ aKoreanDate.iYear -= 1;
+ }
+ }
+ else
+ {
+ if( !aKoreanDate.iLeapMonth )
+ { /* Leap months don't need month decreasing */
+ aKoreanDate.iMonth -= 1;
+ }
+ if( KMonthExceptions[i].isLeapMonth )
+ {
+ aKoreanDate.iLeapMonth = ETrue;
+ }
+ else
+ {
+ aKoreanDate.iLeapMonth = EFalse;
+ }
+ }
+ }
+ else
+ {
+ aKoreanDate.iDay -= 1;
+ }
+ break;
+ }
+ }
+ }
+ TRACE_EXIT_POINT;
+ }
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::KoreanToDateTimeL
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CKoreanCalConv::KoreanToDateTimeL( TKoreanDate& aKoreanDate, TDateTime& aDateTime )
+ {
+ TRACE_ENTRY_POINT;
+ TInt i;
+ TKoreanDate fixDate = aKoreanDate;
+
+ /* Check if month length fix is needed */
+ for( i = 0 ; i < KMonthExceptionCnt ; i++ )
+ {
+ if( (KMonthExceptions[i].cycle == fixDate.iCycle &&
+ KMonthExceptions[i].year == fixDate.iYear &&
+ fixDate.iMonth != 1) ||
+ (fixDate.iMonth == 1 &&
+ (KMonthExceptions[i].year == (fixDate.iYear - 1) &&
+ KMonthExceptions[i].cycle == fixDate.iCycle) ||
+ (KMonthExceptions[i].year == 60 && fixDate.iYear == 1 &&
+ KMonthExceptions[i].cycle == (fixDate.iCycle - 1))) )
+ { /* Year may contain an exception */
+ if( (KMonthExceptions[i].koreanMonth == fixDate.iMonth &&
+ KMonthExceptions[i].isLeapMonth == fixDate.iLeapMonth) )
+ { /* Month contains an exception */
+ if( fixDate.iDay == 30 )
+ { /* Fix the last day to be the first day of next month */
+ fixDate.iDay = 1;
+ if( fixDate.iMonth == 12 )
+ {
+ fixDate.iMonth = 1;
+ if( fixDate.iYear == 60 )
+ {
+ fixDate.iYear = 1;
+ fixDate.iCycle += 1;
+ }
+ else
+ {
+ fixDate.iYear += 1;
+ }
+ }
+ else
+ {
+ if( KMonthExceptions[i].nextIsLeapMonth )
+ { /* Leap months don't need increasing,
+ just set the flag */
+ fixDate.iLeapMonth = ETrue;
+ }
+ else
+ {
+ fixDate.iLeapMonth = EFalse;
+ fixDate.iMonth += 1;
+ }
+ }
+ }
+ break;
+ }
+ else if( (KMonthExceptions[i].koreanMonth == (fixDate.iMonth - 1) &&
+ !(KMonthExceptions[i].nextIsLeapMonth || fixDate.iLeapMonth)) ||
+ (KMonthExceptions[i].koreanMonth == 12 && fixDate.iMonth == 1) ||
+ (KMonthExceptions[i].koreanMonth == fixDate.iMonth &&
+ KMonthExceptions[i].nextIsLeapMonth && fixDate.iLeapMonth) )
+ { /* It is the month following the exception, increase the day by one */
+ if( fixDate.iDay == 30 )
+ { /* Invalid day, Korean Lunar calendar has always only 29 days
+ after the exception month */
+ User::Leave( KErrArgument );
+ }
+ else
+ {
+ fixDate.iDay += 1;
+ }
+ break;
+ }
+ }
+ }
+
+ /* Check if leap month fix is needed */
+ for( i = 0 ; i < KLeapExceptionCnt ; i++ )
+ {
+ if( KLeapExceptions[i].cycle == fixDate.iCycle &&
+ KLeapExceptions[i].year == fixDate.iYear )
+ { /* Year contains an exception */
+ if( KLeapExceptions[i].koreanLeapMonth != fixDate.iMonth &&
+ fixDate.iLeapMonth )
+ { /* This year does not have the requested leap month in
+ Korean lunar calendar, leave with error */
+ User::Leave( KErrArgument );
+ }
+
+ if( fixDate.iMonth == KLeapExceptions[i].koreanLeapMonth &&
+ fixDate.iLeapMonth )
+ { /* Leap month in Korean lunar calendar, but not in Chinese
+ lunar calendar, fix by clearing the leap indicator*/
+ fixDate.iLeapMonth = EFalse;
+ if( KLeapExceptions[i].koreanLeapMonth < KLeapExceptions[i].chineseLeapMonth )
+ { /* Also month needs to be increased */
+ fixDate.iMonth += 1;
+ }
+ }
+ else if( fixDate.iMonth > KLeapExceptions[i].koreanLeapMonth &&
+ fixDate.iMonth < KLeapExceptions[i].chineseLeapMonth )
+ { /* Month between the leap month */
+ if( KLeapExceptions[i].koreanLeapMonth < KLeapExceptions[i].chineseLeapMonth )
+ {
+ fixDate.iMonth += 1;
+ }
+ else
+ {
+ fixDate.iMonth -= 1;
+ }
+ }
+ else if( fixDate.iMonth == (KLeapExceptions[i].chineseLeapMonth + 1) &&
+ !fixDate.iLeapMonth )
+ { /* Leap month in Chinese lunar calendar, fix by decreasing
+ the monrth by one and setting the leap indicator */
+ fixDate.iMonth -= 1;
+ fixDate.iLeapMonth = ETrue;
+ }
+ chineseConv->ChineseToDateTimeL( fixDate, aDateTime );
+
+ TRACE_EXIT_POINT;
+ return;
+ }
+ }
+ /* Use the chinese converter for result */
+ chineseConv->ChineseToDateTimeL( fixDate, aDateTime );
+ TRACE_EXIT_POINT;
+ }
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::DateRange
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CKoreanCalConv::DateRange( TDateTime& aLower, TDateTime& aUpper )
+ {
+ TRACE_ENTRY_POINT;
+ aLower.SetYear( 1900 );
+ aLower.SetMonth( EJanuary );
+ aLower.SetDay( 1 );
+ aUpper.SetYear( 2099 );
+ aUpper.SetMonth( EDecember );
+ aUpper.SetDay( 31 );
+ TRACE_EXIT_POINT;
+ }
+
+// -----------------------------------------------------------------------------
+// CKoreanCalConv::DateRange
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CKoreanCalConv::DateRange( TKoreanDate& aLower, TKoreanDate& aUpper )
+ {
+ TRACE_ENTRY_POINT;
+ aLower.iCycle = 76;
+ aLower.iYear = 36;
+ aLower.iMonth = 12;
+ aLower.iDay = 1;
+ aLower.iLeapMonth = EFalse;
+ aUpper.iCycle = 79;
+ aUpper.iYear = 56;
+ aUpper.iMonth = 11;
+ aUpper.iDay = 20;
+ aUpper.iLeapMonth = EFalse;
+ TRACE_EXIT_POINT;
+ }
+
+// End of file