java 时间类详解(一)

java 常用的时间工具类

  • java.util.Calender
  • java.util.Date 是用于表示一个日期和时间的对象(实际一个long类型的以毫秒表示的时间戳)
  • java.time.LocalDateTime
  • java.time.LocalDate
  • java.time.ZonedDateTime
  • java.time.Instant

初始化操作及具体时间的指定:

  • data
 public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:MM:ss");
        // 导包的时候要注意不要导成java.sql.Date
        Date date = new Date();
        System.out.println(sdf.format(date));
        System.out.println(date.getYear() + 1900); // 必须加上1900
        System.out.println(date.getMonth() + 1); // 0~11,必须加上1
        System.out.println(date.getDate()); // 1~31,不能加1
        // 转换为String:
        System.out.println(date.toString());
        // 转换为GMT时区:
        System.out.println(date.toGMTString());
        // 转换为本地时区:
        System.out.println(date.toLocaleString());
    }

date设置指定时间的的一些方法目前1.8都不推荐使用了,如下:
在这里插入图片描述

  • Calender
public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 支持四种初始化的方式,可以根据具体的业务,选择合适的方式
        Calendar calendar = Calendar.getInstance();
        // 清除默认的当前时间设置指定的时间(清除所有)
        calendar.clear();
        calendar.set(Calendar.YEAR, 2020);
        // 设置八表示九月
        calendar.set(Calendar.MONTH, 8);
        // 其他属性不设置则使用默认值
        // 调用getTime使Calender对象转为Date,才做时间处理
        System.out.println(sdf.format(calendar.getTime()));
    }

LocalDateTime

  public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 为时间可以具体到秒
        LocalDateTime time = LocalDateTime.now();
        // 当前时间的加多少分钟,其他属性也是plus开头的,减时间为minus开头的方法
        time.plusMinutes(10);
        String format = dtf.format(time);
        System.out.println(format); //print 2020-10-30 14:22:30
    }

LocalDate

  public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 为时间可以具体到秒
        LocalDate time = LocalDate.now();
        // 当前时间的加多少分钟,其他属性也是plus开头的,减时间为minus开头的方法(不能支持到小时以后更小的操作)
        // 同时 DateTimeFormatter不能指定到小时以后,否则抛出UnsupportedTemporalTypeException异常
        time.plusDays(10);
        String format = dtf.format(time);
        System.out.println(format); //print 2020-10-30 14:22:30
    }

ZoneLocalDateTime

 public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 默认时区,若需特别指定具体的时区时可以ZonedDateTime.now(ZoneId.of("America/New_York")); 用指定时区获取当前时间
        ZonedDateTime time = ZonedDateTime.now();
        time.plusDays(10);
        String format = dtf.format(time);
        System.out.println(format);
        // 以中国时区获取当前时间:
        ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        // 转换为纽约时间:
        ZonedDateTime zny = now.withZoneSameInstant(ZoneId.of("America/New_York"));
        System.out.println(now);
        System.out.println(zny);
    }

**Instant **

public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 这个当前时间戳在java.time中以Instant类型表示,我们用Instant.now()获取当前时间戳,
        Instant now = Instant.now();
        // 不可格式化
        System.out.println(now.getEpochSecond()); // 秒
        System.out.println(now.toEpochMilli()); // 毫秒
    }

格式化参数说明

  • G Era 标志符
  • y 年
  • M 年中的月份
  • w 年中的周数
  • W 月中的周数
  • D 年中的天数
  • d 月中的天数
  • F 月份中的星期
  • E 星期中的天数
  • a Am/pm 标记
  • H 一天中的小时数(0-23)
  • k 一天中的小时数(1-24
  • K am(中午)/pm(下午) 中的小时数(0-11)
  • h am(中午)/pm(下午) 中的小时数(1-12)
  • m 小时中的分钟数
  • s 分钟中的秒数
  • S 毫秒

常用的时间格式类(java)

  • SimpleDateFormat
  • DateTimeFormatter
    SimpleDateFormat是一个可变的对象,使用的使用会存在一定线程安全问题。而DateFimeFormatter反之(因为是一个不可变对象,同时只创建一个实例)

初始化方式和简单使用:


    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        // 使用DateTimeFormatter,将LocalDateTime转为指定格式的String
        System.out.println("dateTimeFormatter ——————>" + dtf.format(now));
        Date date = new Date();
        
        System.out.println("simpleDateFormat ——————>" + sdf.format(date));
        String str = "2020-10-30 15:04:19";
        LocalDateTime specified = LocalDateTime.parse(str,dtf);
        Date parse = sdf.parse(str);
        
    }

SimpleDateFormat线程安全的问题的bug复现


    //(1)创建单例实例
    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args) throws ParseException {
        //(2)创建多个线程,并启动
        for (int i = 0; i < 20; ++i) {
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    try {//(3)使用单例日期实例解析文本
                        System.out.println(sdf.parse("2020-10-30 15:26:22"));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            });
            thread.start();//(4)启动线程
        }

    }

在这里插入图片描述
通过运行的结果可知,近三分之一的都报错了。可以通过改造使其达到线程安全(过程繁琐,不如之间用DateTimeFormatter)。
改造为线程安全的SimpleDateFormat如下:

 // 用于存放不同模式的SimpleDateFormat
    private static Map<String, ThreadLocal<SimpleDateFormat>> containerMap = new HashMap<>();

    private static final ReentrantLock lock = new ReentrantLock();

    /**
     * 功能描述 根据不同格式化要求,返回不同的安全的SimpleDateFormat对象
     *
     * @param pattern
     * @return SimpleDateFormat对象
     */
    public static SimpleDateFormat getSimpleDateFormat(final String pattern) {
        ThreadLocal<SimpleDateFormat> local = containerMap.get(pattern);
        final ReentrantLock creatLock = lock;
        if (local == null) {
            // 加锁操作
            creatLock.lock();
            try {
                local = containerMap.get(pattern);
                if (local == null) {
                    local = new ThreadLocal<SimpleDateFormat>() {
                        @Override
                        protected SimpleDateFormat initialValue() {
                            return new SimpleDateFormat(pattern);
                        }
                    };
                }

            } finally {
                creatLock.unlock();
            }
        }
        return local.get();
    }

性能对比
使用默认的性能如下:
在这里插入图片描述
优化后性能如下:
在这里插入图片描述

以上为java提供时间类的简单使用总结。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值