Date类

java.util 包提供了 Date 类来封装当前的日期和时间,Date 类提供两个构造函数来实例化 Date 对象

  • 第一个构造函数使用当前日期和时间来初始化对象   Date( )
  • 第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数  Date(long millisec)
package com.yyx.util;

import java.util.Date;

/**
 * 日期时间工具类
 *
 * @author yyx 2018年6月25日
 */
public class DateUtil {
    public static void main(String[] args) {
        testDate();
    }

    /**
     * Date类的其他方法都已过时,被替代
     */
    public static void testDate() {
       Date date=new Date();
       System.out.println(date.toString());

       //getTime() 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数
       long currentTime=date.getTime();
       System.out.println(currentTime);

       //设置此 Date 对象,以表示 1970 年 1 月 1 日 00:00:00 GMT 以后 time 毫秒的时间点
       date.setTime(currentTime+1530367288365L);
       System.out.println(date.toString());

       long time=System.currentTimeMillis();
       Date dateAnother=new Date(time);
       System.out.println(dateAnother.toString());
    }
}

 Calendar类

     Calendar是一个抽象类,不能直接实例化,但是Calendar类提供一个工厂方法,即getInstance来创建一个Calendar实例

package com.yyx.util;

import java.util.Calendar;
import java.util.Date;

/**
 * 日期时间工具类
 *
 * @author yyx 2018年6月25日
 */
public class DateUtil {
    public static void main(String[] args) {
        TestCalendar();
    }

    public static void TestCalendar() {
        Calendar calendar = Calendar.getInstance();
        // 获取年份
        int year = calendar.get(Calendar.YEAR);
        // 获取月,这里需要需要月份的范围为0~11,因此获取月份的时候需要+1才是当前月份值
        int month = calendar.get(Calendar.MONTH) + 1;
        // 获取日
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        // 获取时
        // int hour = calendar.get(Calendar.HOUR);
        int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24小时表示
        // 获取分
        int minute = calendar.get(Calendar.MINUTE);
        // 获取秒
        int second = calendar.get(Calendar.SECOND);
        // 星期,英语国家星期从星期日开始计算
        int weekday = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        System.out.println(year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second + " 星期" + weekday);

        //将给定的日历字段设置为给定值
        calendar.set(Calendar.YEAR, 2020);
        calendar.set(Calendar.MONTH, 7);
        System.out.println(calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH)+1) + "-" + day + " " + hour + ":" + minute + ":" + second + " 星期" + weekday);

        //根据日历的规则,为给定的日历字段添加或减去指定的时间量
        calendar.add(Calendar.YEAR, 2);
        System.out.println(calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH)+1) + "-" + calendar.get(Calendar.DAY_OF_MONTH));

        //返回一个表示此 Calendar 时间值(从历元至现在的毫秒偏移量)的 Date 对象
        Date date=calendar.getTime();
        System.out.println(date.toString());

        //使用给定的 Date 设置此 Calendar 的时间
        Date dateAnother=new Date();
        calendar.setTime(dateAnother);
        System.out.println(calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH)+1) + "-" + calendar.get(Calendar.DAY_OF_MONTH));
    }
}

 SimpleDateFormat类

      SimpleDateFormat 是一个以与语言环境相关的方式来格式化和分析日期的具体类。它允许进行格式化(日期 -> 文本)、分析(文本 -> 日期)和规范化

package com.yyx.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日期时间工具类
 *
 * @author yyx 2018年6月25日
 */
public class DateUtil {
    public static void main(String[] args) {
        testSimpleDateFormat();
    }

    public static void testSimpleDateFormat() {
        //format() 将给定的 Date 格式化为日期/时间字符串
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        Date date=new Date();
        System.out.println(simpleDateFormat.format(date));

        String dateString = "2009-08-02 13:43:00";
        SimpleDateFormat df =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //parse() 解析字符串的文本,生成 Date
        try {
            System.out.println(df.parse(dateString));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

SimpleDateFormat日期格式是不同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须是外部同步的

解决方法

1、需要的时候创建新实例

说明:在需要用到 SimpleDateFormat 的地方新建一个实例,不管什么时候,将有线程安全问题的对象由共享变为局部私有都能避免多线程问题,不过也加重了创建对象的负担。在一般情况下,这样其实对性能影响比不是很明显的。

2、使用同步:同步 SimpleDateFormat 对象

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateSyncUtil {

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static String formatDate(Date date) throws ParseException {
        synchronized(sdf) {
            return sdf.format(date);
        }
    }

    public static Date parse(String strDate) throws ParseException {
        synchronized(sdf) {
            return sdf.parse(strDate);
        }
    }
}

      说明:当线程较多时,当一个线程调用该方法时,其他想要调用此方法的线程就要 block 等待,多线程并发量大的时候会对性能有一定的影响

3、使用 ThreadLocal

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ConcurrentDateUtil {

    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    public static Date parse(String dateStr) throws ParseException {
        return threadLocal.get().parse(dateStr);
    }

    public static String format(Date date) {
        return threadLocal.get().format(date);
    }
}

      说明:使用 ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法

4、Java 8 中的解决办法

Java 8 提供了新的日期时间 API,其中包括用于日期时间格式化的 DateTimeFormatter,它与 SimpleDateFormat 最大的区别在于:DateTimeFormatter 是线程安全的,而 SimpleDateFormat 并不是线程安全

Java常用类Date、Calendar、SimpleDateFormat详解的更多相关文章

  1. Java AtomicInteger类的使用方法详解_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 首先看两段代码,一段是Integer的,一段是AtomicInteger的,为以下: public class Samp ...

  2. Java常用类Date相关知识

    Date:类 Date 表示特定的瞬间,精确到毫秒. 在 JDK 1.1 之前,类 Date 有两个其他的函数.它允许把日期解释为年.月.日.小时.分钟和秒值.它也允许格式化和解析日期字符串. Dat ...

  3. 【Java常用类】Calendar

    Calendar日历类 实例化 方法一 创建其子类**(GregorianCalendar)**的对象 方法二 调用其静态方法getInstance() Calendar instance = Cal ...

  4. Java File 类的使用方法详解

    Java File类的功能非常强大,利用Java基本上可以对文件进行所有的操作.本文将对Java File文件操作类进行详细地分析,并将File类中的常用方法进行简单介绍,有需要的Java开发者可以看 ...

  5. Java File 类的使用方法详解(转)

    转自:http://www.codeceo.com/article/java-file-class.html Java File类的功能非常强大,利用Java基本上可以对文件进行所有的操作.本文将对J ...

  6. java常用类————Date类

    Date类在Java.util包中. 一.功能介绍:创建Date对象,获取时间,格式化输出的时间. 二.对象创建:1.使用Date类无参数的构造方法创建的对象可以获取本地时间.例如: Date now ...

  7. Java基础-DButils工具类(QueryRunner)详解

    Java基础-DButils工具类(QueryRunner)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC ...

  8. Java基础 —— Java常用类

    Java常用类: java.lang包: java.lang.Object类: hashcode()方法:返回一段整型的哈希码,代表地址. toString()方法:返回父类名+"@&quo ...

  9. Java常用类学习笔记总结

    Java常用类 java.lang.String类的使用 1.概述 String:字符串,使用一对""引起来表示. 1.String声明为final的,不可被继承 2.String ...

随机推荐

  1. apue学习笔记(第十五章 进程间通信)

    本章将说明进程之间相互通信的其它技术----进程间通信(IPC) 管道 管道只能在具有公共祖先的两个进程之间只用.通常,一个管道由一个进程创建,在进程调用fork后,这个管道就能在父进程和子进程之间使 ...

  2. 重读金典------高质量C编程指南(林锐)-------第三章 命名规则

      3.1  共性规则 规则:标识符应该直观且可以拼读,可进行英语翻译. 规则:标识符的长度需要控制好,不应该太长. 规则:命名规则应该同操作系统或者开发工具等保持一致,比如大小写混用.AddChar ...

  3. (转)Spring对注解(Annotation)处理源码分析1——扫描和读取Bean定义

    1.从Spring2.0以后的版本中,Spring也引入了基于注解(Annotation)方式的配置,注解(Annotation)是JDK1.5中引入的一个新特性,用于简化Bean的配置,某些场合可以 ...

  4. linux 源代码安装mysql5.5

    linux下源代码安装mysql过程例如以下: yum update yum upgrade yum install -y vim man wget yum install -y gcc gcc-c+ ...

  5. LeetCode 之 Valid Palindrome(字符串)

    [问题描写叙述] Given a string, determine if it is a palindrome, considering only alphanumeric characters a ...

  6. PHP实现上次登录功能

    通过一个sql语句把上次的登录时间给本次登录时间,再把当前时间记录下来 update userinfo  set lasttime=userinfo.logintime,logintime= CURR ...

  7. 使用HTML5制作简单的RPG游戏

    很久以前就想着做一个游戏,但什么都不会又不知道从哪里开始,胡乱找来一些书籍和资料结果太深奥看不懂,无奈只能放弃.这一弃就是十多年,倥偬半生,眼看垂垂老矣,还是没能有什么成果. 近年来游戏引擎越来越多, ...

  8. 卡特兰数-Catalan数

    卡特兰数的含义: 说到卡特兰数,就不得不提及卡特兰数序列.卡特兰数序列是一个整数序列.其通项公式是我们从中取出的就叫做第n个卡特兰数数,前几个卡特兰数数是:1, 1, 2, 5, 14, 42, 13 ...

  9. 深入理解Java 8 Stream

    Java 8中新增了Stream,主要是lambda表达式的应用,其链式调用简洁,用于高效表达集合操作. 先对Stream的使用做了解,参照blog. (1) 生成Stream的方式 主要有以下几种 ...

  10. HDFS源码分析之数据块及副本状态BlockUCState、ReplicaState

    关于数据块.副本的介绍,请参考文章<HDFS源码分析之数据块Block.副本Replica>. 一.数据块状态BlockUCState 数据块状态用枚举类BlockUCState来表示,代 ...