⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datelunar.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 *
 * Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
 *
 * File: DateLunar.c
 *
 * Release: Palm OS 5 SDK (68K) R3.
 *
 * Description:
 *	  This file contains the (temporary) lunar calendar support for the
 *	Datebook application.  These routines will be part of Time Manager 6.0.
 *
 *****************************************************************************/

#include <PalmTypes.h>

#include <Chars.h>
#include <DateTime.h>
#include <DataMgr.h>						// For DmGetResource
#include <ErrorMgr.h>
#include <MemoryMgr.h>					// For memErrInvalidParam
#include <StringMgr.h>					// For StrNCopy, StrIToA, etc
#include <TextMgr.h>						// For TxtReplaceStr
#include <SysUtils.h>					// For SysStringByIndex
#include "UIResources.h"				// For strListRscType

#include "DateLunar.h"

/* Drop this in here so that the table processing code can be more easily
ported to Sahara.
*/
#ifndef BUS_ALIGN
	#define  BUS_ALIGN_16       	16     // 16-bit data must be read/written at 16-bit address
	#define  BUS_ALIGN_32			32     // 32-bit data must be read/written at 32-bit address
	#define BUS_ALIGN BUS_ALIGN_16
#endif

/***********************************************************************
 * Private constants
 **********************************************************************/

/* Resource types and IDs
*/
#define kLunarCalendarSupportedID			10200
#define kMiscStrListID							10208
#define kLunarStemsStrListID					10209
#define kLunarBranchesStrListID				10210
#define kLunarAnimalsStrListID				10211
#define kLunarMonthsStrListID					10212
#define kLunarDaysStrListID					10213
#define kLunarCalendarRscType					'luca'	// Lunar calendar data
#define kChineseLunarCalendarID				19000		// Chinese lunar calendar data

/* Max length of any date template string (before expansion), excluding the null.
*/
#define				maxDateTemplateLen					31	

const
UInt16				kLunarCalendarDataVersion			= 1;

/* Maximum substring lengths for building Chinese lunar date string
*/
#define				kMaxLunarStemStrLen					15
#define				kMaxLunarBranchStrLen				15
#define				kMaxLunarAnimalStrLen				15
#define				kMaxLunarMonthStrLen					15
#define				kMaxLunarDayStrLen					15
#define				kMaxLunarLeapMonthStrLen			15

/* Miscellaneous string list resource (kMiscStrListID) indexes
*/
const
UInt16				kLunarTemplateMiscStrListIndex	= 0;
const
UInt16				kLunarLeapMonthMiscStrListIndex	= 1;

/* Substring parameter indexes for building Chinese lunar date string
*/
const
UInt16				kLunarStemParamIndex					= 0;
const
UInt16				kLunarBranchParamIndex				= 1;
const
UInt16				kLunarAnimalParamIndex				= 2;
const
UInt16				kLunarMonthParamIndex				= 3;
const
UInt16				kLunarDayParamIndex					= 4;
const
UInt16				kLunarLeapMonthParamIndex			= 5;

/***********************************************************************
 * Private macros
 ***********************************************************************/

/* Convert <inputValue> from 68K format to ARM format (or vice-versa)
and put the result in <outputValue>.

WARNING!	The <inputValue> and <outputValue> arguments are evaluated more
			than once, and cannot refer to the same area of memory.
*/
#define	SwapBytes_(inputValue, outputValue)												\
				switch (sizeof(outputValue)) {												\
					case 1:																			\
						outputValue = inputValue;												\
					break;																			\
					case 2:																			\
						((UInt8*)&outputValue)[0] = ((UInt8*)(&inputValue))[1];		\
						((UInt8*)&outputValue)[1] = ((UInt8*)(&inputValue))[0];		\
					break;																			\
					case 4:																			\
						((UInt8*)&outputValue)[0] = ((UInt8*)(&inputValue))[3];		\
						((UInt8*)&outputValue)[1] = ((UInt8*)(&inputValue))[2];		\
						((UInt8*)&outputValue)[2] = ((UInt8*)(&inputValue))[1];		\
						((UInt8*)&outputValue)[3] = ((UInt8*)(&inputValue))[0];		\
					break;																			\
				}

/***********************************************************************
 * Private types
 **********************************************************************/

/* Description of a single month in the Chinese lunar calendar 
*/
typedef struct _LunarMonthType LunarMonthType;
struct _LunarMonthType {
	UInt8		monthNumber;		// 1..13 (0 if unused)
	UInt8		daysInThisMonth;	// 29..30 (0 if unused)
};

/* Description of a single year in the Chinese solar/lunar calendar
*/
typedef struct _LunarYearType LunarYearType;
struct _LunarYearType {
	Int32					yearStartDay;		// Offset from 1904-1-1, -337..46409 (1903-1-29..2031-1-23)
	LunarMonthType		lunarMonths[timMaxChineseLunarMonths];		// Month info array (last might not be used)
};

/* Database of lunar calendar information

The complete database is (2+4+(13*2))*128=4096 bytes.
*/
typedef struct _LunarCalendarDataType LunarCalendarDataType;
struct _LunarCalendarDataType {
	UInt16				version;
	UInt16				lunarYearOfYearIndex0;	// Position of lunarYear[0] in sexigesimal cycle 1..60
	UInt16				numKnownYears;		// # elements in lunarYears
	LunarYearType		lunarYears[1];		// Variable length record
};

/***********************************************************************
 * Private forward declarations
 ***********************************************************************/

static LunarCalendarDataType*
PrvGetLunarCalendarP(void);

static UInt16
PrvFindLunarYearIndex(
	const
	LunarCalendarDataType*	iLunarCalendarDataP,
	Int32					iDayCount);

static Char*
PrvStringByIndex(
	UInt16				iStringListID,
	UInt16				iStringIndex,
	Char*					oResultStr,
	UInt16				iMaxSize);

/***********************************************************************
 * Private global variables
 ***********************************************************************/

static
LunarCalendarDataType*	pLunarCalendarP = NULL;


/***********************************************************************/
Boolean
DateSupportsLunarCalendar(void)
/*
Return true if the system locale supports the Chinese lunar calendar.
*/
{
	Boolean				systemSupportsLunarCalendar
								= (Boolean)ResLoadConstant(kLunarCalendarSupportedID);

	return(systemSupportsLunarCalendar);

} // DateSupportsLunarCalendar

  
/***********************************************************************/
Err
DateSecondsToLunarDate(
	UInt32				iSeconds,
	UInt16*				oLunarYear,
	UInt16*				oLunarMonth,
	UInt16*				oLunarDay,
	Boolean*				oIsLeapMonth)
/*
Convert <iSeconds> (since 1/1/1904) to the Chinese *<oLunarYear>,
*<oLunarMonth> and *<oLunarDay>.  Set *<oIsLeapMonth> to true if this is
the second month in this year with *<oLunarMonth>.
*/
{
	LunarCalendarDataType*	chineseLunarCalendarP = NULL;
	Int32					dayCount;
	LunarYearType*		lunarYearP = NULL;
	UInt16				lunarYearIndex;
	UInt16				lunarMonthIndex;
	Int32					yearStartDay;
	UInt16				lunarYearOfYearIndex0;

	/* Initialize our outputs in case we're unsuccessful.
	*/
	*oLunarYear = 1;
	*oLunarMonth = 1;
	*oLunarDay = 1;
	*oIsLeapMonth = false;

	if (!DateSupportsLunarCalendar())
		return(timErrNoLunarCalendarSupport);

	/* Convert the input seconds to days since 1904
	*/
	dayCount = iSeconds / daysInSeconds;

	/* Grab the lunar calendar resource
	*/
	chineseLunarCalendarP = PrvGetLunarCalendarP();
	if (!chineseLunarCalendarP) {
		ErrNonFatalDisplay("Unable to load lunar calendar data resource.");
		return(timErrNoLunarCalendarSupport);
	}

	/* Find the year record that corresponds to this date, and calculate its
	position in the sexigesimal cycle.
	*/
#if BUS_ALIGN == BUS_ALIGN_32
	lunarYearOfYearIndex0 = chineseLunarCalendarP->lunarYearOfYearIndex0;
#else
	SwapBytes_(chineseLunarCalendarP->lunarYearOfYearIndex0, lunarYearOfYearIndex0);
#endif
	lunarYearIndex = PrvFindLunarYearIndex(chineseLunarCalendarP, dayCount);
	lunarYearP =	(	chineseLunarCalendarP->lunarYears
						+	lunarYearIndex);
	*oLunarYear =	(	(	(	lunarYearIndex
								+	lunarYearOfYearIndex0
								-	timFirstChineseLunarYear)
							%	(	timLastChineseLunarYear
								-	timFirstChineseLunarYear
								+	1))
						+	timFirstChineseLunarYear);

	/* We now know the year, and can calculate day number within it.
	*/
#if BUS_ALIGN == BUS_ALIGN_32
	yearStartDay = lunarYearP->yearStartDay;
#else
	SwapBytes_(lunarYearP->yearStartDay, yearStartDay);
#endif
	*oLunarDay = (UInt16)(dayCount - yearStartDay);

	/* Search for the correct lunar month, and calculate the lunar day.
	*/
	for (	lunarMonthIndex = 0;
			*oLunarDay >= lunarYearP->lunarMonths[lunarMonthIndex].daysInThisMonth;
			lunarMonthIndex++) {
		if (	(lunarMonthIndex >= timMaxChineseLunarMonths)
			||	(lunarYearP->lunarMonths[lunarMonthIndex].monthNumber == 0)
			||	(lunarYearP->lunarMonths[lunarMonthIndex].daysInThisMonth == 0)) {
			ErrNonFatalDisplay("Unable to find correct lunar month in lunar year.");
			return(timErrNoLunarCalendarSupport);
		}
		(*oLunarDay) -= lunarYearP->lunarMonths[lunarMonthIndex].daysInThisMonth;
	}
	(*oLunarDay)++;	// First day in month is returned as 1 (not 0)

	/* Return its month number and whether it's a leap month
	*/
	*oLunarMonth = lunarYearP->lunarMonths[lunarMonthIndex].monthNumber;
	*oIsLeapMonth =	(	(lunarMonthIndex > 0)
							&&	(	lunarYearP->lunarMonths[lunarMonthIndex-1].monthNumber
								==	lunarYearP->lunarMonths[lunarMonthIndex].monthNumber));

	return(errNone);

} // DateSecondsToLunarDate


/***********************************************************************/
Err
DateToLunarStr(
	UInt16				iLunarYear,
	UInt16				iLunarMonth,
	UInt16				iLunarDay,
	Boolean				iIsLeapMonth,
	Char*					oLunarDateStr,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -