Java中的时间和日期

Date

    该类出现于JDK1.1,且该类提供了对日期进行操作的诸多方法,但是其一直存在着很多问题。官方也意识到了这个问题后来提供了Calendar类进行对日期的操作,日期的格式化交给了DateFormat

Date类的构造方法简述
    1. Date()  // 无参构造器,分配Date对象,并使用当前的时间初始化
    2. Date(long date) // 分配Date对象,使用自基准时间(元年 1970年1月1日 00:00:00)以来的毫秒数进行初始化

Date方法简述
    1. boolean after(Date when) // 输入一个时间判断是否在当前时间之后
    2. boolean before(Date when) // 同上判断是否在当前时间之前
    3. int compareTo(Date anotherDate) // 用当前的时间和输入的时间做比较 若等于返回0 若输入日期在当前之前返回一个负数 若输入日期在当前日期之后则返回一个正数
    4. String toString() // 把当前的 Date 对象转换成规定格式的字符串然后返回(dow mon dd hh:mm:ss zzz yyyy)

    上述的方法和构造方法都摘录于 JDK API1.6

OK!接下来就是 Calender类了

该类在源码中是这样定义的:

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> 

    首先这是一个抽象类,说明我们不能直接将其 new 一个对象出来,因为此 Calendar 给我们提供了一个获取实例的方法 getInstance()
    该方法返回的是一个 Calendar 对象(该对象为 Calendar的子类对象),用该种方式获取对象之后,其日历字段已由当前的日期和时间初始化。
    为什么说返回的 Calendar 对象是一个子类对象呢?因为每个国家和地区都有自己的一套日历算法。

// 这个是该方法的源码
public static Calendar getInstance()
{
    return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}

    根据器其源码我们可以看出 createCalendar 就是根据不同国家地区返回对应的时间子类。

// createCalendar 方法的源码
private static Calendar createCalendar(TimeZone zone, Locale aLocale)
    {
        CalendarProvider provider =
            LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
                                 .getCalendarProvider();
        if (provider != null) {
            try {
                return provider.getInstance(zone, aLocale);
            } catch (IllegalArgumentException iae) {
                // fall back to the default instantiation
            }
        }

        Calendar cal = null;

        if (aLocale.hasExtensions()) {
            String caltype = aLocale.getUnicodeLocaleType("ca");
            if (caltype != null) {
                switch (caltype) {
                case "buddhist":
                cal = new BuddhistCalendar(zone, aLocale);
                    break;
                case "japanese":
                    cal = new JapaneseImperialCalendar(zone, aLocale);
                    break;
                case "gregory":
                    cal = new GregorianCalendar(zone, aLocale);
                    break;
                }
            }
        }
        if (cal == null) {
            // If no known calendar type is explicitly specified,
            // perform the traditional way to create a Calendar:
            // create a BuddhistCalendar for th_TH locale,
            // a JapaneseImperialCalendar for ja_JP_JP locale, or
            // a GregorianCalendar for any other locales.
            // NOTE: The language, country and variant strings are interned.
            if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
                cal = new BuddhistCalendar(zone, aLocale);
            } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                       && aLocale.getCountry() == "JP") {
                cal = new JapaneseImperialCalendar(zone, aLocale);
            } else {
                cal = new GregorianCalendar(zone, aLocale);
            }
        }
        return cal;
    }
如何使用Calender
    构造方法
1. Calendar()    // 构造一个带有默认时区和语言环境的 Calendar
2. Calendar(TimeZone zone, Locale aLocale)    // 构造一个带有指定时区和语言环境的 Calendar

/*
    Calendar中常用的方法代码演示
*/
public class App01 {
    static Calendar calendar = null;
    static {
        calendar = Calendar.getInstance();
    }
    // 设置日期
    public static void test4() {
        calendar.set(Calendar.YEAR, 2000);
        System.out.println("现在是:" + calendar.get(Calendar.YEAR) + "年");
        calendar.set(2008, 8, 8);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println("现在是:" + year + "年" + month + "月" + day + "日");
    }

    // 获取任意一个月的最后一天
    public static void test3() {
        // 假设求 5 月的最后一天
        int currentMonth = 5;
        // 先求出6月份的第一天,实际中这里5为外部传递进来的 currentMonth 变量
        calendar.set(calendar.get(Calendar.YEAR), currentMonth, 1);
        calendar.add(Calendar.DATE, -1);
        // 获取日
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println("5月份的最后一天为" + day + "号");
    }


    // 一年后的今天
    public static void test2() {
        // 在Calendar中选择 Year属性 +1
        calendar.add(Calendar.YEAR, 1);
        int Year = calendar.get(Calendar.YEAR);
        // Month
        int Month = calendar.get(Calendar.MONTH) + 1;
        // Day
        int Day = calendar.get(Calendar.DAY_OF_MONTH);
        // Hour
        int Hour = calendar.get(Calendar.HOUR);
        // Minute
        int Minute = calendar.get(Calendar.MINUTE);
        // Second
        int Second = calendar.get(Calendar.SECOND);
        // WeekDay
        int WeekDay = calendar.get(Calendar.DAY_OF_WEEK);
        System.out.println(Year + "年:" + Month + "月:" + Day + "日:" + Hour + "时:" + Minute + "分:" + Second + "秒:星期" + WeekDay );
    }

    public static void test1 () {        
        // Year
        int Year = calendar.get(Calendar.YEAR);
        // Month
        int Month = calendar.get(Calendar.MONTH) + 1;
        // Day
        int Day = calendar.get(Calendar.DAY_OF_MONTH);
        // Hour
        int Hour = calendar.get(Calendar.HOUR);
        // Minute
        int Minute = calendar.get(Calendar.MINUTE);
        // Second
        int Second = calendar.get(Calendar.SECOND);
        // WeekDay
        int WeekDay = calendar.get(Calendar.DAY_OF_WEEK);
        System.out.println(Year + "年:" + Month + "月:" + Day + "日:" + Hour + "时:" + Minute + "分:" + Second + "秒:星期" + WeekDay );
    }
}

    根据Calendar类与Date类的对比我们发现,同样是对于日期的操作,Calendar 的操作更加的严谨和有效率。

OK 接下来是日期的格式类 DateFormat

    首先是 DateFormat 在源码中的定义

public abstract class DateFormat extends Format

    此类是一个抽象类,证明我们不能使用 new 的方式获取其实例化对象,直接使用其子类实例化即可,但是这个类还提供了可以直接获取其实例化对象的方法。

// 两个产生 DateFormat 对象的基础方法
private static DateFormat get(int timeStyle, int dateStyle, int flags, Locale loc) {
    if ((flags & 1) != 0) {
        if (timeStyle < 0 || timeStyle > 3) {
            throw new IllegalArgumentException("Illegal time style " + timeStyle);
        }
    } else {
        timeStyle = -1;
    }
    if ((flags & 2) != 0) {
        if (dateStyle < 0 || dateStyle > 3) {
            throw new IllegalArgumentException("Illegal date style " + dateStyle);
        }
    } else {
        dateStyle = -1;
    }

    LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DateFormatProvider.class, loc);
    DateFormat dateFormat = get(adapter, timeStyle, dateStyle, loc);
    if (dateFormat == null) {
        dateFormat = get(LocaleProviderAdapter.forJRE(), timeStyle, dateStyle, loc);
    }
    return dateFormat;
}
private static DateFormat get(LocaleProviderAdapter adapter, int timeStyle, int dateStyle, Locale loc) {
    DateFormatProvider provider = adapter.getDateFormatProvider();
    DateFormat dateFormat;
    if (timeStyle == -1) {
        dateFormat = provider.getDateInstance(dateStyle, loc);
    } else {
        if (dateStyle == -1) {
            dateFormat = provider.getTimeInstance(timeStyle, loc);
        } else {
            dateFormat = provider.getDateTimeInstance(dateStyle, timeStyle, loc);
        }
    }
    return dateFormat;
}

// 获得时间的 DateFormat 对象的三个重载方法
public final static DateFormat getTimeInstance()
{
    return get(DEFAULT, 0, 1, Locale.getDefault(Locale.Category.FORMAT));
}
public final static DateFormat getTimeInstance(int style)
{
    return get(style, 0, 1, Locale.getDefault(Locale.Category.FORMAT));
}
public final static DateFormat getTimeInstance(int style, Locale aLocale)
{
    return get(style, 0, 1, aLocale);
}

// 获得日期的 DateFormat 对象的三个重载方法
public final static DateFormat getDateInstance()
{
    return get(0, DEFAULT, 2, Locale.getDefault(Locale.Category.FORMAT));
}
public final static DateFormat getDateInstance(int style)
{
    return get(0, style, 2, Locale.getDefault(Locale.Category.FORMAT));
}
public final static DateFormat getDateInstance(int style, Locale aLocale)
{
    return get(0, style, 2, aLocale);
}

// 获得时间日期的 DateFormat 对象的三个重载方法
public final static DateFormat getDateTimeInstance()
{
    return get(DEFAULT, DEFAULT, 3, Locale.getDefault(Locale.Category.FORMAT));
}
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle)
{
    return get(timeStyle, dateStyle, 3, Locale.getDefault(Locale.Category.FORMAT));
}
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)
{
    return get(timeStyle, dateStyle, 3, aLocale);
}

// 默认的是获得的日期时间的 DateFormat 对象
public final static DateFormat getInstance() {
    return getDateTimeInstance(SHORT, SHORT);
}

    通过上面的源码展示我们可以知道,在DateFormat 对象的获取的过程中,虽然可以获得不同的 DateFormat 对象,但是这些方法的被后都依赖于一个 get() 方法。
    我们继续看两个 get 方法,我们又会发现,其实上面的那个 get 方法,也是依赖于下面的按个 get 方法,我们看下面的那个 get 方法,又会发现一个叫做 DateForamtProvider 的类,看名字就是一个 DateFormat 对象的提供者,OK 继续深入其源码,发现其居然是一个抽象类,其类中维护着几个 get类的抽象方法。

接下来的是 DateFormat 的子类,我们平时使用更加频繁的一个对象 SimpleDateFormat

    首先是其源码中的定义

public class SimpleDateFormat extends DateFormat 

    它是继承自 DateFormat 抽象类的一个普通类
    使用这个类的时候,首先得准备好一个日期格式模板,根据模板的格式来转化日期
这里写图片描述

    如何使用这个类

// 构造方法
public SimpleDateFormat(String pattern)
// 转化
public Date parse(String source) throws ParseException    //-->此时取得的是全部时间数
// 格式化
public final String Format(Date date)    //-->将时间重新格式化成字符串显示

    SimpleDateFormat类使用具体实例

public static void test1() {
    SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
    SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yy/MM/dd HH:mm");
    SimpleDateFormat simpleDateFormat3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 等价于 mow.toLocaleString()
    SimpleDateFormat simpleDateFormat4 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E ");
    SimpleDateFormat simpleDateFormat5 = new SimpleDateFormat("一年中的第 D 天 一年中的第 W 个星期 在一天中k时 z时区");
    Date date = new Date();
    System.out.println(date);
    System.out.println(simpleDateFormat1.format(date));
    System.out.println(simpleDateFormat2.format(date));
    System.out.println(simpleDateFormat3.format(date));
    System.out.println(simpleDateFormat4.format(date));
    System.out.println(simpleDateFormat5.format(date));
    System.out.println(date.toGMTString());
    System.out.println(date.toLocaleString());
    System.out.println(date.toString());
}

输出为:
Sun Mar 11 22:05:25 CST 2018
2018031122052518/03/11 22:05
2018-03-11 22:05:25
20180311220525秒 星期日
一年中的第 70 天 一年中的第 3 个星期 在一天中22时 CST时区
11 Mar 2018 14:05:25 GMT
2018-3-11 22:05:25
Sun Mar 11 22:05:25 CST 2018

    把给定的字符串中的日期提取为Date

public static void test2() throws Exception {
    String strDate = "2018-10-19 10:11:30.345";
    // 准备第一个模板 从字符串中提取日期文字
    String pat1 = "yyyy-MM-dd HH:mm:ss.SSS";
    // 准备第二个摹本 从字符串中提取日期文字
    String pat2 = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒";
    SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pat1);    // 实例化模板对象
    SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat(pat2);    // 实例化模板对象
    Date date = null;
    System.out.println(simpleDateFormat1.parse(strDate));
    try {
        date = simpleDateFormat2.parse(strDate);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值