📄 datelunar.c
字号:
UInt16 iMaxStrLen)
/*
Convert the Chinese <iLunarYear>, <iLunarMonth>, <iLunarDay> and
<iIsLeapMonth> into a Chinese string describing this lunar date,
and place the result in *<oLunarDateStr>, which can hold <iMaxStrLen>
bytes (excluding the null). timOmitLunarYear, timOmitLunarMonth,
and timOmitLunarDay may be passed in <iLunarYear>, <iLunarMonth> and
<iLunarDay> (respectively) in order to omit these portions of the string.
History:
2002-10-23 CS Added support for timOmitLunarYear, timOmitLunarMonth,
and timOmitLunarDay.
2003-01-17 CS Build output in separate buffer in case caller's
isn't long enough for temporary results (i.e., caller
is omitting one or more fields, but we haven't yet
removed the replacement tokens from the template).
*/
{
Char stemStr[kMaxLunarStemStrLen+1];
Char branchStr[kMaxLunarBranchStrLen+1];
Char animalStr[kMaxLunarAnimalStrLen+1];
Char monthStr[kMaxLunarMonthStrLen+1];
Char dayStr[kMaxLunarDayStrLen+1];
Char leapMonthStr[kMaxLunarLeapMonthStrLen+1];
Char lunarDateStr[timMaxLunarDateStrLen+1];
stemStr[0] = 0;
branchStr[0] = 0;
animalStr[0] = 0;
monthStr[0] = 0;
dayStr[0] = 0;
leapMonthStr[0] = 0;
if (!DateSupportsLunarCalendar())
return(timErrNoLunarCalendarSupport);
/* Load the template string and then jam it with the year stem & branch,
animal, month, optional leap month text, and day.
*/
PrvStringByIndex( kMiscStrListID,
kLunarTemplateMiscStrListIndex,
lunarDateStr,
timMaxLunarDateStrLen+1);
if (StrLen(lunarDateStr) == 0) {
ErrNonFatalDisplay("Unable to load lunar date template.");
return(timErrNoLunarCalendarSupport);
}
if (iLunarYear != timOmitLunarYear) {
PrvStringByIndex( kLunarStemsStrListID,
(UInt16) ( (iLunarYear-timFirstChineseLunarYear)
% timNumChineseStems),
stemStr,
kMaxLunarStemStrLen+1);
if (StrLen(stemStr) == 0) {
ErrNonFatalDisplay("Unable to load lunar stem string.");
return(timErrNoLunarCalendarSupport);
}
PrvStringByIndex( kLunarBranchesStrListID,
(UInt16) ( (iLunarYear-timFirstChineseLunarYear)
% timNumChineseBranches),
branchStr,
kMaxLunarBranchStrLen+1);
if (StrLen(branchStr) == 0) {
ErrNonFatalDisplay("Unable to load lunar branch string.");
return(timErrNoLunarCalendarSupport);
}
PrvStringByIndex( kLunarAnimalsStrListID,
(UInt16) ( (iLunarYear-timFirstChineseLunarYear)
% timNumChineseBranches),
animalStr,
kMaxLunarAnimalStrLen+1);
if (StrLen(animalStr) == 0) {
ErrNonFatalDisplay("Unable to load lunar year animal string.");
return(timErrNoLunarCalendarSupport);
}
}
TxtReplaceStr( lunarDateStr,
timMaxLunarDateStrLen,
stemStr,
kLunarStemParamIndex);
TxtReplaceStr( lunarDateStr,
timMaxLunarDateStrLen,
branchStr,
kLunarBranchParamIndex);
TxtReplaceStr( lunarDateStr,
timMaxLunarDateStrLen,
animalStr,
kLunarAnimalParamIndex);
if (iLunarMonth != timOmitLunarMonth) {
PrvStringByIndex( kLunarMonthsStrListID,
(UInt16)(iLunarMonth-timFirstChineseLunarMonth),
monthStr,
kMaxLunarMonthStrLen+1);
if (StrLen(monthStr) == 0) {
ErrNonFatalDisplay("Unable to load lunar month string.");
return(timErrNoLunarCalendarSupport);
}
}
TxtReplaceStr( lunarDateStr,
timMaxLunarDateStrLen,
monthStr,
kLunarMonthParamIndex);
if (iLunarDay != timOmitLunarDay) {
PrvStringByIndex( kLunarDaysStrListID,
(UInt16)(iLunarDay-timFirstChineseLunarDay),
dayStr,
kMaxLunarDayStrLen+1);
if (StrLen(dayStr) == 0) {
ErrNonFatalDisplay("Unable to load lunar day string.");
return(timErrNoLunarCalendarSupport);
}
}
TxtReplaceStr( lunarDateStr,
timMaxLunarDateStrLen,
dayStr,
kLunarDayParamIndex);
if ( (iLunarMonth != timOmitLunarMonth)
&& (iIsLeapMonth)) {
PrvStringByIndex( kMiscStrListID,
kLunarLeapMonthMiscStrListIndex,
leapMonthStr,
kMaxLunarLeapMonthStrLen+1);
if (StrLen(leapMonthStr) == 0) {
ErrNonFatalDisplay("Unable to load lunar leap month string.");
return(timErrNoLunarCalendarSupport);
}
}
TxtReplaceStr( lunarDateStr,
timMaxLunarDateStrLen,
leapMonthStr,
kLunarLeapMonthParamIndex);
/* Now that we've built the result, copy it to the caller's buffer.
DOLATER CS - Return an error if result doesn't fit?
*/
if (StrLen(lunarDateStr) <= iMaxStrLen) {
StrCopy(oLunarDateStr, lunarDateStr);
} else {
UInt16 truncatedLen = TxtGetTruncationOffset(lunarDateStr, iMaxStrLen);
MemMove( oLunarDateStr,
lunarDateStr,
truncatedLen);
oLunarDateStr[truncatedLen] = chrNull;
ErrNonFatalDisplay("Lunar date string overflows buffer.");
}
return(errNone);
} // DateToLunarStr
/***********************************************************************/
Boolean
SelectLunarDayIsSupported(void)
/*
Return true if there is a Chinese lunar calendar application installed
(used by the DateBook application).
*/
{
// DOLATER CS - Implement this routine.
return(false);
} // SelectLunarDayIsSupported
/***********************************************************************/
void
TerminateDateLunar(void)
/*
Temporary routine to unlock resources used by the lunar calendar support
code, etc.
*/
{
if (pLunarCalendarP) {
MemPtrUnlock(pLunarCalendarP);
}
pLunarCalendarP = NULL;
} // TerminateDateLunar
/***********************************************************************/
static LunarCalendarDataType*
PrvGetLunarCalendarP(void)
/*
Return a pointer to the locked lunar calendar data resource.
*/
{
if (!pLunarCalendarP) {
MemHandle lunarCalendarH = NULL;
UInt16 version;
lunarCalendarH = DmGetResource( kLunarCalendarRscType,
kChineseLunarCalendarID);
if (lunarCalendarH) {
pLunarCalendarP = MemHandleLock(lunarCalendarH);
#if BUS_ALIGN == BUS_ALIGN_32
version = pLunarCalendarP->version;
#else
SwapBytes_(pLunarCalendarP->version, version);
#endif
if (version != kLunarCalendarDataVersion) {
return(NULL);
}
}
}
return(pLunarCalendarP);
} // PrvGetLunarCalendarP
/***********************************************************************/
static UInt16
PrvFindLunarYearIndex(
const
LunarCalendarDataType* iLunarCalendarDataP,
Int32 iDayCount)
/*
Return the index into <iLunarCalendarDataP>->lunarYears of the lunar year
in which <iDayCount> (since 1904-1-1) appears, where *<iLunarCalendarDataP>
contains a description of all supported lunar years.
DOLATER CS - Do the bsearch thing here.
*/
{
UInt16 lunarYearIndex;
UInt16 numKnownYears;
#if BUS_ALIGN == BUS_ALIGN_32
numKnownYears = pLunarCalendarP->numKnownYears;
#else
SwapBytes_(pLunarCalendarP->numKnownYears, numKnownYears);
#endif
for ( lunarYearIndex = numKnownYears-1;
lunarYearIndex >= 0;
lunarYearIndex--) {
Int32 yearStartDay;
#if BUS_ALIGN == BUS_ALIGN_32
yearStartDay
= iLunarCalendarDataP->lunarYears[lunarYearIndex].yearStartDay;
#else
SwapBytes_( iLunarCalendarDataP->lunarYears[lunarYearIndex].yearStartDay,
yearStartDay);
#endif
if (iDayCount >= yearStartDay) {
/* If date is beyond beginning of last year in data, then we need to
make sure it's not beyond the end of the last year.
*/
if (lunarYearIndex == (numKnownYears-1)) {
UInt16 monthIndex;
UInt16 daysInLastYear = 0;
for ( monthIndex = 0;
monthIndex < timMaxChineseLunarMonths;
monthIndex++) {
daysInLastYear += iLunarCalendarDataP->lunarYears[lunarYearIndex].lunarMonths[monthIndex].daysInThisMonth;
}
if (iDayCount >= (yearStartDay + daysInLastYear)) {
break;
}
}
return(lunarYearIndex);
}
}
ErrNonFatalDisplay("Unable to find lunar year for input date.");
return(0);
} // PrvFindLunarYearIndex
/***********************************************************************/
static Char*
PrvStringByIndex(
UInt16 iStringListID,
UInt16 iStringIndex,
Char* oResultStr,
UInt16 iMaxSize)
/*
Place the <iStringIndex>th string from the tSTL resource <stringListID>
(including the prefix string) into <oResultStr>, and return the result.
Copy at most <iMaxSize> bytes of it (including the chrNull).
*/
{
return(SysStringByIndex(iStringListID, iStringIndex, oResultStr, iMaxSize));
} // PrvStringByIndex
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -