这两天要写了个NextDate求解函数,有两种想法,一种方法很简单,直接利用Calendar类的add()方法,得到给定日期的下一日;另一种方法就是自己写函数求解,根据输入的日期,分类判断,比较繁琐。实现界面如下图1:
期望的布局如下图2:
附图1的源代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
* 求解NextDate,输入一个日期,输出它的下一天
* @version v1.0 2009-11-28
* @author badu
*/
public class NextDate
{
public static void main(String [] args)
{
NextDateFrame frame=new NextDateFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class NextDateFrame extends JFrame
{
public static final String TITLE="NextDate函数";
public static final int WIDTH=800;
public static final int HEIGHT=600;
//年月日输入栏
private JTextField firstTextField=new JTextField(10);
private JTextField secondTextField=new JTextField(10);
private JTextField thirdTextField=new JTextField(10);
//日期显示栏
private JTextField resultByCalculatedText=new JTextField(20);
private JTextField resultByTheoryText=new JTextField(20);
//显示输入的日期的标签
private JLabel inputLabel=null;
//输入日期
private String dateStr="";
//错误提示信息
private String errorInfo="";
//判断结果,用于写日志文件,给程序中没有实现日志记录功能
private String result="";
//匹配输入是否为整数的正则表达式
private String regex="^[+-]?[0-9]+$";
public NextDateFrame()
{
setTitle(TITLE);
setSize(WIDTH,HEIGHT);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenSize.width-WIDTH)/2,(screenSize.height-HEIGHT)/2);
//NextDate函数问题描述
JPanel northPanel=new JPanel();
String questionStr="<html>NextDate问题:<br>"+
"NextDate函数有三个变量:year(年份),month(月份),day(日期)。输出为输入日期后一天的日期。<br>"+
"例如,如果输入为:1994年6月18号,则nextDate函数的输出为1964年6月19日。<br>"+
"要求输入变量year,month,day都是正整数,并且满足一下条件:<br>"+
"Con1: 1900<=year<=2050<br>"+
"Con2: 1<=year<=12<br>"+
"Con3: 1<=day<=31<br><br><br><br></html>";
JLabel questionLabel=new JLabel(questionStr,SwingConstants.LEFT);
northPanel.add(questionLabel);
JSeparator separator=new JSeparator(SwingConstants.HORIZONTAL);
add(northPanel,BorderLayout.NORTH);
add(separator);
JPanel itemPanel=new JPanel();
itemPanel.setLayout(new GridLayout(1,3));
JPanel leftPanel=new JPanel();
leftPanel.add(new JLabel("请输入年份(****): ",SwingConstants.RIGHT));
leftPanel.add(firstTextField);
leftPanel.add(new JLabel("请输 入月 份(**): ",SwingConstants.RIGHT));
leftPanel.add(secondTextField);
leftPanel.add(new JLabel("请输 入日 期(**): ",SwingConstants.RIGHT));
leftPanel.add(thirdTextField);
itemPanel.add(leftPanel);
JPanel middlePanel=new JPanel();
JButton submitButton=new JButton("下一天 >>");
JButton cancellButton=new JButton("重 置");
middlePanel.add(submitButton);
middlePanel.add(cancellButton);
itemPanel.add(middlePanel);
JPanel rightPanel=new JPanel();
rightPanel.add(inputLabel=new JLabel(dateStr));
rightPanel.add(new JLabel("<html><br>由程序计算出的下一天是: <br></html>"));
rightPanel.add(resultByCalculatedText);
resultByCalculatedText.setEditable(false);
rightPanel.add(new JLabel("<html><br>实 际 的 下 一 天 是 : <br></html>"));
rightPanel.add(resultByTheoryText);
resultByTheoryText.setEditable(false);
itemPanel.add(rightPanel);
add(itemPanel);
submitButton.addActionListener(new JudgementAction());
cancellButton.addActionListener(new CancellAction());
}
private class JudgementAction implements ActionListener
{
private String firstText;
private String secondText;
private String thirdText;
//显示输入日期的下一日,分别为计算值和实际值
private String calculatedDate=null;
private String theoryDate=null;
public void actionPerformed(ActionEvent event)
{
firstText=firstTextField.getText().trim();
secondText=secondTextField.getText().trim();
thirdText=thirdTextField.getText().trim();
result +="年份,月份,日期分别是:"+firstText+" , "+secondText+" , "+thirdText+" , ";
//输入是否均非空
if((!firstText.equals(""))&&(!secondText.equals(""))&&(!thirdText.equals("")))
{
//输入是否均为整数
if(firstText.matches(regex)&&secondText.matches(regex)&&thirdText.matches(regex))
{
int firstSide=Integer.parseInt(firstText);
int secondSide=Integer.parseInt(secondText);
int thirdSide=Integer.parseInt(thirdText);
boolean isRightDate=isRightDate(firstSide,secondSide,thirdSide);
//输入日期是否有效
if(isRightDate)
{
dateStr=firstText+"年"+secondText+"月"+thirdText+"日";
inputLabel.setText(dateStr);
result +=firstText+"年"+secondText+"月"+thirdText+"日的下一日:";
calculatedDate=getCalculatedNextDate(firstSide,secondSide,thirdSide);
resultByCalculatedText.setText(calculatedDate);
result +="程序计算得到的下一日是 "+calculatedDate+",";
theoryDate=getTheoryNextDate(firstSide,secondSide,thirdSide);
resultByTheoryText.setText(theoryDate);
result +="实际的下一日是 "+theoryDate;
}
else
{
result +=errorInfo;
inputLabel.setText(errorInfo);
resultByCalculatedText.setText("无");
resultByTheoryText.setText("无");
}
}
else
{
errorInfo="输入的年份或月份或日期不全为整数,请重新输入";
result +=errorInfo;
inputLabel.setText(errorInfo);
resultByCalculatedText.setText("X");
resultByTheoryText.setText("X");
}
}
else
{
errorInfo="输入的年份或月份或日期不完整,请重新输入";
result +=errorInfo;
inputLabel.setText(errorInfo);
resultByCalculatedText.setText("X");
resultByTheoryText.setText("X");
}
firstTextField.setEditable(false);
secondTextField.setEditable(false);
thirdTextField.setEditable(false);
}
//判断输入日期是否为有效日期
private boolean isRightDate(int year,int month,int day)
{
boolean b=false;
if(year>=1900&&year<=2050)
{
if(month>=1&&month<=12)
{
if(day>=1&&day<=31)
{
if(month==4||month==6||month==9||month==11)
{
if(day==31)
errorInfo=month+"月份没有31日";
else
b=true;
}
else if(month==2)
{
if(day==30||day==31)
errorInfo="2月份没有30和31";
else
{
if(!((year%4==0 && year%100!=0) || year%400==0))
{
if(day==29)
errorInfo +=String.valueOf(year)+"年不是闰年,因此该年的2月份没有29";
else
b=true;
}
else
b=true;
}
}
else
b=true;
}
else
{
errorInfo="请输入指定值内的日期";
}
}
else
{
errorInfo="请输入指定值内的月份";
}
}
else
{
errorInfo="请输入指定值内的年份";
}
return b;
}
//输入日期下一日的计算值
private String getCalculatedNextDate(int year,int month,int day)
{
switch (month)
{
case 1: case 3:case 5:case 7:case 8:case 10 :
if(day==31)
{
day=1;
month=month+1;
}
else
day=day+1;
break;
case 4:case 6:case 9:case 11:
if(day==30)
{
day=1;
month=month+1;
}
else
day=day+1;
break;
case 12:
if(day==31)
{
day=1;
month=1;
year=year+1;
}
else if(day<31)
{
day=day+1;
}
break;
case 2:
if(day==28)
{
if(((year%4==0 && year%100!=0) || year%400==0))
{
day=29;
}
else
{
day=1;
month=3;
}
}
else if(day==29)
{
//之前已近判断过数据的有效性,因此在这里如果某个2月份有29,一定是有效的,无需再判断是否闰年
day=1;
month=3;
}
else if(day<28)
{
day=day+1;
}
else
System.out.println("二月没有"+day+"号!");
break;
default:
}
return String.valueOf(year)+"年"+String.valueOf(month)+"月"+String.valueOf(day)+"日";
}
//利用API来计算给定日期的下一日,即实际值,与程序计算的下一日比较
private String getTheoryNextDate(int year,int month,int day)
{
//Calendar的MONTH属性为0到11,分别表示1-12月份。
GregorianCalendar date = new GregorianCalendar(year,month-1,day);
date.add(Calendar.DAY_OF_MONTH,1);
int y=date.get(Calendar.YEAR);
int m=date.get(Calendar.MONTH);
int d=date.get(Calendar.DAY_OF_MONTH);
return String.valueOf(y)+"年"+String.valueOf(m+1)+"月"+String.valueOf(d)+"日";
}
}
//重置
private class CancellAction implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
firstTextField.setText("");
secondTextField.setText("");
thirdTextField.setText("");
resultByCalculatedText.setText("");
resultByTheoryText.setText("");
inputLabel.setText("");
result="";
errorInfo="";
firstTextField.setEditable(true);
secondTextField.setEditable(true);
thirdTextField.setEditable(true);
}
}
}