每日一类-java.util.Date

1. 简介

日期类型,常用的数据类型。内部记录的是从1970年1月1日0点(UTC)到当前时间经历的毫秒数。
关联的两个工具类CalendarSimpleDateFormat提供了时间的运算,格式化等api。

2. 概念

  1. GMT,UT, UTC
  2. 时区,夏令时

3. 源码

  1. toString(), wtb

    // 用于parse方法,已经废弃。只有[2-20]用于表示toString中的月份和星期
    private final static String wtb[] = {
            "am", "pm",
            "monday", "tuesday", "wednesday", "thursday", "friday",
            "saturday", "sunday",
            "january", "february", "march", "april", "may", "june",
            "july", "august", "september", "october", "november", "december",
            "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
            "mst", "mdt", "pst", "pdt"
        };
    
    public String toString() {
        // "EEE MMM dd HH:mm:ss zzz yyyy";
        ...
        // day of week,星期天是1,为了配置常量数组wtb,改为8
        int index = date.getDayOfWeek();
        if (index == BaseCalendar.SUNDAY) {
            index = 8;
        }
        ...
    }
  2. parse() vs DateFormat.parse(String s)
    无设计 vs 有设计

4. 示例

  1. 格式化
@Test
    public void testDate2String() {
        Date d = new Date();
        System.out.println(d);

        DateFormat df = DateFormat.getDateInstance();
        System.out.println(df.format(d));
    }
  1. 涉及夏令时的操作
    @Test
    public void testDst() {
        // 卢森堡
        System.setProperty("user.timezone", "Europe/Luxembourg");

        Date now = new Date();
        System.out.println(now);

        Calendar c = Calendar.getInstance();
        c.setTime(now);
        // 东1区,夏令时
        System.out.println(c.get(Calendar.ZONE_OFFSET) / (1000*60*60));
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));

        c.add(Calendar.MONTH, 3);
        // 非夏令时
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.ZONE_OFFSET) / (1000*60*60));
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));
    }

    @Test
    public void testOffsetDate() {
        // 卢森堡
        System.setProperty("user.timezone", "Europe/Luxembourg");
        Calendar c = Calendar.getInstance();
        // 此时仍是夏令时,DST OFFSET=1,偏移2个小时,包含一个DST切换补偿的一个小时
        // 卢森堡在当地时间 20181028日,03:00:00 时钟向后调整 1 小时 变为 20181028日,02:00:00,结束夏令时
        c.set(2018, 9, 28, 1, 59, 59);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));

        c.add(Calendar.HOUR, 2);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));

        c = Calendar.getInstance();
        // 2点以后,认为时区已经切换,不再有补偿
        c.set(2018, 9, 28, 2, 0, 0);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));

        c.add(Calendar.HOUR, 1);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));

        c = Calendar.getInstance();
        // 进入夏令时,没有2点,直接到3点
        // 卢森堡在当地时间 20180325日,02:00:00 时钟向前调整 1 小时 变为 20180325日,03:00:00,开始夏令时
        c.set(2018, 2, 25, 2, 0, 0);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));

        c.add(Calendar.HOUR, 1);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));

        c.set(2018, 2, 25, 1, 59, 59);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));

        c.add(Calendar.HOUR, 1);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DST_OFFSET) / (1000*60*60));
    }

5. 总结

  1. 前后台,涉及时间的传递时,建议使用字符串,避免客户端和服务端时区不一致,导致时间更新异常。
  2. 在存在夏令时的地区,时间处理需要特别注意下DST_OFFSET。
    数据库中的时间需要统一时区来记录。
  3. 了解常用的几种日期格式即可。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值