计算农历的函数
函数|农历
代码:--------------------------------------------------------------------------------
[本篇全文] [回复本文] [本篇作者: top ] [本篇人气: 10]
发信人: top (英语六级&&PHP), 信区: Programming
标 题: 阴阳历算法
发信站: 燕赵 BBS (Tue Apr 8 12:14:16 2003), 转信
http://linux.tcpip.com.cn
阴阳历算法
发言者:kent 发言时间:2001-11-08 12:03:11
程序为:
/*
prototype: int calconv( struct convdate * );
struct convdate
{
int source; ==0 则输入日期为西历, !=0 则输入为农历
int solaryear; 输出或输入之西历年份
int solarmonth; 西历月
int solardate; 西历日
int lunaryear; 输出或输入之农历年份
int lunarmonth; 农历月
int lunarmonth; 农历月
int lunardate; 农历日
int weekday; 该日为星期几 ( 0==星期日, 1==星期一, ... )
int kan; 该日天干 ( 0==甲, 1==乙, ..., 9==癸 )
int chih; 该日地支 ( 0==子, 1==丑, ..., 11==亥 )
};
呼叫时须设定 souce 的值, 若为 0 则为西历转农历, 否则为农历转西历. 然後视
输入为西历或农历来设定西历或农历的年月日. 转换後的年月日会填入结构中( 农
历或西历 ), 以及该日为星期几, 天干地支.
若函式的返回值为 0 表示没有错误, 1 为输入之年份错误, 2 为输入之月份错误
,
3 为输入之日期错误.
输入之西历年须在 1937 - 2031 间
输入之农历年须在 1936 - 2030 间
若须扩充, 则增加 lunarcal[]
*/
#define firstyear 1936 /* the first year in lunarcal[] */
struct convdate
{
int source;
int source;
int solaryear;
int solarmonth;
int solardate;
int lunaryear;
int lunarmonth;
int lunardate;
int weekday;
int kan;
int chih;
};
struct taglunarcal
{
int basedays; /* 到西历 1 月 1 日到农历正月初一的累积日数 */
int intercalation; /* 闰月月份. 0==此年没有闰月 */
int baseweekday; /* 此年西历 1 月 1 日为星期几再减 1 */
int basekanchih; /* 此年西历 1 月 1 日之干支序号减 1 */
int monthdays[13]; /* 此农历年每月之大小, 0==小月(29日), 1==大月(30日
)*/
};
struct taglunarcal lunarcal[] = {
{ 23, 3, 2, 17, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, /* 1936 */
{ 23, 3, 2, 17, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, /* 1936 */
{ 41, 0, 4, 23, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
{ 30, 7, 5, 28, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 },
{ 49, 0, 6, 33, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 38, 0, 0, 38, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 1940 */
{ 26, 6, 2, 44, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 45, 0, 3, 49, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 35, 0, 4, 54, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 24, 4, 5, 59, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1944 */
{ 43, 0, 0, 5, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
{ 32, 0, 1, 10, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 },
{ 21, 2, 2, 15, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 40, 0, 3, 20, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, /* 1948 */
{ 28, 7, 5, 26, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 47, 0, 6, 31, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 36, 0, 0, 36, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 26, 5, 1, 41, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, /* 1952 */
{ 44, 0, 3, 47, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 33, 0, 4, 52, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },
{ 23, 3, 5, 57, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
{ 42, 0, 6, 2, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 }, /* 1956 */
{ 30, 8, 1, 8, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 48, 0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 48, 0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 38, 0, 3, 18, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
{ 27, 6, 4, 23, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 1960 */
{ 45, 0, 6, 29, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 },
{ 35, 0, 0, 34, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 24, 4, 1, 39, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
{ 43, 0, 2, 44, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, /* 1964 */
{ 32, 0, 4, 50, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
{ 20, 3, 5, 55, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
{ 39, 0, 6, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 29, 7, 0, 5, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 1968 */
{ 47, 0, 2, 11, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 36, 0, 3, 16, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
{ 26, 5, 4, 21, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
{ 45, 0, 5, 26, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1972 */
{ 33, 0, 0, 32, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 },
{ 22, 4, 1, 37, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
{ 41, 0, 2, 42, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 },
{ 30, 8, 3, 47, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, /* 1976 */
{ 48, 0, 5, 53, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1 },
{ 37, 0, 6, 58, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 27, 6, 0, 3, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
{ 46, 0, 1, 8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 1980 */
{ 46, 0, 1, 8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 1980 */
{ 35, 0, 3, 14, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
{ 24, 4, 4, 19, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 43, 0, 5, 24, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 32, 10, 6, 29, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 }, /* 1984 */
{ 50, 0, 1, 35, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 39, 0, 2, 40, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1 },
{ 28, 6, 3, 45, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0 },
{ 47, 0, 4, 50, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 1988 */
{ 36, 0, 6, 56, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 },
{ 26, 5, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1 },
{ 45, 0, 1, 6, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0 },
{ 34, 0, 2, 11, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 }, /* 1992 */
{ 22, 3, 4, 17, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 40, 0, 5, 22, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 30, 8, 6, 27, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1 },
{ 49, 0, 0, 32, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1 }, /* 1996 */
{ 37, 0, 2, 38, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 27, 5, 3, 43, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 46, 0, 4, 48, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
{ 35, 0, 5, 53, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 }, /* 2000 */
{ 23, 4, 0, 59, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 42, 0, 1, 4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 42, 0, 1, 4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 31, 0, 2, 9, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 21, 2, 3, 14, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 2004 */
{ 39, 0, 5, 20, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 28, 7, 6, 25, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },
{ 48, 0, 0, 30, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
{ 37, 0, 1, 35, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 2008 */
{ 25, 5, 3, 41, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 44, 0, 4, 46, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 33, 0, 5, 51, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 22, 4, 6, 56, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 2012 */
{ 40, 0, 1, 2, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 30, 9, 2, 7, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 49, 0, 3, 12, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
{ 38, 0, 4, 17, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 2016 */
{ 27, 6, 6, 23, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
{ 46, 0, 0, 28, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 },
{ 35, 0, 1, 33, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
{ 24, 4, 2, 38, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 2020 */
{ 42, 0, 4, 44, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
{ 31, 0, 5, 49, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 21, 2, 6, 54, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 40, 0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 2024 */
{ 40, 0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 2024 */
{ 28, 6, 2, 5, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
{ 47, 0, 3, 10, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 },
{ 36, 0, 4, 15, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
{ 25, 5, 5, 20, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, /* 2028 */
{ 43, 0, 0, 26, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },
{ 32, 0, 1, 31, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
{ 22, 3, 2, 36, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 } };
#define lastyear (firstyear+sizeof(lunarcal)/sizeof(struct
taglunarcal)-1)
/* 西历年每月之日数 */
int solarcal[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/* 西历年每月之累积日数, 平年与闰年 */
int solardays[2][14] = {
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396 },
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 397 } };
/* 求此西历年是否为闰年, 返回 0 为平年, 1 为闰年 */
int getleap( int year )
{
if ( year % 400 == 0 )
if ( year % 400 == 0 )
return 1;
else if ( year % 100 == 0 )
return 0;
else if ( year % 4 == 0 )
return 1;
else
return 0;
}
/* 西历农历转换 */
int calconv( struct convdate *cd )
{
int leap, d, sm, y, im, l1, l2, acc, i, lm, kc;
if ( cd->source == 0 ) /* solar */
{
if ( cd->solaryear solaryear > lastyear )
return 1;
sm = cd->solarmonth - 1;
if ( sm 11 )
return 2;
leap = getleap( cd->solaryear );
if ( sm == 1 )
if ( sm == 1 )
d = leap + 28;
else
d = solarcal[sm];
if ( cd->solardate solardate > d )
return 3;
y = cd->solaryear - firstyear;
acc = solardays[leap][sm] + cd->solardate;
cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
kc = acc + lunarcal[y].basekanchih;
cd->kan = kc % 10;
cd->chih = kc % 12;
if ( acc {
y--;
cd->lunaryear = cd->solaryear - 1;
leap = getleap( cd->lunaryear );
sm += 12;
acc = solardays[leap][sm] + cd->solardate;
}
else
cd->lunaryear = cd->solaryear;
l1 = lunarcal[y].basedays;
l1 = lunarcal[y].basedays;
for ( i=0; i{
l2 = l1 + lunarcal[y].monthdays[i] + 29;
if ( acc break;
l1 = l2;
}
cd->lunarmonth = i + 1;
cd->lunardate = acc - l1;
im = lunarcal[y].intercalation;
if ( im != 0 && cd->lunarmonth > im )
{
cd->lunarmonth--;
if ( cd->lunarmonth == im )
cd->lunarmonth = -im;
}
if ( cd->lunarmonth > 12 )
cd->lunarmonth -= 12;
}
else /* lunar */
{
if ( cd->lunaryear lunaryear >= lastyear )
if ( cd->lunaryear lunaryear >= lastyear )
return 1;
y = cd->lunaryear - firstyear;
im = lunarcal[y].intercalation;
lm = cd->lunarmonth;
if ( lm {
if ( lm != -im )
return 2;
}
else if ( lm 12 )
return 2;
if ( im != 0 )
{
if ( lm > im )
lm++;
else if ( lm == -im )
lm = im + 1;
}
lm--;
if ( cd->lunardate > lunarcal[y].monthdays[lm] + 29 )
return 3;
acc = lunarcal[y].basedays;
acc = lunarcal[y].basedays;
for ( i=0; i acc += lunarcal[y].monthdays[i] + 29;
acc += cd->lunardate;
leap = getleap( cd->lunaryear );
for ( i=13; i>=0; i-- )
if ( acc > solardays[leap][i] )
break;
cd->solardate = acc - solardays[leap][i];
if ( i {
cd->solaryear = cd->lunaryear;
cd->solarmonth = i + 1;
}
else
{
cd->solaryear = cd->lunaryear + 1;
cd->solarmonth = i - 11;
}
leap = getleap( cd->solaryear );
y = cd->solaryear - firstyear;
acc = solardays[leap][cd->solarmonth-1] + cd->solardate;
cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
kc = acc + lunarcal[y].basekanchih;
{
cd->kan = kc % 10;
cd->chih = kc % 12;
}
return 0;
}

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Many users will choose the Huawei brand when choosing smart watches. Among them, Huawei GT3pro and GT4 are very popular choices. Many users are curious about the difference between Huawei GT3pro and GT4. Let’s introduce the two to you. . What are the differences between Huawei GT3pro and GT4? 1. Appearance GT4: 46mm and 41mm, the material is glass mirror + stainless steel body + high-resolution fiber back shell. GT3pro: 46.6mm and 42.9mm, the material is sapphire glass + titanium body/ceramic body + ceramic back shell 2. Healthy GT4: Using the latest Huawei Truseen5.5+ algorithm, the results will be more accurate. GT3pro: Added ECG electrocardiogram and blood vessel and safety

Why Snipping Tool Not Working on Windows 11 Understanding the root cause of the problem can help find the right solution. Here are the top reasons why the Snipping Tool might not be working properly: Focus Assistant is On: This prevents the Snipping Tool from opening. Corrupted application: If the snipping tool crashes on launch, it might be corrupted. Outdated graphics drivers: Incompatible drivers may interfere with the snipping tool. Interference from other applications: Other running applications may conflict with the Snipping Tool. Certificate has expired: An error during the upgrade process may cause this issu simple solution. These are suitable for most users and do not require any special technical knowledge. 1. Update Windows and Microsoft Store apps

Detailed explanation of the method of converting int type to byte in PHP In PHP, we often need to convert the integer type (int) to the byte (Byte) type, such as when dealing with network data transmission, file processing, or encryption algorithms. This article will introduce in detail how to convert the int type to the byte type and provide specific code examples. 1. The relationship between int type and byte In the computer field, the basic data type int represents an integer, while byte (Byte) is a computer storage unit, usually 8-bit binary data

In C++, variables of type int can only hold positive or negative integer values; they cannot hold decimal values. There are float and double values available for this purpose. The double data type was created to store decimals up to seven digits after the decimal point. Conversion of an integer to a double data type can be done automatically by the compiler (called an "implicit" conversion), or it can be explicitly requested by the programmer from the compiler (called an "explicit" conversion). In the following sections, we'll cover various conversion methods. Implicit conversions The compiler performs implicit type conversions automatically. To achieve this, two variables are required - one of floating point type and the other of integer type. When we simply assign a floating point value or variable to an integer variable, the compiler takes care of all the other things

Part 1: Initial Troubleshooting Steps Checking Apple’s System Status: Before delving into complex solutions, let’s start with the basics. The problem may not lie with your device; Apple's servers may be down. Visit Apple's System Status page to see if the AppStore is working properly. If there's a problem, all you can do is wait for Apple to fix it. Check your internet connection: Make sure you have a stable internet connection as the "Unable to connect to AppStore" issue can sometimes be attributed to a poor connection. Try switching between Wi-Fi and mobile data or resetting network settings (General > Reset > Reset Network Settings > Settings). Update your iOS version:

The value range of int32 is from -2 to the 31st power to 2 to the 31st power minus 1, that is, -2147483648 to 2147483647. int32 is a signed integer type, which means it can represent positive numbers, negative numbers, and zero. It uses 1 bit to represent the sign bit, and the remaining 31 bits are used to represent the numerical value. Since one bit is used to represent the sign bit, the effective number of int32 bits is 31.

In Java, int is a 32-bit signed data type, and its variables require 32-bit memory; the valid range of the int data type is -2147483648 to 2147483647, and all integers in this range are called integer literals. An integer literal can be assigned to an int variable, such as "int num1 = 21;".

The number of bytes occupied by the int type may vary in different programming languages and different hardware platforms. Detailed introduction: 1. In C language, the int type usually occupies 2 bytes or 4 bytes. In 32-bit systems, the int type occupies 4 bytes, while in 16-bit systems, the int type occupies 2 bytes. In a 64-bit system, the int type may occupy 8 bytes; 2. In Java, the int type usually occupies 4 bytes, while in Python, the int type has no byte limit and can be automatically adjusted, etc.
