日历程序
(www.Jojoo.net) 2002-1-8 (请双击自动滚屏观看,单击停止,再击..)
该 Java 程序可以显示 1582 年以后任一月的日历。用户可以在一个文本框里
输入年份,通过下拉框选择月份,然后点击“新日历”按纽,就可以显示那个
月的日历。可以通过在 HTML 文件里加入下面的语句,调用该程序,
<applet code>="Calendar.class" width=421 height=481></applet>
该程序假定在一个 421x481 象素的表面上绘制日历
语言: Java 平台: Unix, Windows
************************************************************************/
import java.applet.Applet;
import java.awt.*;
import java.util.Date;
public class Calendar extends Applet
{
static final int YTOP = 90; /* 日历上方的空白 */
static final int YHEADER = 30; /* 日期名称行的高度 */
static final int NCELLX = 7; /* 横行的方格数 */
static final int CELLSIZE = 60; /* 方格的大小 */
static final int MARGIN = 8; /* 数字距方格上方和右方的空白 */
static final int FEBRUARY = 1; /* 闰年的特殊月份 */
// 日历上方的控件.
Label yearLabel = new Label("Year:");
TextField yearTextField = new TextField("1996", 5);
Label monthLabel = new Label("Month:");
Choice monthChoice = new Choice();
Button newCalButton = new Button("New Calendar");
// 当前年份和月份的日期对象.
Date now = new Date();
// 日历上方的控件的字体.
Font smallArialFont = new Font("Arial", Font.PLAIN, 15);
// 日历上方年月标题的字体.
Font largeArialFont = new Font("Arial", Font.BOLD, 30);
String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
String months[] = {"January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December"};
int DaysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 用户输入的年和月.
int userMonth;
int userYear;
public void init()
/*
功能: 获取当前的年份和月份,初始化控件.
注意: 程序启动时,自动调用.
*/
{
setBackground(Color.white);
// 初始话月份和年份为当前值.
userMonth = now.getMonth();
userYear = now.getYear() + 1900;
// "Year:" 标签.
yearLabel.setFont(smallArialFont);
add(yearLabel);
// 输入年份的文本区.
yearTextField.setFont(smallArialFont);
yearTextField.setText(String.valueOf(userYear));
add(yearTextField);
// "Month:" 标签.
monthLabel.setFont(smallArialFont);
add(monthLabel);
// 输入月份的组合框.
monthChoice.setFont(smallArialFont);
for (int i = 0; i < 12; i++)
monthChoice.addItem(months[i]);
monthChoice.select(userMonth);
add(monthChoice);
// "新日历" 按纽.
newCalButton.setFont(smallArialFont);
add(newCalButton);
} // 初始化
public void paint(Graphics g)
/*
功能: 根据全局变量 userMonth 和 userYear 绘制日历.
注意: 当界面需要重画时会自动调用,用户点击"新日历" 按纽,也会触发重画功能.
*/
{
FontMetrics fm; /* 获取字体信息 */
int fontAscent; /* 字符高度 */
int dayPos; /* 日期字符串竖直方向的位置 */
int xSize, ySize; /* 日历的大小 (单元格) */
int numRows; /* 行数 (4, 5, 6) */
int xNum, yNum; /* number position at top right of cells */
int numDays; /* 该月的天数 */
String dayStr; /* 一周中星期字符串 */
int marg; /* margin of month string baseline from cell table */
String caption; /* 上方中心的月份 */
// 获取字体信息.
fm = g.getFontMetrics();
fontAscent = fm.getAscent();
dayPos = YTOP + (YHEADER + fontAscent) / 2;
// 日历的宽度 (单元格).
xSize = NCELLX * CELLSIZE;
// Header rectangle across top for day names.
g.drawRect(0, YTOP, xSize, YHEADER);
// Put days at top of each column, centered.
for (int i = 0; i < NCELLX; i++)
g.drawString(days[i], (CELLSIZE-fm.stringWidth(days[i]))/2 + i*CELLSIZE,
dayPos);
// 获取该月需要的行数
numRows = NumberRowsNeeded(userYear, userMonth);
// 表格的竖直线.
ySize = numRows * CELLSIZE;
for (int i = 0; i <= xSize; i += CELLSIZE)
g.drawLine(i, YTOP + YHEADER, i, YTOP + YHEADER + ySize);
// 表格的水平线.
for (int i = 0, j = YTOP + YHEADER; i <= numRows; i++, j += CELLSIZE)
g.drawLine(0, j, xSize, j);
// 初始数字的位置(右上角单元).
xNum = (CalcFirstOfMonth(userYear, userMonth) + 1) * CELLSIZE - MARGIN;
yNum = YTOP + YHEADER + MARGIN + fontAscent;
// 获取该月的天数, 如果是闰年的二月, 加一天.
numDays = DaysInMonth[userMonth] +
((IsLeapYear(userYear) && (userMonth == FEBRUARY)) ? 1 : 0);
// 在每个表格的右上角显示数字.
for (int day = 1; day <= numDays; day++)
{
dayStr = String.valueOf(day);
g.drawString(dayStr, xNum - fm.stringWidth(dayStr), yNum);
xNum += CELLSIZE;
if (xNum > xSize)
{
xNum = CELLSIZE - MARGIN;
yNum += CELLSIZE;
} // if
} // for
// 设置年月标题为大字体.
g.setFont(largeArialFont);
// 获取字体信息 (当前为大字体).
fm = g.getFontMetrics();
// 设置标题在竖直方向的空白.
marg = 2 * fm.getDescent();
// 设置标题为月份, 并在中间位置.
caption = months[userMonth] + " " + String.valueOf(userYear);
g.drawString(caption, (xSize-fm.stringWidth(caption))/2, YTOP - marg);
} // 绘制
public boolean action(Event e, Object o)
/*
功能: 刷新年月的全局变量, 当用户点击按纽时绘制.
*/
{
int userYearInt;
if (e.target instanceof Button)
{
if ("New Calendar".equals((String)o))
{
// 从组合框中选择月份.
userMonth = monthChoice.getSelectedIndex();
// 从文本框获取年份.
userYearInt = Integer.parseInt(yearTextField.getText(), 10);
if (userYearInt > 1581)
userYear = userYearInt;
// 调用 paint() 绘制新日历.
repaint();
return true;
}
}
return false;
}
int NumberRowsNeeded(int year, int month)
/*
功能: 计算日历需要的行数.
输入: year = 给出的 1582 年以后的年份.
month = 0 为一月, 1 为二月, 依次类推.
输出: 行数: 5 或 6, 只有当二月有28天, 同时一号为星期天时, 只需要4行.
*/
{
int firstDay; /* 该月的第一天的星期 */
int numCells; /* 该月需要的表格数 */
/* 年份应为 1582 年以后. */
if (year < 1582) return (-1);
/* 去除无效的月份. */
if ((month < 0) || (month > 11)) return (-1);
/* 获取该月的第一天. */
firstDay = CalcFirstOfMonth(year, month);
/* 如果是闰年的二月, 第一天是星期天, 返回 4 行. */
if ((month == FEBRUARY) && (firstDay == 0) && !IsLeapYear(year))
return (4);
/* 需要的表格数 = 第一行的空表格 + 该月的天数. */
numCells = firstDay + DaysInMonth[month];
/* 闰年需要为2月29日增加一格 */
if ((month == FEBRUARY) && (IsLeapYear(year))) numCells++;
/* 小于等于35格为5行,更多则为6行. */
return ((numCells <= 35) ? 5 : 6);
}
int CalcFirstOfMonth(int year, int month)
/*
功能: 计算该月第一天是星期几.
输入: year = 给出的 1582 年以后的年份.
month = 0 为一月, 1 为二月, 依次类推.
输出: 该月第一天的星期: 0 = 星期天, 1 = 星期一, 依次类推.
*/
{
int firstDay; /* 该年1月1日的星期,然后是该月第一天的星期 */
int i; /* 月份的循环变量 */
/* 年份应为 1582 年以后. */
if (year < 1582) return (-1);
/* 去除无效的月份. */
if ((month < 0) || (month > 11)) return (-1);
/* 获取该年1月1日的星期 */
firstDay = CalcJanuaryFirst(year);
/* 计算该月第一天是该年中的第几天. */
for (i = 0; i < month; i++)
firstDay += DaysInMonth[i];
/* 闰年二月份后的月份加一天 */
if ((month > FEBRUARY) && IsLeapYear(year)) firstDay++;
/* 转换为星期 */
return (firstDay % 7);
}
boolean IsLeapYear(int year)
/*
功能: 判断是否是闰年.
输入: year = 给出的 1582 年以后的年份.
输出: TRUE 是闰年, FALSE 不是.
*/
{
/* 能被100整除, 不能被400整除的年份, 不是闰年.
* 能被100整除, 也能被400整除的年份, 是闰年.*/
if ((year % 100) == 0) return((year % 400) == 0);
/* 不能被100整除, 能被4整除的年份是闰年. */
return ((year % 4) == 0);
}
int CalcJanuaryFirst(int year)
/*
功能: 计算该年1月1日的星期.
输入: year = 给出的 1582 年以后的年份.
输出: 1月1日的星期: 0 = 星期天, 1 = 星期一, 依次类推.
注意: 1582 年 1 月 1 日是星期五; 平年加1 , 闰年加2.
*/
{
/* 年份应为 1582 年以后. */
if (year < 1582) return (-1);
/* 始于01-01-1582 星期五; 平年加1 , 闰年加2. */
return ((5 + (year - 1582) + CalcLeapYears(year)) % 7);
}
int CalcLeapYears(int year)
/*
功能: 计算自 1582 年以后的闰年数.
输入: year = 给出的 1582 年以后的年份.
输出: 自 1582 年以后的闰年数. 如果早于 1582 年, 返回 -1 .
注意: 如果给出的年份是闰年, 计算结果不包括它.
能被100整除, 不能被400整除的年份, 不是闰年.
能被100整除, 也能被400整除的年份, 是闰年.
不能被100整除, 能被4整除的年份是闰年.
*/
{
int leapYears; /* 返回的闰年数 */
int hundreds; /* 能被100整除的年数 */
int fourHundreds; /* 能被400整除的年数 */
/* 年份应为 1582 年以后. */
if (year < 1582) return (-1);
/* 能被4整除的年数 */
leapYears = (year - 1581) / 4;
/* 计算能被100整除的年数; 然后从闰年数中除去*/
hundreds = (year - 1501) / 100;
leapYears -= hundreds;
/* 闰年数中加上能被400整除的年数 */
fourHundreds = (year - 1201) / 400;
leapYears += fourHundreds;
return (leapYears);
}
}
java 日历 日期 java写日历
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Java 日历 java 日历系统
一、需求(提供一个日期字符串(YYYY-MM-DD)返回日历信息,并且提供周日与周一选项是否放置在第一位选项)
Java 日历 java开源日历 字符串 ci 日期工具类