本文源码:GitHub·点这里 || GitEE·点这里

一、时间和日期

在系统开发中,日期与时间作为重要的业务因素,起到十分关键的作用,例如同一个时间节点下的数据生成,基于时间范围的各种数据统计和分析,集群节点统一时间避免超时等。

在时间和日期中有几个关键概念:

  • 日期:通常年月日的组合表示当前日期。
  • 时间:通常时分秒的组合表示当前时间。
  • 时区:世界各国家与地区经度不同,划分24个标准时区,相邻时区的时间相差一个小时。
  • 时间戳:从UTC时间的1970-1-1 00:00:00起到现在的总秒数。

日期和时间的用法在系统中通常是获取时间和一些常见的计算与格式转换处理,在一些垮时区的业务中就会变的复杂很多,例如在电商业务中的全球贸易或者海淘等。

二、JDK原生API

1、Date基础

基础用法

java.sql.Date继承java.util.Date,相关方法也大部分直接调用父类方法。

public class DateTime01 {
public static void main(String[] args) {
long nowTime = System.currentTimeMillis() ;
java.util.Date data01 = new java.util.Date(nowTime);
java.sql.Date date02 = new java.sql.Date(nowTime);
System.out.println(data01);
System.out.println(date02.getTime());
}
}
打印:
Fri Jan 29 15:11:25 CST 2021
1611904285848

计算规则

public class DateTime02 {
public static void main(String[] args) {
Date nowDate = new Date();
System.out.println("年:"+nowDate.getYear());
System.out.println("月:"+nowDate.getMonth());
System.out.println("日:"+nowDate.getDay());
}
}

年份:当前时间减去1900;

public int getYear() {
return normalize().getYear() - 1900;
}

月份:0-11表示1-12月份;

public int getMonth() {
return normalize().getMonth() - 1;
}

天份:正常表示;

public int getDay() {
return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;
}

格式转换

非线程安全的日期转换API,该用法在规范的开发中是不允许使用的。

public class DateTime02 {
public static void main(String[] args) throws Exception {
// 默认转换
DateFormat dateFormat01 = new SimpleDateFormat() ;
String nowDate01 = dateFormat01.format(new Date()) ;
System.out.println("nowDate01="+nowDate01);
// 指定格式转换
String format = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat dateFormat02 = new SimpleDateFormat(format);
String nowDate02 = dateFormat02.format(new Date()) ;
System.out.println("nowDate02="+nowDate02);
// 解析时间
String parse = "yyyy-MM-dd HH:mm";
SimpleDateFormat dateFormat03 = new SimpleDateFormat(parse);
Date parseDate = dateFormat03.parse("2021-01-18 16:59:59") ;
System.out.println("parseDate="+parseDate);
}
}

作为JDK初始版本就使用的日期和时间,Date类一直在项目中使用,但是相关API的方法都已经基本废弃,通常使用一些二次封装的时间组件。该API的设计堪称Java中的最烂。

2、Calendar升级

Calendar作为一个抽象类,定义日期时间相关转换与计算的方法,这个类目测

public class DateTime04 {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR,2021);
calendar.set(Calendar.MONTH,1);
calendar.set(Calendar.DAY_OF_MONTH,12);
calendar.set(Calendar.HOUR_OF_DAY,23);
calendar.set(Calendar.MINUTE,59);
calendar.set(Calendar.SECOND,59);
calendar.set(Calendar.MILLISECOND,0);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
Date defDate = calendar.getTime();
System.out.println(defDate+"||"+dateFormat.format(defDate));
}
}
输出:Fri Feb 12 23:59:59 CST 2021||2021-02-12 23:59:59

直观感觉,Date中相关方法迁移Calendar实现,简化Date的功能侧重对日期与时间的实体封装,Calendar复杂相关计算策略,DateFormat依旧用来做格式处理。但是Calendar依旧很少被使用,上述基础API就已经是很好的说明了。

3、JDK1.8升级API

Java8之后的版本中,核心API类包括LocalDate-日期、LocalTime-时间、LocalDateTime-日期加时间。

  • LocalDate:日期描述是final修饰的不可变类,默认格式yyyy-MM-dd。
  • LocalTime:时间描述是final修饰的不可变类,默认格式hh:mm:ss.zzz。
  • LocalDateTime:日期与时间描述final修饰的不可变类。
public class DateTime05 {
public static void main(String[] args) {
// 日期:年-月-日
System.out.println(LocalDate.now());
// 时间:时-分-秒-毫秒
System.out.println(LocalTime.now());
// 日期时间:年-月-日 时-分-秒-毫秒
System.out.println(LocalDateTime.now());
// 日期节点获取
LocalDate localDate = LocalDate.now();
System.out.println("[" + localDate.getYear() +
"年];[" + localDate.getMonthValue() +
"月];[" + localDate.getDayOfMonth()+"日]");
// 计算方法
System.out.println("1年后:" + localDate.plusYears(1));
System.out.println("2月前:" + localDate.minusMonths(2));
System.out.println("3周后:" + localDate.plusWeeks(3));
System.out.println("3天前:" + localDate.minusDays(3)); // 时间比较
LocalTime localTime1 = LocalTime.of(12, 45, 45); ;
LocalTime localTime2 = LocalTime.of(16, 30, 30); ;
System.out.println(localTime1.isAfter(localTime2));
System.out.println(localTime2.isAfter(localTime1));
System.out.println(localTime2.equals(localTime1)); // 日期和时间格式
LocalDateTime localDateTime = LocalDateTime.now() ;
LocalDate myLocalDate = localDateTime.toLocalDate();
LocalTime myLocalTime = localDateTime.toLocalTime();
System.out.println("日期:" + myLocalDate);
System.out.println("时间:" + myLocalTime);
}
}

如果作为JodaTime组件的深度用户,对这个几个API使用基本无压力。

4、时间戳

时间戳也是业务中常用的方式,基于Long类型表示时间,在很多时候远比常规日期与时间的格式更好用。

public class DateTime06 {
public static void main(String[] args) {
// 精确到毫秒级别
System.out.println(System.currentTimeMillis());
System.out.println(new Date().getTime());
System.out.println(Calendar.getInstance().getTime().getTime());
System.out.println(LocalDateTime.now().toInstant(
ZoneOffset.of("+8")).toEpochMilli());
}
}

这里需要注意的是在实际业务中由于获取时间戳的方式是多样的,所以建议统一工具方法,和规定精确度,避免部分精确到秒部分精确到毫秒的问题,这样可以规避在使用时相互转换的情况。

三、JodaTime组件

在Java8之前JodaTime组件是大部分系统中的常见选择,有很多方便好用的日期与时间的处理方法封装。

基础依赖:

<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>

在joda-time提供的组件之上做一个简单的工具类封装,保证业务处理风格统一。

public class JodaTimeUtil {

    // 时间格式
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private JodaTimeUtil (){} // 获取当前时间
public static DateTime getCurrentTime (){
return new DateTime() ;
} // 获取指定时间
public static DateTime getDateTime (Object obj){
return new DateTime(obj) ;
} // 把时间以指定格式转换为字符串
public static String getNowDate (Date date, String format){
return new DateTime(date).toString(format) ;
} // 获取星期时间
public static String getWeek (Object date){
DateTime time = getDateTime (date) ;
String week = null ;
switch (time.getDayOfWeek()) {
case DateTimeConstants.SUNDAY:
week = "星期日";
break;
case DateTimeConstants.MONDAY:
week = "星期一";
break;
case DateTimeConstants.TUESDAY:
week = "星期二";
break;
case DateTimeConstants.WEDNESDAY:
week = "星期三";
break;
case DateTimeConstants.THURSDAY:
week = "星期四";
break;
case DateTimeConstants.FRIDAY:
week = "星期五";
break;
case DateTimeConstants.SATURDAY:
week = "星期六";
break;
default:
break;
}
return week ;
}
}

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/java-base-parent
GitEE·地址
https://gitee.com/cicadasmile/java-base-parent

阅读标签

Java基础】【设计模式】【结构与算法】【Linux系统】【数据库

分布式架构】【微服务】【大数据组件】【SpringBoot进阶】【Spring&Boot基础

数据分析】【技术导图】【 职场

Java基础篇(04):日期与时间API用法详解的更多相关文章

  1. Hadoop生态圈-zookeeper的API用法详解

    Hadoop生态圈-zookeeper的API用法详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.测试前准备 1>.开启集群 [yinzhengjie@s101 ~] ...

  2. Java中时间API使用详解

    目录 Java中时间API使用详解 1. 时区概念 2. 几种常见的时间 3. 时间戳 4. Java中的时间API 5. Java8中新添加的时间API 6. 在东八区的机器上获得美国时间 Java ...

  3. Java基础学习总结(53)——HTTPS 理论详解与实践

    前言 在进行 HTTP 通信时,信息可能会监听.服务器或客户端身份伪装等安全问题,HTTPS 则能有效解决这些问题.在使用原始的HTTP连接的时候,因为服务器与用户之间是直接进行的明文传输,导致了用户 ...

  4. java基础之JDBC一:概述及步骤详解

    1. JDBC的简介 概述: 就是Java用来操作不同数据库(DBMS)的类库(技术), 本质就是一些类和接口. /* 类: DriverManager 接口: Driver, Connection, ...

  5. JavaEE基础(02):Servlet核心API用法详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.核心API简介 1.Servlet执行流程 Servlet是JavaWeb的三大组件之一(Servlet.Filter.Listener) ...

  6. Java并发编程(06):Lock机制下API用法详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.Lock体系结构 1.基础接口简介 Lock加锁相关结构中涉及两个使用广泛的基础API:ReentrantLock类和Condition接 ...

  7. [置顶] Java基础学习总结(34)——HTTP协议详解

    一.什么是HTTP协议 HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的 ...

  8. 《Java基础知识》动态代理(InvocationHandler)详解

    1. 什么是动态代理 对象的执行方法,交给代理来负责.比如user.get() 方法,是User对象亲自去执行.而使用代理则是由proxy去执行get方法. 举例:投资商找明星拍广告,投资商是通过经纪 ...

  9. java基础: ArrayList集合应用, ArrayList增删改查详解,综合java基础实现学生管理系统,

    1.ArrayList 集合和数组的区别 : 共同点:都是存储数据的容器 不同点:数组的容量是固定的,集合的容量是可变的 1.1 -ArrayList的构造方法和添加方法 public ArrayLi ...

随机推荐

  1. HTML5 使用浏览器内置数据库之 indexedDB

    indexedDB是H5规范里的浏览器内置数据库,是nosql数据库的一种.因为另一种数据库Web SQL不再受W3C支持,所以还得学习下这个. 基本情况 兼容性:ie11及以上都支持, W3C是这么 ...

  2. Web信息收集-目标扫描-OpenVAS

    Web信息收集-目标扫描-OpenVAS 一.OpenVAS简述 二.部署OpenVAS 2.1 升级Kali Linux 2.2 安装OpenVAS 2.3 修改admin账户密码 2.4 修改默认 ...

  3. Spring5源码,@Autowired

    一.@Autowired所具有的功能 二.在Spring中如何使用@Autowired 三.@Autowired注解背后的工作原理 一.@Autowired所具有的功能 @Autowired是一个用来 ...

  4. gcc选项 笔记

    gcc –E hello.c –o hello.i   使用gcc的选项"-E" 让gcc在预处理结束后停止编译过程. gcc –S hello.i –o hello.s   &q ...

  5. 微信支付V3 SDK Payment Spring Boot 1.0.6 发布,实现留守红包,助力抗疫

    春节将至,为防控疫情,多地政府提倡员工.外来务工者留守本地过年,并鼓励企业向员工发放"留守红包".为此,微信支付推出"春节留守红包"能力,希望可以协助有发放需求 ...

  6. windows下使用HyperV安装Centos7虚拟机

    以前都是用的VM(VMWare)安装虚拟机, 然鹅, 现在电脑装了Docker需要开启Windows的HyperV, 而我使用的VM版本(14)和HyperV 是不兼容的, 于是搜索引擎搜索了一下解决 ...

  7. Linux 防火墙相关操作

    目录 1.查看防火墙状态 2.部署防火墙 3.常用操作 4.其他操作 1.查看防火墙状态 systemctl status firewalld 绿字部分 Active:active(running) ...

  8. 查看文件MD5值

    Windows 打开命令窗口(Win+R),然后输入cmd ·输入命令certutil -hashfile 文件绝对路径 MD5 Linux MD5算法常常被用来验证网络文件传输的完整性,防止文件被人 ...

  9. Codeforces Round #671 (Div. 2)

    比赛链接:https://codeforces.com/contest/1419 A. Digit Game 题意 给出一个 $n$ 位数,游戏规则如下: 1-indexed Raze标记奇数位 Br ...

  10. 2019HDU多校 Round10

    Solved:3 Rank:214 08 Coin 题意:n组硬币 每组有两个 分别有自己的价值 每组的第一个被拿了之后才能拿第二个 问拿1,2....2n个硬币的最大价值 题解:之前贪心带反悔的做法 ...