PackedDateTime packNow() { int year, dayOfYear, secOfDay, tzSeconds; int64_t days, usecs; localdate(&year, &dayOfYear, &secOfDay, &tzSeconds); days = daysSinceEpochYD(YearDay(year, dayOfYear)); usecs = secOfDay * USECS_PER_SEC; return packDaysUseconds(days, usecs - tzSeconds * USECS_PER_SEC); }
YearDay unpackYearDay(PackedDateTime dateTime, int timezone) { int year = 0, day = 0; auto days = (dateTime + timezone * USECS_PER_SEC) / USECS_PER_DAY; toInternalYD(&year, &day, days); if (day >= ACCUMULATED_DAYS[10]) { day -= ACCUMULATED_DAYS[10]; } else { --year; day += 31 + (isLeapYear(year) ? 29 : 28); } return YearDay(year, day + 1); }
// 计算*this和ref之间相差的天数,要求ref.IsPrior(*this)为真 int ChineseDate::DoDiff(const ChineseDate &ref) const { assert(!IsPrior(ref)); // *this >= ref int days = 0; // 首先计算两个年份的1月1日相差的天数 for (int year = ref.m_year; year < m_year; ++year) { days += ChineseCalendarDB::GetYearDays(year); } // 处理月和日 days += YearDay(); days -= ref.YearDay(); return days; }
// 向前(未来)调整指定天数(注意:不能调整到农历2050年12月30日之后) // 如果调整成功,则返回true;否则返回false(此时*this在调用前后不会发生改变) bool ChineseDate::DoAdjustForward(int days) { assert(days > 0); if (ChineseDate(2050, 12, 30).DoDiff(*this) < days) return false; // 不能调整到农历2050年12月30日之后 // 以每年最后一天为参考点进行计算 days += YearDay(); int yearDays = ChineseCalendarDB::GetYearDays(m_year); while (days > yearDays) { days -= yearDays; ++m_year; yearDays = ChineseCalendarDB::GetYearDays(m_year); } FromYearDay(days); return true; }
// 向后(过去)调整指定天数(注意:不能调整到农历1901年1月1日之前) // 如果调整成功,则返回true;否则返回false(此时*this在调用前后不会发生改变) bool ChineseDate::DoAdjustBackward(int days) { assert(days > 0); if (this->DoDiff(ChineseDate(1901, 1, 1)) < days) return false; // 不能调整时间到农历1901年1月1日之前 // 以每年第一天(1月1日)为参考点进行计算 int yearDays = ChineseCalendarDB::GetYearDays(m_year); days += yearDays - YearDay(); while (days > yearDays) { days -= yearDays; --m_year; yearDays = ChineseCalendarDB::GetYearDays(m_year); } FromYearDay(yearDays - days); return true; }