• Java日期时间处理


    Java日期时间处理

    Author: lzj

    1. 常用日期类

    java.util.Date
    代码中一般创建的就是这个类的对象,
    需要注意的是: 这个类的部分方法已经 @Deprecated 了, 对应推荐使用下面说到的Calendar类的相关方法
    常用方法:

    • getTime() / setTime(long time)
    • before(Date date) / after(Date date)
    • compareTo(Date date)

    java.sql.Date
    java.sql.Time
    java.sql.Timestamp
    这三个类是java.util.Date的子类, 主要是为了针对SQL语句时使用

    java.util.Calendar
    Calendar是一个抽象类, 用来获取一个时间点的时间信息, 例如: 取每月第一天, 每月最后一天, 一年中的第几天等等都使用这个类
    获取Calendar实例的方法:

    Calendar c = Calendar.getInstance();
    

    Calendar类的常用方法:

    • getTime(), 返回一个Date对象, 一般是利用Calendar对象处理好时间信息, 然后调用getTime()方法返回Date对象
    • getTimeInMillis(), 也可以调用这个方法返回long毫秒数
    • get(int field), 返回参数指定日历字段的值
    • set(int field, int value), 设置参数指定日历字段的值
    • add(int field, int amount), 在指定的日历字段上加或减去参数值
    • set方法还有三个重载, 可以直接设置年, 月, 日, 时, 分, 秒

    关于参数field
    Calendar提供了大量的静态常量, 分别表示不同的时间点含义

    Date now = new Date(); // 示例代码运行时间: 2016-11-03 15:29:29
    Calendar c = Calendar.getInstance();
    c.setTime(now);
    
    System.out.println(c.get(Calendar.YEAR)); // 2016
    System.out.println(c.get(Calendar.MONTH)); // 10, 注意月份是从0开始的
    System.out.println(c.get(Calendar.DATE)); // 3
    
    System.out.println(c.get(Calendar.WEEK_OF_MONTH)); // 1, 本月第几周
    System.out.println(c.get(Calendar.DAY_OF_WEEK)); // 5, 本周第几天, 从周日开始算
    
    System.out.println(c.get(Calendar.HOUR_OF_DAY)); // 15, 24小时制
    System.out.println(c.get(Calendar.MINUTE)); // 29
    System.out.println(c.get(Calendar.SECOND)); //29
    

    java.text.DateFormatjava.text.SimpleDateFormat
    这两个类用来将日期对象格式化(format方法)为字符串, 或将字符串解析(parse方法)为日期对象
    DateFormat是抽象类, 为SimpleDateFormat的父类, 编码时使用SimpleDateFormat实例化对象即可

    Date currDate = new Date();
    String strCurrDate = "2016-11-03 15:29:29";
    
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(df.format(currDate));
    System.out.println(df.parse(strCurrDate));
    

    注意事项:
    Calendar, DateFormat, SimpleDateFormat 为非线程安全类

    2. DateUtils和DateFormatUtils

    DateUtils和DateFormatUtils 属于Apache Commons项目的Lang包, 位于org.apache.commons.lang.time包目录下,
    其作用就是处理日期时间信息.
    DateUtils和DateFormatUtils的实现, 就是对Calendar, Date, SimpelDateFormat等基本日期时间类的综合使用, 熟悉了这些日期时间基本类的使用之后, 完全可以自己封闭属于自己的日期工具类.

    2.1 DateUtils常用方法

    add方法
    • addYears(Date date, int amount)
    • addMonths(Date date, int amount)
    • addDays(Date date, int amount)
    • addHours(Date date, int amount)
    • addMinutes(Date date, int amount)
    • addSeconds(Date date, int amount)

    这组6个方法比较常用, 其作用就是在相应的日历字段上加减参数值, 并返回一个新的Date对象
    其实现就是调用了Calendar类的setTime(Date date)方法和add(int field, int amount)方法
    以addYears为例, 看下源码

    public static Date addYears(Date date, int amount) {
        return add(date, Calendar.YEAR, amount);
    }
    
    Deprecated
    public static Date add(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(calendarField, amount);
        return c.getTime();
    }
    

    这里DateUtils将add方法@Deprecated了, 并不是说这个方法不能使用了, 而是不再建议在外部调用这个方法,
    对这个方法做了一次重构(以明确函数取代参数), 我们只需要使用重构后的具体方法就可以了.

    重构手法: 以明确函数取代参数
    针对参数的每一个可能值, 建立一个独立的函数, 详情见《重构 改善既有代码的设计》

    set方法
    • setYears(Date date, int amount)
    • setMonths(Date date, int amount)
    • setDays(Date date, int amount)
    • setHours(Date date, int amount)
    • setMinutes(Date date, int amount)
    • setSeconds(Date date, int amount)

    这6个方法作用是给日期对象的特定日历字段赋值, 对应的这个方法中使用的是Calendar类的set(int field, int value)方法

    舍入方法
    • round(Date date, int field)
    • round(Calendar date, int field)
    • round(Object date, int field)
    • truncate(Date date, int field)
    • truncate(Calendar date, int field)
    • truncate(Object date, int field)

    这组方法主要是对日期时间对象进行"四舍五入"或"截断"操作
    round()方法的三个重载实现的功能是四舍五入, 第2个参数field表示对此字段右侧的字段进行四舍五入操作
    truncate()方法的三个重载实现的功能是截断, 第2个参数field表示对此字段右侧的字段进行截断

    String strCurrDate = "2016-11-03 13:40:29";
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = df.parse(strCurrDate);
    
    System.out.println(DateUtils.round(date, Calendar.HOUR));
    System.out.println(DateUtils.truncate(date, Calendar.HOUR));
    
    // Thu Nov 03 14:00:00 CST 2016
    // Thu Nov 03 13:00:00 CST 2016
    
    比较方法
    • isSameDay(Date date1, Date date2)
    • isSameDay(Calendar cal1, Calendar cal2)
    • isSameInstant(Date date1, Date date2)
    • isSameInstant(Calendar cal1, Calendar cal2)

    从方法名很容易识别这组方法的功能,
    isSameDay的两个重载方法用于判断两个日期时间对象是否是同一天
    isSameInstant的两个重载方法用于判断两个日期时间对象是否是同一个实例

    getFragmentIn*系列方法
    • getFragmentInDays(Date date, int fragment)
    • getFragmentInHours(Date date, int fragment)
    • ...

    表示指定时间的天(小时)数, 关键参数是fragment, 为Calendar指定的时间常量字段值.

    String strCurrDate = "2016-11-03 13:40:29";
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = df.parse(strCurrDate);
    
    System.out.println(DateUtils.getFragmentInDays(date, Calendar.YEAR)); // 308, 表示当年已经过去308天
    System.out.println(DateUtils.getFragmentInDays(date, Calendar.MONTH)); // 3, 表示当月已经过去3天
    
    System.out.println(DateUtils.getFragmentInHours(date, Calendar.MONTH)); // 85, 表示当月已经过去85小时
    System.out.println(DateUtils.getFragmentInHours(date, Calendar.DATE)); // 13, 表示当天已经过去13小时
    

    若传入的fragment参数的值不在Calendar类定义的日期常量字段值的范围内, 则抛出异常信息:

    Exception in thread "main" java.lang.IllegalArgumentException: The fragment 123 is not supported
    

    若传入的fragment参数的值不在语义范围内, 则返回0, 例如:

    System.out.println(DateUtils.getFragmentInHours(date, Calendar.MINUTE)); // 0, 在当前分钟中, 取不出过去了多少小时
    
    iterator方法
    • iterator(Date focus, int rangeStyle)
    • iterator(Calendar focus, int rangeStyle)
    • iterator(Object focus, int rangeStyle)

    DateUtils提供了迭代器方法, 这个方法会返回一个Iterator对象, Iterator对象中包含了指定范围(rangeStyle)的日期对象.
    关于参数rangeStyle的取值, DateUtils提供了6个int型静态常量, 分别为:

    /** A week range, starting on Sunday. */
    public final static int RANGE_WEEK_SUNDAY = 1;
    
    /** * A week range, starting on Monday. */
    public final static int RANGE_WEEK_MONDAY = 2;
    
    /** * A week range, starting on the day focused. */
    public final static int RANGE_WEEK_RELATIVE = 3;
    
    /** A week range, centered around the day focused. */
    public final static int RANGE_WEEK_CENTER = 4;
    
    /** A month range, the week starting on Sunday. */
    public final static int RANGE_MONTH_SUNDAY = 5;
    
    /** * A month range, the week starting on Monday. */
    public final static int RANGE_MONTH_MONDAY = 6;
    

    举个例子:

    String strCurrDate = "2016-11-05";
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    Date date = df.parse(strCurrDate);
    
    Iterator<Calendar> iter2 = DateUtils.iterator(date, DateUtils.RANGE_WEEK_RELATIVE);
    while(iter2.hasNext()) {
        Calendar c = iter2.next();
        System.out.println(df.format(c.getTime()));
    }
    
    // 输出结果: 
    // 2016-11-05
    // 2016-11-06
    // 2016-11-07
    // 2016-11-08
    // 2016-11-09
    // 2016-11-10
    // 2016-11-11
    
    parseDate方法
    • parseDate(String str, String[] parsePatterns)

    DateUtils只提供了一个解析日期的方法,
    第一个参数为要解析的日期字符串
    第二个参数为一个字符串数组, 数组中的元素为解析日期所需要的模式串
    在方法实现中, 遍历数据parsePatterns以解析日期字符串, 解析成功即跳出遍历, 返回Date对象

    2.2 DateFormatUtils常用方法

    • format(long millis, String pattern)
    • format(Date date, String pattern)
    • format(Calendar calendar, String pattern)

    就是format方法的三个重载, 很简单

    DateUtils和DateFormatUtils除了使用简单方便之外, 还有个好处就是线程安全
    因为在方法内部, 无论是Calendar对象还是DateFormat(DateFormatUtils类使用的是FastDateFormat)对象都是创建一个新的实例

  • 相关阅读:
    C#串口通信程序实现无感知签到与答题
    C# 调用adb command 读取手机型号和IMEI
    sql 截取字符串
    .NET下的ORM框架有哪些
    linq-to-sql实现left join,group by,count
    C# 生成二维码
    数据库面试题.net
    .net面试中的一些常见问题与答案
    Jquery判断其中任意一个文本框的值是否被修改
    矩阵乘法的MPI并行计算
  • 原文地址:https://www.cnblogs.com/lzj0616/p/6196756.html
Copyright © 2020-2023  润新知