Java使用DateTimeFormatter实现格式化时间

用扫描器获取输入的时间(年月日时分),这个时间的格式是常用的格式,然后格式化这个时间,把格式化的时间输出到控制台,可以在控制台重复输入时间.格式化的时间参考企业微信聊天记录的展示时间.用DateTimeFormatter实现,功能如下:
同年:
不同年:
同月:月日+上午/下午+时分
同年不同月:月日+时分
今天:上午/下午+时分
明天:明天+上午/下午+时分
昨天:昨天+上午/下午+时分
包括今天在内的一周内:星期+上午/下午+时分

首先看一下测试类:

package hrkj;

import java.util.Scanner;

/**
 * 日期时间测试类
 *
 * @author 张林琛<br>
 * @date 2020/01/10 08:35:29
 * @version 1.0
 */
public class DateTimeTest {

 public static void main(String[] args) {
 // 获取Scanner扫描器
 Scanner sc = new Scanner(System.in);
 // 程序开始提示语句
 Hint.HINT_STAR.print();
 // 程序退出提示语句
 System.out.println(Order.ORDER_EXIT.getname());
 while (sc.hasNextLine()) {
  String str = sc.nextLine();
  // 判断是否为退出指令
  if (Order.ORDER_EXIT.compare(str)) {
  Hint.HINT_END.print();
  //如果退出,则关闭扫描器
  sc.close();
  break;
  // 判断输入的是否为空格或回车
  } else if (str.equals(" ") || str.equals(""
   + "")) {
  Hint.BLANK_OR_ENTER.print();
  } else {
  // 开始处理日期时间
  DateTimeTool.dateTimeFormatter(str);
  }
  Hint.HINT_STAR.print();
  System.out.println(Order.ORDER_EXIT.getname());
 }
 }

}

这里比较好的一点就是,在程序结束之前,会关闭扫描器,程序开始和程序结束,都会有提示语句:

请输入正确的时间,例如:
2020-01-10 10:10   2020.01.10 10:10   2020/01/10 10:10
退出请输入:[exit, 退出]

上面效果分别对应以下两行代码:

    // 程序开始提示语句
 Hint.HINT_STAR.print();
 // 程序退出提示语句
 System.out.println(Order.ORDER_EXIT.getname());

其中[exit, 退出]单独为第二行代码,与第一行代码效果拼接在一起,值得注意的是,Hint是一个枚举类,程序开始;运行期间和结尾的提示语句,都定义为枚举值,具体如下:

package hrkj;

/**
 * 日期时间类的提示语句,用于提示错误信息
 *
 * @author 张林琛<br>
 * @date 2020/01/10 08:39:27
 * @version 1.0
 */

public enum Hint {
 /**
 * 日期时间长度不合法
 */
 LENGTH_ILLEGAL("日期时间长度不合法,"),
 /**
 * 日期错误
 */
 HINT_DATE("日期输入错误,"),
 /**
 * 月份输入不合法
 */
 HINT_MONTH("月份输入不合法,"),
 /**
 * 大月只有31天
 */
 HINT_BIGMONTH("大月只有31天,"),
 /**
 * 小月只有30天
 */
 HINT_TINYMONTH("小月只有30天,"),
 /**
 * 平年2月只有28天
 */
 HINT_TINY_TWOMONTH("平年二月只有28天,"),
 /**
 * 闰年二月只有29天
 */
 HINT_BIG_TWOMONTH("闰年二月只有28天,"),
 /**
 * 时间错误
 */
 HINT_TIME("时间输入错误,"),
 /**
 * 输入空格或回车
 */
 BLANK_OR_ENTER("不能输入空格或直接回车,"),
 /**
 * 以空格分开日期和时间
 */
 DATE_BLANK_TIME("请以空格分割开日期和时间,"),
 /**
 * 开始提示语句
 */
 HINT_STAR("请输入正确的时间,例如:\n2020-01-10 10:10  2020.01.10 10:10  2020/01/10 10:10\n退出请输入:"),
 /**
 * 程序结束提示语句
 */
 HINT_END("程序结束,欢迎下次使用!");
 // 定义实例变量
 private final String name;

 /**
 * 单个参数构造器
 *
 * @param name
 */
 private Hint(String name) {
 this.name = name;

 }

 /**
 * 获取实例变量的值
 *
 * @return name
 */
 public String getName() {
 return name;
 }

 /**
 * 打印提示语句的方法
 */
 public void print() {
 System.out.print(name);
 }
}

因为枚举类中定义了一个print()方法,调用此方法可直接打印枚举值.
上面说到,[exit, 退出]为退出指令,用户输入exit或退出则会关闭扫描器,接着关闭程序,在此也把退出定义为一个指令枚举类,具体实现如下:

package hrkj;

import java.util.Arrays;

/**
 * 日期时间类的指令集,用于输入相对应的指令
 *
 * @author 张林琛<br>
 * @date 2020/01/10 08:38:05
 * @version 1.0
 */
public enum Order {
 /**
 * 退出指令
 */
 ORDER_EXIT("exit","退出");
 // 定义实例变量数组name
 private final String[] name;

 /**
 * 形参可变的构造器
 * @param name
 */
 private Order(String... name) {
 this.name = name;
 }

 /**
 * 获取退出的指令
 * @return 获取的指令
 */
 public String getname() {
 return Arrays.toString(name);
 }

 /**
 * 判断输入的是不是退出的指令
 * @param str 输入的指令
 * @return 是否是退出指令
 */
 public boolean compare(String str) {
 for (int i = 0; i < name.length; i++) {
  if (str.equals(name[i])) {
  return true;
  }
 }
 return false;
 }
}

Order枚举类虽然枚举实例只有一个退出(如果有其他指令可继续添加),但枚举值为两个:退出和exit,用户输入任意一个就会达到退出的效果,在此类中定义一个比较方法,用于比较用户输入的是否与枚举值相同,用到equals()方法,之所以没有用contains()方法,是因为一旦用contains()方法,那么用户输入e,x,it,等,只要是在枚举值包含的,都可以退出.

最后便是工具类,用于格式化日期时间并输出,实现细节如下

package hrkj;

import java.time.LocalDateTime;
import java.time.MonthDay;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Arrays;

/**
 * 日期时间实现类,使用DateTimeFormatter实现
 *
 * @author 张林琛<br>
 * @date 2020/01/10 08:36:37
 * @version 1.0
 */
public class DateTimeTool {
 /**
 * 有31天的月份
 */
 static int[] bigMonth = { 1, 3, 5, 7, 8, 10, 12 };
 /**
 * 有30天的月份
 */
 static int[] tinyMonth = { 4, 6, 9, 11 };

 /**
 * 处理日期和时间
 *
 * @param str
 */
 public static void dateTimeFormatter(String str) {
 // 判断日期时间的长度
 if (str.length() < 9 || str.length() > 16) {
  Hint.LENGTH_ILLEGAL.print();
  return;
 }
 // 判断输入的日期和时间是否以空格分割
 if (str.contains(" ")) {
  // 创建数组来接收分割后的日期时间
  String[] datetime = str.split(" ");
  // 获取日期
  String[] date = splitDate(datetime[0]);
  // 判断日期长度
  if (date.length != 3) {
  Hint.HINT_DATE.print();
  return;
  }
  // 获取年
  Integer y = Integer.valueOf(date[0]);
  // 获取月
  Integer M = Integer.valueOf(date[1]);
  // 获取日
  Integer d = Integer.valueOf(date[2]);
  // 判断是不是闰年
  if (!handleDate(y, M, d)) {
  // 如果月份大于12或小于1
  if (M > 12 || M < 1) {
   Hint.HINT_MONTH.print();
   return;
   // 如果大月天数超过31或小于1
  } else if (Arrays.binarySearch(bigMonth, M) > -1 && (d <= 0 || d > 31)) {
   Hint.HINT_BIGMONTH.print();
   return;
   // 如果小月天数超过30或小于1
  } else if (Arrays.binarySearch(tinyMonth, M) > -1 && (d <= 0 || d > 30)) {
   Hint.HINT_TINYMONTH.print();
   return;
   // 如果平年二月天数超过28或小于1
  } else if (y % 4 != 0 && y % 100 != 0 && M == 2 && (d <= 0 || d > 28)) {
   Hint.HINT_TINY_TWOMONTH.print();
   return;
   // 如果平年二月天数超过28或小于1
  } else if (y % 400 != 0 && M == 2 && (d <= 0 || d > 28)) {
   Hint.HINT_TINY_TWOMONTH.print();
   return;
   // 如果闰年二月天数超过29或小于1
  } else if (y % 4 == 0 && y % 100 != 0 && M == 2 && (d <= 0 || d > 29)) {
   Hint.HINT_BIG_TWOMONTH.print();
   return;
   // 如果闰年二月天数超过29或小于1
  } else if (y % 400 == 0 && M == 2 && (d <= 0 || d > 29)) {
   Hint.HINT_BIG_TWOMONTH.print();
   return;
  } else {
   return;
  }

  }
  // 获取时间
  String time = datetime[1];
  // 判断是否以正则分割
  boolean b = spiltTime(time);
  // 如果没有以正则分割
  if (!b) {
  Hint.HINT_TIME.print();
  return;
  } else {
  // 进行日期和时间的拼接
  String dateTime = y + "-" + M + "-" + d + " " + time;
  DateTimeFormatter ofPattern1 = DateTimeFormatter.ofPattern("y-M-d H:m");
  LocalDateTime parse1 = LocalDateTime.parse(dateTime, ofPattern1);
  // System.out.println(parse1);
  // 判断是不是当年
  if (y == Year.now().getValue()) {
   // 判断是不是当月
   if (M == MonthDay.now().getMonthValue()) {
   // 判断是不是今天
   if (d == MonthDay.now().getDayOfMonth()) {
    printMessage("今天 a H:m", parse1);
    // 判断是不是昨天
   } else if (d - MonthDay.now().getDayOfMonth() == -1) {
    printMessage("今天 a H:m", parse1);
    // 判断是不是明天
   } else if (d - MonthDay.now().getDayOfMonth() == 1) {
    printMessage("明天 a H:m", parse1);
    // 判断一周内的哪一天
   } else if (d - MonthDay.now().getDayOfMonth() >= -7
    && d - MonthDay.now().getDayOfMonth() <= -2) {
    printMessage("E a H:m", parse1);
    // 在当月内,但不在本周
   } else {
         printMessage("M-d a H:m", parse1);
   }
   // 当前年的其他月
   } else {
   printMessage("M-d H:m", parse1);
   }
   // 不同年的情况下
  } else {
  DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT);
   System.out.println(parse1.format(dtf) + "分");
  }

  }
 } else {
  return;
 }

 }

 /**
 * 获取时间格式器并解析,打印时间
 *
 * @param info     模式字符串
 * @param localDateTime LocalDateTime对象
 */
 private static void printMessage(String info, LocalDateTime localDateTime) {
 //把模式字符串传进去,获取到DateTimeFormatter对象
 DateTimeFormatter ofPattern2 = DateTimeFormatter.ofPattern(info);
 //用LocalDateTime对象解析获取到的DateTimeFormatter对象
 System.out.println(localDateTime.format(ofPattern2));
 }

 /**
 * 判断大小闰年方法
 * 其中判断了平年和闰年内大月和小月的天数
 * @param y 年
 * @param m 月
 * @param d 日
 * @return true为闰年,false为平年
 */
 private static boolean handleDate(int y, int m, int d) {
 // 是闰年二月情况下
 if (y % 4 == 0 && y % 100 != 0 && m == 2 && (d > 0 && d <= 29)) {
  return true;
  // 是闰年二月情况下
 } else if (y % 400 == 0 && m == 2 && (d > 0 && d <= 29)) {
  return true;
  // 不是闰年,但是二月情况下
 } else if (y % 4 != 0 && y % 400 != 0 && m == 2 && (d > 0 && d <= 28)) {
  // 不是闰年,2月28天
  return true;
  // 不是二月,判断是否是大月
 } else if (Arrays.binarySearch(bigMonth, m) > -1 && (d > 0 && d <= 31)) {
  return true;
  // 不是二月,判断是否是小月
 } else if (Arrays.binarySearch(tinyMonth, m) > -1 && (d > 0 && d <= 30)) {
  return true;
 }
 return false;
 }

 /**
 * 使用正则表达式限定时间
 *
 * @param time 需要分割的时间
 * @return 分割后的结果
 */
 private static boolean spiltTime(String time) {
 String t = "([01]?[0-9]{1}|[2][0-3]):[0-5]?[0-9]";
 return time.matches(t) ? true : false;
 }

 /**
 * 使用正则表达式限定日期
 *
 * @param date 需要分割的日期
 * @return 分割后的日期
 */
 private static String[] splitDate(String date) {
 // 分割年月日
 String r = "[\\./-]{1}";
 // 月份出现的位数
 String s = "\\d{1,2}";
 return date.matches("\\d+" + "(" + r + s + "){2}") ? date.split(r) : new String[0];
 }

}

在实现类中,使用了正则表达式(一个强大的字符串处理工具)来限定日期和时间的分隔符(. / - : 四种),输入类型(只能为数字)等,得到自己想要的日期时间格式,然后对平闰年进行判断,完成后再拼接时间.然后把获取时间格式器和解析抽象成一个方法(因为用的很多,如果不抽象成方法,会显得代码很冗长),每次使用直接调用方法.最后在不同年的情况下,使用了不同风格的时间格式化器完成格式化.

测试虽然没有任何Bug,但跨年(比如19年的12月31号是20年的1月1号的昨天),跨月(比如20年1月31号为星期五,2月2号为星期日)没有实现,如需其他需要,请自行添加逻辑实现.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • JAVA格式化时间日期的简单实例

    复制代码 代码如下: import java.util.Date;import java.text.DateFormat; /*** 格式化时间类* DateFormat.FULL = 0* DateFormat.DEFAULT = 2* DateFormat.LONG = 1* DateFormat.MEDIUM = 2* DateFormat.SHORT = 3* @author    Michael * @version   1.0, 2007/03/09*/ public class T

  • java格式化时间示例

    实现日期的格式化,需要用到类: java.text.DateFormat DateFormat没有可以直接使用的构造函数,一般使用DateFormate的子类---java.text.SimpleDateFormat完成构造. public SimpleDateFormat(String pattern) 测试代码 复制代码 代码如下: import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.D

  • Java SimpleDateFormat中英文时间格式化转换详解

    SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类.它允许进行格式化(日期 -> 文本).解析(文本 -> 日期)和规范化. SimpleDateFormat使得可以选择任何用户定义的日期-时间格式的模式.但是,仍然建议通过DateFormat中的getTimeInstance.getDateInstance 或 getDateTimeInstance 来创建日期-时间格式器.每一个这样的类方法都能够返回一个以默认格式模式初始化的日期/时间格式器.可以根据需

  • java获取当前时间并格式化代码实例

    这篇文章主要介绍了java获取当前时间并格式化代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 private static final DateTimeFormatter FORMAT_FOURTEEN = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); private static final DateTimeFormatter FORMAT_DATE = DateTimeFor

  • 解决SpringMVC 返回Java8 时间JSON数据的格式化问题处理

    有时在Spring MVC中返回JSON格式的response的时候会使用@ResponseBody注解,不过在处理java8中时间的时候会很麻烦,一般我们使用的HTTPMessageConverter是MappingJackson2HttpMessageConverter,它默认返回的时间格式是这种: "startDate" : { "year" : 2010, "month" : "JANUARY", "dayO

  • Java使用DateFormatter格式化日期时间的方法示例

    本文实例讲述了Java使用DateFormatter格式化日期时间的方法.分享给大家供大家参考,具体如下: Java版本:1.8开始 import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; /** * Created by Fra

  • Java date format时间格式化操作示例

    本文实例讲述了Java date format时间格式化操作.分享给大家供大家参考,具体如下: import java.util.Date; import java.text.DateFormat; /** * 格式化时间类 * DateFormat.FULL = 0 * DateFormat.DEFAULT = 2 * DateFormat.LONG = 1 * DateFormat.MEDIUM = 2 * DateFormat.SHORT = 3 * @author Michael * @

  • Java日期时间格式化操作DateUtils 的整理

    Java日期时间格式化操作DateUtils 的整理 直接上代码,总结了开发过程中经常用到的日期时间格式化操作! import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.concurrent.TimeUnit; /** * ClassName: DateUtils <br/> * D

  • java 数值类型分秒时间格式化的实例代码

    java 数值类型分秒时间格式化的实例代码 java 实例代码: import java.util.concurrent.TimeUnit; public class DateUtils { private static final String[] UNIT_DESC = new String[]{"天", "小时", "分钟", "秒"}; /** * 格式化持续时间<br/> * 将持续时间,格式化为 xx天

  • Java使用DateTimeFormatter实现格式化时间

    用扫描器获取输入的时间(年月日时分),这个时间的格式是常用的格式,然后格式化这个时间,把格式化的时间输出到控制台,可以在控制台重复输入时间.格式化的时间参考企业微信聊天记录的展示时间.用DateTimeFormatter实现,功能如下: 同年: 不同年: 同月:月日+上午/下午+时分 同年不同月:月日+时分 今天:上午/下午+时分 明天:明天+上午/下午+时分 昨天:昨天+上午/下午+时分 包括今天在内的一周内:星期+上午/下午+时分 首先看一下测试类: package hrkj; import

  • Java使用DateTimeFormatter格式化输入的日期时间

    要求: 用DateTimeFormatter实现: 用扫描器获取输入的时间(年月日时分),这个时间的格式是常用的格式,然后格式化这个时间,把格式化的时间输出到控制台,可以在控制台重复输入时间.格式化的时间参考企业微信聊天记录的展示时间 分析: 1.时间的常用格式为: xxxx-xx-xx xx:xx xxxx/xx/xx xx:xx xxxx.xx.xx xx:xx 等格式 2.微信显式时间格式为: 今天显式: 00:01 - 23:59 ; 昨天显式: 昨天 01:01 ; 前天显式: 周几

  • java 格式化时间的示例代码

    package jkcs; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class jdcs { public static void main(String[] args) th

  • Java核心教程之常见时间日期的处理方法

    Java日期处理类Date详解 时间的基础知识 时区:整个地球分为二十四时区,每个时区都有自己的本地时间. 为了统一起见,使用一个统一的时间,称为全球标准时间(UTC,Universal Time Coordinated). TC与格林尼治平均时(GMT,Greenwich Mean Time,也翻译成:格林威治标准时间)差不多一样 CST(北京时间),北京时间,China standard Time,中国标准时间.在时区划分上,属东八区,比协调世界时早8小时,记为UTC+8. 时间戳:自197

  • js格式化时间小结

    废话不多说,先把各种格式化方法贴给大家 复制代码 代码如下: var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-????) myDate.getMonth(); //获取当前月份(0-11,0代表1月) myDate.getDate(); //获取当前日(1-31) myDate.getDay(); //获取当前星期X(0-6,0代表星期天) myDate

  • js格式化时间的方法

    本文为大家分享了javascript时间格式化的方法,分享给大家供大家参考,具体内容如下 可以说是Web项目中不可或缺的一个Javascript类库,它可以帮助你快速的解决客户端编程的许多问题,下面贴出一个用js格式化时间的方法. Date.prototype.format =function(format) { var o = { "M+" : this.getMonth()+1, //month "d+" : this.getDate(), //day &quo

  • Java8生成时间方式及格式化时间的方法实例

    LocalDate类 第一种:直接生成当前时间 LocalDate date = LocalDate.now(); System.out.println(date); 结果:2020-08-20 第二种:使用 LocalDate.of 构建时间 LocalDate date = LocalDate.now(); date = LocalDate.of(2020, 9, 20); System.out.println(date); 结果:2020-09-20 第三种:使用 LocalDate.pa

  • SpringBoot利用jackson格式化时间的三种方法

    前言 在实际开发中我们经常会与时间打交道,那这就会涉及到一个时间格式转换的问题.接下来会介绍几种在SpirngBoot中如何对时间格式进行转换. 准备工作 创建项目,添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 创建实体类UserDT

  • java中的日期和时间比较大小

    目录 日期和时间比较大小 java中日期如何比较大小 java中时间如何比较大小 比较两个日期时间,比较两个日期大小 LocalDateTime DateTimeFormatter 日期和时间比较大小 java中日期如何比较大小 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); //设置日期格式 Date begin = fmt.parse("2017-07-30"); //开始日期 Date end

随机推荐