程序设计与方法学作业一之三天打鱼两天晒网
第一章
中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言/java/python实现程序解决问题。
基本要求:1.程序风格良好(使用自定义注释模板),提供友好的输入输出。
提高要求:1.输入数据的正确性验证。
2.使用文件进行数据测试。如将日期 20100101 20111214 等数据保存在in.txt文件中,程序读入in.dat文件进行判定,并将结果输出至out.txt文件。
这道题是我们老师上课时候布置给我们的作业,要求我们自己独立完成的一个作业,当我看到这道题是,感觉挺熟悉的,正好是时候我大一时候用c语言写过的一道题,整体的思路和老师课上讲的基本差不多,计算两个日期之间有多少天具体思路是:先计算出两个year之间有多少个闰年,闰年数乘以366加上平年数乘以365,然后判断当前year是否为闰年,再根据month加上month对应的天数,最后再加上day对应的天数。然后取余判断余数,并注意闰年和日期是否合法。
所以这里我并不打算再那样做,于是上课时我就想到已经学习过的Java,记得里面有一个Date类,希望能将输入的日期字符串转化为Date类型,然后计算出该Date变量的格林威治时间,也就是到1970年1月1日之间的毫秒数,然后与题目给出的日期的格林威治时间做差,求的相差多少毫秒,并转换为天数并取余判断。其中判断日期是否合法可以使用simpleDateFormat.setLenient(false); 设置如果日期不合法则抛出异常,在异常中返回-1,并main方法里对返回进行判断。
之后我加入了从文件读入,并存入数据库的实现。
- 首先创建数据库及输入文件
CREATE TABLE fish (
id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
date varchar(20) DEFAULT NULL,
state varchar(10) DEFAULT NULL,
)
输入文件target.txt
2011-9-2
2011-3-7
2014-3-4
2016-4-5
2015-1-2
2014-2-30 //最后一行为测试非法日期
- 之后开始定义simpleDateFormat对日期进行解析以及其他需要定义的变量
private static SimpleDateFormat simpleDateFormat; // 定义SimpleDateFormat对日期进行解析
static Date sourceDate = null; // 定义源日期
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 设置日期输入格式
simpleDateFormat.setLenient(false); // 设置如果日期不合法则抛出异常
String strDate = null; // 目标Date字符串
int day; // 两个日期之间的天数
int remainder; // 对5取余后的余数
String state; // 状态
try {
sourceDate = simpleDateFormat.parse("2010-1-1"); // 对源字符串类型进行转换
} catch (ParseException e) {
// TODO Auto-generated catch block
System.out.println("输入Date非法"); // 如果日期不合法,则抛出异常
}
- 之后开始进行文件的读入并调用getDay函数获取日期之间的天数差
// BufferedReader按行读取文件
FileInputStream inputStream = new FileInputStream("target.txt"); // 读取文件中的数据
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
while ((strDate = bufferedReader.readLine()) != null) { // 按行读取
// System.out.println(str);
day = getDay(strDate); // 调用getDay函数,计算目标日期与源日期之间的天数
if (day == -1) { // 如果返回天数为-1,则设置state为非法并存如数据库
state = "输入Date非法";
save(strDate, state);
continue;
}
System.out.println(strDate);
- 对天数进行取余并判断是否为打鱼还是晒网并存入数据库及关闭输入流
remainder = day % 5; // 计算天数对5取余的数
if (remainder > 0 && remainder <= 3) { // 若在0至3之间即为打鱼,否则为晒网
System.out.println("打鱼");
state = "打鱼";
save(strDate, state); // 将打鱼状态,日期存入数据库
} else {
System.out.println("晒网");
state = "晒网";
save(strDate, state); // 将晒网状态,日期存入数据库
}
}
// close
inputStream.close();
bufferedReader.close();
- 其中getDay函数如下
/**
* 计算目标日期与源日期之间的天数
*
* @param dateString
* @return
*/
private static int getDay(String dateString) {
// TODO Auto-generated method stub
Date date = null;
try {
date = simpleDateFormat.parse(dateString); // 对源字符串类型进行转换
} catch (ParseException e) {
// TODO Auto-generated catch block
System.out.println("输入Date非法"); // 如果日期不合法则返回-1
return -1;
}
long time = date.getTime() - sourceDate.getTime(); // 计算目标日期的格林威治时间和源日期的格林威治时间之差
int day = (int) (time / 1000 / 60 / 60 / 24); // 根据返回的毫秒数计算天数
return day;
}
- save函数如下
/**
* save函数,将源Date与状态存入数据库
*
* @param strDate
* @param state
*/
public static void save(String strDate, String state) {
PreparedStatement ps = null;
Connection conn = null;
String sql = "insert into fish(date,state) values(?,?)";
try {
conn = getConnection();
ps = conn.prepareStatement(sql);
ps.setString(1, strDate);
ps.setString(2, state);
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- getConnection函数如下
/**
* 建立连接
*
* @return
*/
public static Connection getConnection() {
Connection conn = null;
try {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Fish?useSSL=yes", "root", "1234");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("注册驱动失败");
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
- 最终的结果
- 期间遇到的问题及解决办法
在判断日期是否为合法日期时,我首先使用了Date类的getDay、getMonth等方法获取到目标date的具体年月日,并进行判断是否非法,之后发现这样写起来太过繁琐,查看API文档后发现SimpleDateFormat类中已经有方法可以进行日期是否合法的判断,只需对抛出的异常进行处理即可,最后我就改了一下,减轻了代码繁琐。 - 以下为所有源代码
package shilaoshi;
/**
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ____/`---'\____
* .' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* 佛祖保佑 永无BUG
* 佛曰:
* 写字楼里写字间,写字间里程序员;
* 程序人员写程序,又拿程序换酒钱。
* 酒醒只在网上坐,酒醉还来网下眠;
* 酒醉酒醒日复日,网上网下年复年。
* 但愿老死电脑间,不愿鞠躬老板前;
* 奔驰宝马贵者趣,公交自行程序员。
* 别人笑我忒疯癫,我笑自己命太贱;
* 不见满街漂亮妹,哪个归得程序员?
*/
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Fish1 {
private static SimpleDateFormat simpleDateFormat; // 定义SimpleDateFormat对日期进行解析
static Date sourceDate = null; // 定义源日期
public static void main(String[] args) throws IOException {
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 设置日期输入格式
simpleDateFormat.setLenient(false); // 设置如果日期不合法则抛出异常
String strDate = null; // 目标Date字符串
int day; // 两个日期之间的天数
int remainder; // 对5取余后的余数
String state; // 状态
try {
sourceDate = simpleDateFormat.parse("2010-1-1"); // 对源字符串类型进行转换
} catch (ParseException e) {
// TODO Auto-generated catch block
System.out.println("输入Date非法"); // 如果日期不合法,则抛出异常
}
// BufferedReader按行读取文件
FileInputStream inputStream = new FileInputStream("target.txt"); // 读取文件中的数据
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
while ((strDate = bufferedReader.readLine()) != null) { // 按行读取
// System.out.println(str);
day = getDay(strDate); // 调用getDay函数,计算目标日期与源日期之间的天数
if (day == -1) { // 如果返回天数为-1,则设置state为非法并存如数据库
state = "输入Date非法";
save(strDate, state);
continue;
}
System.out.println(strDate);
System.out.println(day);
remainder = day % 5; // 计算天数对5取余的数
if (remainder > 0 && remainder <= 3) { // 若在0至3之间即为打鱼,否则为晒网
System.out.println("打鱼");
state = "打鱼";
save(strDate, state); // 将打鱼状态,日期存入数据库
} else {
System.out.println("晒网");
state = "晒网";
save(strDate, state); // 将晒网状态,日期存入数据库
}
}
// close
inputStream.close();
bufferedReader.close();
}
/**
* 计算目标日期与源日期之间的天数
*
* @param dateString
* @return
*/
private static int getDay(String dateString) {
// TODO Auto-generated method stub
Date date = null;
try {
date = simpleDateFormat.parse(dateString); // 对源字符串类型进行转换
} catch (ParseException e) {
// TODO Auto-generated catch block
System.out.println("输入Date非法"); // 如果日期不合法则返回-1
return -1;
}
long time = date.getTime() - sourceDate.getTime(); // 计算目标日期的格林威治时间和源日期的格林威治时间之差
int day = (int) (time / 1000 / 60 / 60 / 24); // 根据返回的毫秒数计算天数
return day;
}
/**
* 建立连接
*
* @return
*/
public static Connection getConnection() {
Connection conn = null;
try {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Fish?useSSL=yes", "root", "1234");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("注册驱动失败");
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
/**
* save函数,将源Date与状态存入数据库
*
* @param strDate
* @param state
*/
public static void save(String strDate, String state) {
PreparedStatement ps = null;
Connection conn = null;
String sql = "insert into fish(date,state) values(?,?)";
try {
conn = getConnection();
ps = conn.prepareStatement(sql);
ps.setString(1, strDate);
ps.setString(2, state);
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}