通过DateTimeFormatter格式器格式化日期时间
题目要求:
用扫描器获取输入的时间(年月日时分),这个时间的格式是常用的格式,然后格式化这个时间,把格式化的时间输出到控制台,可以在控制台重复输入时间.格式化的时间参考企业微信聊天记录的展示时间.
知识需求
- java基础知识
- Scanner扫描器
- 普通类,枚举类
- final修饰符
- 正则表达式
- DateTimeFormatter格式器(格式化及解析知识)
- 包装类,打印对象
- 一系列的常用方法等
实现思路及简易步骤
- 获取扫描器,通过扫描器获取输入的时间(年月日时分)
- 创建一个Notice类(提示信息类),用于存取日期时间格式化期间要用到的完整的提示信息(如普通类,枚举类)
- 创建一个Regex枚举类,用于匹配日期时间的正则表达式,把传入的日期时间匹配相对应的正则表达式,将匹配好的日期时间传入日期时间工具类的获取日期时间的方法中,然后进行具体的格式化实现
- 这个时间的格式是常用的格式,然后格式化这个时间,把格式化的时间输出到控制台,可以在控制台重复输入时间.格式化的时间参考企业微信聊天记录的展示时间.
- 需要实现:
同年:
同月:月日+时分
今天:上午/下午+时分
明天:明天+时分
昨天:昨天+时分
今天之前(包括今天)的一周内:星期+时分
不同月时:
上个月(通过调整时间进行测试):
今天:上午/下午+时分
明天:明天+时分
昨天:昨天+时分
今天之前(包括今天)的一周内:星期+时分
本月:月日+时分
下个月(通过调整时间进行测试):
明天:明天+时分
其他月:月日+时分
不同年:年月日+时分
程序测试情景如下:
欢迎使用日期时间格式器!
若退出程序,请输入'exit'或'退出' !
请参考企业微信聊天记录的展示时间,输入一个合法的时间:
合法时间格式为日期格式为yyyy.MM.dd HH:mm
形如:2020.1.10 19:19
或日期格式为yyyy-MM-dd HH:mm
形如:2020-1-10 19:19
或日期格式为yyyy/MM/dd HH:mm
形如:2020/1/10 19:19
请输入:
2020/1/11 19:19
格式化后日期时间为:
下午 19:19
若退出程序,请输入'exit'或'退出' !
2020/1/12 19:19
格式化后日期时间为:
明天 19:19
若退出程序,请输入'exit'或'退出' !
2020/1/10 19:19
格式化后日期时间为:
昨天 19:19
若退出程序,请输入'exit'或'退出' !
2020/1/9 19:19
格式化后日期时间为:
周四 19:19
若退出程序,请输入'exit'或'退出' !
2020/1/3 19:19
格式化后日期时间为:
1月3日 19:19
若退出程序,请输入'exit'或'退出' !
2020/2/29 19:19
格式化后日期时间为:
2月29日 19:19
若退出程序,请输入'exit'或'退出' !
2019/2/28 19:19
格式化后日期时间为:
2019年2月28日 19:19
若退出程序,请输入'exit'或'退出' !
如果需要其他情形,请自行测试!
实现代码如下:
测试类
package datetimeformatter;
/**
* 日期时间测试类<br>
* 2020年1月10日 上午9:43:16
*
* @author zcf
* @version 1.0
*/
public class Test {
/**
* 程序入口
*
* @param args 入口参数
*/
public static void main(String[] args) {
/**
* 进入时间格式器
*/
DateTime.startIn();
}
}
日期时间类
package datetimeformatter;
import java.util.Scanner;
/**
* 日期时间类<br>
* 2020年1月10日 上午9:44:13
*
* @author zcf
* @version 1.0
*/
public class DateTime {
/**
* 闰年日期正则
*/
private static final String LEEP_YEAR = Regex.LEEP_YEAR.getDesc();
/**
* 平年日期正则
*/
private static final String COMMON_YEAR = Regex.COMMON_YEAR.getDesc();
/**
* 时间正则
*/
private static final String TIME = Regex.TIME.getDesc();
/**
* 私有构造器 不能创建实例
*/
private DateTime() {
}
/**
* 时间格式器,开始方法
*/
public static void startIn() {
// 进入程序的提示语
Notice.inTip();
// 获取扫描器
Scanner sc = new Scanner(System.in);
// 判断是否有下一行输入
while (sc.hasNextLine()) {
// 获取下一行输入输入的日期时间
// trim()方法忽略在控制台输出时,前后的无用空格
String dateTime = sc.nextLine().trim();
if (dateTime.matches("exit|退出")) {
// 退出程序
Notice.printNotice(Notice.EXIT_FINASH);
// 关闭扫描器
sc.close();
break;
}
// 把传入的日期时间匹配相对应的正则表达式
else if ((dateTime.matches(LEEP_YEAR + TIME)) || (dateTime.matches(COMMON_YEAR + TIME))) {
// 将匹配好的时间传入工具类的获取日期时间的方法中
DateTimeTool.getDateTime(dateTime);
// 退出程序
Notice.printNotice(Notice.EXIT_PROGRAM);
continue;
} else {
// 匹配失败,提示错误
Notice.printNotice(Notice.DATE_TIME_ERROR);
// 可进行退出
Notice.printNotice(Notice.EXIT_PROGRAM);
}
}
}
}
信息提示类
package datetimeformatter;
/**
* 程序完整的提示信息<br>
* 2020年1月10日 上午10:51:28
*
* @author zcf
* @version 1.0
*/
public class Notice {
/**
* 退出程序指示语
*/
public static final String EXIT_PROGRAM = "若退出程序,请输入'exit'或'退出' !";
/**
* 退出程序完成指示语
*/
public static final String EXIT_FINASH = "已退出程序,欢迎下次使用!";
/**
* 日期错误指示语
*/
public static final String DATE_ERROR = "日期错误";
/**
* 日期分隔符错误指示语
*/
public static final String DATE_SPLIT_ERROR = "日期分隔符错误,请重新输入:\n";
/**
* 时间错误指示语
*/
public static final String TIME_ERROR = "时间错误";
/**
* 日期时间错误指示语
*/
public static final String DATE_TIME_ERROR = "日期时间不合法,请重新输入:\n";
/**
* 进入程序的提示语(small tip)
*/
public static void inTip() {
System.out.println("欢迎使用日期时间格式器!");
//退出程序提示语
System.out.println(Notice.EXIT_PROGRAM);
System.out.println("请参考企业微信聊天记录的展示时间,输入一个合法的时间:");
System.out.println("合法时间格式为日期格式为yyyy.MM.dd HH:mm\n 形如:2020.1.10 19:19");
System.out.println(" 或日期格式为yyyy-MM-dd HH:mm\n 形如:2020-1-10 19:19");
System.out.println(" 或日期格式为yyyy/MM/dd HH:mm\n 形如:2020/1/10 19:19");
System.out.println("请输入:");
}
/**
* 输出提示信息的方法
*
* @param printNotice 要输出的提示信息
*/
public static void printNotice(String printNotice) {
//输出提示信息
System.out.println(printNotice);
}
}
匹配日期时间正则表达式类
/**
* 验证日期格式为YYYY.MM.DD HH:MM的正则表达式 闰年,能被4整除但不能被100整除,<br>
* ((([0-9]{2}(0[48]|[2468][048]|[13579][26])) 闰年,能被400整除<br>
* |((0[48]|[2468][048]|[13579][26])00) 匹配闰年2月29日这一天。如果不是这一天,则由下面式子继续匹配验证。<br>
* [-\\/\\.]0?2[-\\/\\.]29 <br>
* 平年(0001-9999)<br>
* |([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})<br>
* 月日,1、3、5、7、8、10、12月有31天 [-\\/\\.](((0?[13578]|1[02])[-\\/\\.](0?[1-9]|[12][0-9]|3[01]))<br>
* 月日,4、6、9、11月有30天 |((0?[469]|11)[-\\/\\.](0?[1-9]|[12][0-9]|30)) <br>
* 平年2月<br>
* |(0?2[-\\/\\.](0?[1-9]|[1][0-9]|2[0-8])))) <br>
* 时间 (([01]?[0-9]|2[0-3]):[0-5]?[0-9])
*/
package datetimeformatter;
/**
* 时间日期匹配正则表达式<br>
* 2020年1月10日 下午6:21:44
*
* @author zcf
* @version 1.0
*/
public enum Regex {
/**
* 匹配闰年
*/
LEEP_YEAR("(([0-9]{2}(0[48]|[2468][048]|[13579][26]))"
+ "|((0[48]|[2468][048]|[13579][26])00))[-\\/\\.]0?2[-\\/\\.]29"),
/**
* 匹配平年
*/
COMMON_YEAR("|([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})"
+ "[-\\/\\.](((0?[13578]|1[02])[-\\/\\.](0?[1-9]|[12][0-9]|3[01]))"
+ "|((0?[469]|11)[-\\/\\.](0?[1-9]|[12][0-9]|30))"
+ "|(0?2[-\\/\\.](0?[1-9]|[1][0-9]|2[0-8])))"),
/**
* 匹配时间
*/
TIME(" (([01]?[0-9]|2[0-3]):[0-5]?[0-9])");
/**
* 信息描述
*/
private final String desc;
/**
* 有参构造器
*
* @param desc 信息描述参数
*/
private Regex(String desc) {
this.desc = desc;
}
/**
* 获取信息描述参数
*
* @return 信息描述
*/
public String getDesc() {
return desc;
}
}
格式化日期时间类
package datetimeformatter;
import java.time.LocalDateTime;
import java.time.MonthDay;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
/**
* 日期时间工具类<br>
* 2020年1月10日 上午11:12:19
*
* @author zcf
* @version 1.0
*/
public class DateTimeTool {
/**
* 当前年
*/
private static int currentYear = Year.now().getValue();
/**
* 当前月
*/
private static int currentMonth = MonthDay.now().getMonth().getValue();
/**
* 当前日
*/
private static int currentDay = MonthDay.now().getDayOfMonth();
/**
* 大月
*/
private static int[] bigMonth = { 1, 3, 5, 7, 8, 10, 12 };
/**
* 小月
*/
private static int[] smallMonth = { 4, 6, 9, 11 };
/**
* 获取日期时间方法
*
* @param dateTime 传入的日期时间
* @return 处理后的日期时间
*/
public static String getDateTime(String dateTime) {
String result = null;
// 通过空格来分割日期时间
String[] dateTStrings = dateTime.split(" ");
// 日期时间长度必须为2
if (dateTStrings.length != 2) {
// 日期时间错误指示语
Notice.printNotice(Notice.DATE_TIME_ERROR);
return Notice.DATE_TIME_ERROR;
}
// 分割后的日期
String date = dateTStrings[0];
// 分割后的时间
String time = dateTStrings[1];
// 分隔符
String splitter = "";
// 判断日期中包含的分隔符为 - . 或/
if (date.contains("-")) {
// 通过-分割日期
splitter = "-";
} else if (date.contains(".")) {
// 通过.分割日期
splitter = "\\.";
} else if (date.contains("/")) {
// 通过/分割日期
splitter = "/";
} else {
return Notice.DATE_SPLIT_ERROR;
}
// 对传入的日期进行分割
// 保证日期使用相同的符号分割,例如:<1>yyyy.MM.dd <2>yyyy-MM-dd <3>yyyy/MM/dd
String[] splitAfDate = date.split(splitter);
// 对传入的时间通过冒号(:)进行分割
String[] splitAfTime = time.split(":");
// 确定日期中的年月日分割符一致
if (splitAfDate.length != 3) {
// 分割符不一致时,返回日期错误
System.out.println(Notice.DATE_SPLIT_ERROR);
return Notice.DATE_SPLIT_ERROR;
} else if (splitAfTime.length != 2) {
// 时间错误
System.out.println(Notice.TIME_ERROR);
return Notice.TIME_ERROR;
} else {
// 分割符一致时,正常向下执行
// 传入年
int year = Integer.valueOf(splitAfDate[0]);
// 传入月
int month = Integer.valueOf(splitAfDate[1]);
// 传入日
int day = Integer.valueOf(splitAfDate[2]);
// 传入时
int hour = Integer.valueOf(splitAfTime[0]);
// 传入分
int minute = Integer.valueOf(splitAfTime[1]);
// 拼接完整的日期时间
String inDateTime = year + splitter + month + splitter + day + " " + hour + ":" + minute;
// 使用模式字符串创建格式化器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("y" + splitter + "M" + splitter + "d" + " H:m");
// 把时间日期字符串解析为日期时间对象
LocalDateTime localDateTime = LocalDateTime.parse(inDateTime, formatter);
// 判断传入年份与当前年份一致,为同一年
if (year == currentYear) {
// 判断是否为同一月
if (month == currentMonth) {
if (day == currentDay) {
// 今天,情景如下:
printResult("a HH:mm", localDateTime);
} else if (day - currentDay == 1) {
// 明天,情景如下:
printResult("明天 HH:mm", localDateTime);
} else if (day - currentDay == -1) {
// 昨天,情景如下:
printResult("昨天 HH:mm", localDateTime);
} else if (day - currentDay >= -7 && day - currentDay <= -2) {
// 距今天(包括今天)的一周内,情景如下:
printResult("E HH:mm", localDateTime);
} else {
// 除今天,明天,昨天,以及今天前一周的同一月,,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
} else if (month - currentMonth == 1) {
// 判断下个月
// 判断大月小月以及平年闰年的二月
// 传入日期为1号
if (day == 1) {
// 判断大月的明天
if (Arrays.binarySearch(bigMonth, currentMonth) >= 0 && currentDay == 31) {
// 明天,情景如下:
printResult("明天 HH:mm", localDateTime);
// 判断小月的明天
} else if (Arrays.binarySearch(smallMonth, currentMonth) >= 0 && currentDay == 30) {
// 明天,情景如下:
printResult("明天 HH:mm", localDateTime);
} else {
// 二月
if (currentMonth == 2) {
// 判断是否为闰年
if ((currentYear % 4 == 0 && currentYear % 100 != 0) || currentYear % 400 == 0) {
// 闰年二月为29天
if (currentDay == 29) {
// 明天,情景如下:
printResult("明天 HH:mm", localDateTime);
} else {
// 同月时,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
} else {
// 平年二月为28天
if (currentDay == 28) {
// 明天,情景如下:
printResult("明天 HH:mm", localDateTime);
} else {
// 同月时,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
}
} else {
// 同月时,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
}
} else {
// 同月时,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
} else if (month - currentMonth == -1) {
// 判断上个月
// 判断大月小月以及平年闰年的二月
// 当前为1号
if (currentDay == 1) {
// 判断大月的昨天
if (Arrays.binarySearch(bigMonth, month) >= 0 && day == 31) {
// 昨天,情景如下:
printResult("昨天 HH:mm", localDateTime);
// 判断小月的昨天
} else if (Arrays.binarySearch(smallMonth, month) >= 0 && day == 30) {
// 昨天,情景如下:
printResult("昨天 HH:mm", localDateTime);
} else if (month == 2) {
// 判断是否为闰年
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
// 闰年二月为29天
if (day == 29) {
// 昨天,情景如下:
printResult("昨天 HH:mm", localDateTime);
}
} else {
// 平年二月为28天
if (day == 28) {
// 昨天,情景如下:
printResult("昨天 HH:mm", localDateTime);
}
}
}
return result;
}
// 当前大于等于7号
if (currentDay >= 7) {
// 同月时,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
// 当前天之前的一周
else if (Arrays.binarySearch(bigMonth, month) >= 0 && 31 - day + currentDay < 7) {
// 当前天以及之前的一周
// 距今天(包括今天)的一周内,情景如下:
printResult("E HH:mm", localDateTime);
} else if (Arrays.binarySearch(smallMonth, month) >= 0 && 30 - day + currentDay < 7) {
// 当前天以及之前的一周
// 距今天(包括今天)的一周内,情景如下:
printResult("E HH:mm", localDateTime);
} else if (month == 2) {
// 判断是否为闰年
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
// 闰年二月为29天
if (29 - day + currentDay < 7) {
// 当前天以及之前的一周
// 距今天(包括今天)的一周内,情景如下:
printResult("E HH:mm", localDateTime);
} else {
// 同月时,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
} else {
// 平年二月为28天
if (28 - day + currentDay < 7) {
// 当前天以及之前的一周
// 距今天(包括今天)的一周内,情景如下:
printResult("E HH:mm", localDateTime);
} else {
// 同月时,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
}
} else {
// 同月时,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
} else {
// 除本月,上个月,下个月之外的不同月,情景如下:
printResult("M月d日 HH:mm", localDateTime);
}
} else {
// 不同年时,情景如下:
printResult("yyyy年M月d日 HH:mm", localDateTime);
}
}
return result;
}
/**
* 把日期时间对象格式化为日期时间字符串
*
* @param modeString 模式字符串
* @param localDateTime 日期时间对象
*/
private static void printResult(String modeString, LocalDateTime localDateTime) {
// 使用模式字符串创建格式化器
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern(modeString);
// 把日期时间对象格式化成字符串
String formatDateTime = formatter2.format(localDateTime);
// 输出格式化的日期时间字符串
System.out.println("格式化后日期时间为:\n" + " " + formatDateTime);
}
}
zcf_hrkj
发布了4 篇原创文章 · 获赞 5 · 访问量 60
私信
关注