zoukankan      html  css  js  c++  java
  • 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)对象都是创建一个新的实例

  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/lzj0616/p/6196756.html
Copyright © 2011-2022 走看看