Java日期时间

x33g5p2x  于2021-09-28 转载在 Java  
字(12.0k)|赞(0)|评价(0)|浏览(501)

Java日期时间

Date 构造

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

第一个构造函数使用当前日期和时间来初始化对象。

Date( )

第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。

Date(long millisec)

Date对象 内的方法

Date对象创建以后,可以调用下面的方法。

序号方法和描述
1boolean after(Date date) 若当调用此方法的Date对象在指定日期之返回true,否则返回false。
2boolean before(Date date) 若当调用此方法的Date对象在指定日期之返回true,否则返回false。
3Object clone( ) 返回此对象的副本。
4int compareTo(Date date) 比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。
5int compareTo(Object obj) 若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。
6boolean equals(Object date) 当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。
7long getTime( ) 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
8int hashCode( ) 返回此对象的哈希码值。
9void setTime(long time) 用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。
10String toString( ) 把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。

获取当前日期时间

Java中获取当前日期和时间很简单,使用 Date 对象的 toString() 方法来打印当前日期和时间,如下所示:

// 初始化 Date 对象
       Date date = new Date();
        
       // 使用 toString() 函数显示日期时间
       System.out.println(date.toString());

结果:Sat Jun 06 18:04:39 CST 2020 (这个是英文的时间)

将Date格式化为时间字符串

Date dNow = new Date( );
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");

        System.out.println("当前时间为: " + ft.format(dNow));

结果 : 当前时间为: 2020-06-06 06:15:51

Date dNow = new Date( );
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy年MM月dd日 hh时mm分ss秒");
        System.out.println("当前时间为: " + ft.format(dNow));

结果: 当前时间为: 2020年06月06日 06时16分56秒

Date dNow = new Date( );
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy年MM月dd日");
        System.out.println("当前时间为: " + ft.format(dNow));

结果 : 当前时间为: 2020年06月06日

Date dNow = new Date( );
        SimpleDateFormat ft = new SimpleDateFormat ("hh时mm分ss秒");
        System.out.println("当前时间为: " + ft.format(dNow));

结果: 当前时间为: 06时18分11秒

还可这样玩 使用字符串格式化format

Date dNow = new Date( );
        String date=String.format("%tF",dNow );
        System.out.println("年-月-日格式:"+date);

        String date3=String.format("%tT",dNow);
        System.out.println("HH:MM:SS格式(24时制):"+date3);

        String date4=String.format("%tF %tT",dNow,dNow);
        System.out.println("年-月-日格式 HH:MM:SS格式:"+date4);
       String da=String.format("%tA",data);
        System.out.println(da) ; //获取星期几

年-月-日格式:2020-06-06
HH:MM:SS格式(24时制):18:29:51
年-月-日格式 HH:MM:SS格式:2020-06-06 18:29:51

星期六

将时间字符串转换为Date

SimpleDateFormat  df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        df.setLenient(false);//false严格处理 是否符合 现实中的日期格式 比如 这个月没有31号 但是不开启的情况下 不会报错的
        Date time= null;// 如果格式不对 就会报错
        try {
            time = df.parse("2020-6-6 18:40:5");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println(time);

Sat Jun 06 18:40:05 CST 2020

日期比较

比较有很多种 使用一种就行了 以下是将中文时间 转换为Date对象然后使用此对象中的after 方法 进行比较的

SimpleDateFormat  df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        df.setLenient(false);//false严格处理 是否符合 现实中的日期格式 比如 这个月没有31号 但是不开启的情况下 不会报错的
        Date time= null;// 如果格式不对 就会报错
            try {
                time = df.parse("2020-6-6 18:40:5");
            } catch (ParseException e) {
                e.printStackTrace();
                return;
            }
            Date data=new Date(); //获取本地时间
             boolean  pd=data.after(time); //将本地时间 和 其他的时间进行比较
            if (pd){
                System.out.println("本地时间 大 ");
            }else{
                System.out.println("本地时间 小 ");
            }

本地时间 大

获取间隔的天数 小时 分钟

public static void main(String[] args) {
        String dateStr1 = "2019-01-19 6:6:5";
        String dateStr2 = "2019-01-19 6:5:5";
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date1 = null;
        Date date2 = null;
        try {
            date1 = format.parse(dateStr1);
            date2 = format.parse(dateStr2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println( getDatePoor(date1,date2));
    }

    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

0天0小时1分钟

Java 休眠(sleep)

将当前线程暂停指定时间

public static void main(String[] args) {
        try {
            System.out.println(new Date( ) + "\n");
            Thread.sleep(1000*3);   // 休眠3秒
            System.out.println(new Date( ) + "\n");
        } catch (Exception e) {
            e.getStackTrace();
        }
    }

Sat Jun 06 19:18:10 CST 2020

Sat Jun 06 19:18:13 CST 2020

注意看 间隔了 三秒 才继续执行的

测量代码执行时间

一般用于io流 等 一些较大的 工程 来测试他们的 执行时间 然后进行调优

public static void main(String[] args) {
        try {
            long start = System.currentTimeMillis( );  //这段代码开始时间
            
            Thread.sleep(2000);
            
            long end = System.currentTimeMillis( ); //这段代码结束时间
            long diff = end - start;  //计算 开始和结束 一共 话费多少时间
            System.out.println("代码运行了: : " + diff/1000+"秒");
        } catch (Exception e) {
           e.getStackTrace();
        }
    }

代码运行了: 2秒

计时器

int time=60;  //定义60秒计时器
			for(int i=1;i<=60;i++) {
				System.out.println("秒"+i);
				try {
					//每次间隔一秒后执行 下一次循环
					Thread.sleep(1000);  //每1000毫秒=一秒
				} catch (InterruptedException e) {		
					e.printStackTrace();
				}
			
		    }

Calendar类 获取操作日期

属性介绍
Calendar.YEAR年 默认1
Calendar.MONTH月 默认2
Calendar.DATE日 默认5
Calendar.DAY_OF_MONTH日期,和上面的字段意义完全相同
Calendar.HOUR12小时制的小时
Calendar.HOUR_OF_DAY24小时制的小时 默认11
Calendar.MINUTE分钟 默认 12
Calendar.SECOND秒 默认 13
Calendar.DAY_OF_WEEK星期几 默认 7

get 获取时间

什么都不操作获取的是 本地的时间

Calendar c1 = Calendar.getInstance();
        System.out.println("年"+c1.get(Calendar.YEAR));
        //国外的月份是从0到11 国内是从1到12 所以需要加1
        System.out.println("月"+(c1.get(Calendar.MONTH)+1));
        System.out.println("日"+c1.get(Calendar.DATE));
            System.out.println("时"+c1.get(Calendar.HOUR_OF_DAY));
        System.out.println("分"+c1.get(Calendar.MINUTE));
        System.out.println("秒"+c1.get(Calendar.SECOND));
         //国外的星期1是国内的星期日
        String []arr = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
        //1.数组下标从0开始;2.老外的第一天是从星期日开始的
        System.out.println("今天是:"+arr[c1.get(Calendar.DAY_OF_WEEK)-1]);

这个是我写这篇文章当前的时间:

年2020
月6
日6
时20
分43
秒38
今天是:星期六

Set设置时间

统一设置

Calendar c1 = Calendar.getInstance();
//把Calendar对象c1的年 月 日 时分秒 设为:2009-6-6 1:3:1   当然也可以只设置年月日     2009-6-12     有重载方法
c1.set(2020, 6,6,1,3,1);

还可以单独设置

Calendar c1 = Calendar.getInstance();
        c1.set(Calendar.DATE,20);

如果使用set方法 后那么 月 分 就不需要+1 获取日期的方法也需要改变

Calendar c1 = Calendar.getInstance();
        String []arr1 = {"星期六","星期日","星期一","星期二","星期三","星期四","星期五"};
        int num=c1.get(Calendar.DAY_OF_WEEK);
        System.out.println(num);
        if (num>=7){
            num=0;
        }
        System.out.println("今天是:"+arr1[ num]);

如果有问题可以自己 跳转 数组内的顺序

Add设置 增加/减少时间

Calendar c1 = Calendar.getInstance();
        c1.add(Calendar.DATE, 10);  //加10天
        c1.add(Calendar.DATE, -10); //减10天
//..............其他的时间加减 就没必要写了 参照就行了

线程安全处理时间的办法

JDK8新特性里提供了3个时间类:LocalDate、LocalTime、LocalDateTime

在项目开发中,已经需要对Date类型进行格式,否则可读性很差,格式化Date类型要使用SimpleDateFormat,但SimpleDateFormat是现成不安全的。

为什么需要LocalDate、LocalTime、LocalDateTime

Date如果不格式化,打印出的日期可读性差

使用SimpleDateFormat对时间进行格式化,但SimpleDateFormat是线程不安全的。

calendar是共享变量,并且这个共享变量没有做线程安全控制。当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat】调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值 另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。

LocalDate是日期处理类

// 获取当前日期
LocalDate now = LocalDate.now();
// 设置日期
LocalDate localDate = LocalDate.of(2019, 9, 10);
// 获取年
int year = localDate.getYear();     //结果:2019
int year1 = localDate.get(ChronoField.YEAR); //结果:2019
// 获取月
Month month = localDate.getMonth();   // 结果:SEPTEMBER
int month1 = localDate.get(ChronoField.MONTH_OF_YEAR); //结果:9
// 获取日
int day = localDate.getDayOfMonth();   //结果:10
int day1 = localDate.get(ChronoField.DAY_OF_MONTH); // 结果:10
// 获取星期
DayOfWeek dayOfWeek = localDate.getDayOfWeek();   //结果:TUESDAY
int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK); //结果:2

LocalTime是时间处理类

// 获取当前时间
LocalTime now = LocalTime.now();
// 设置时间
LocalTime localTime = LocalTime.of(13, 51, 10);
//获取小时
int hour = localTime.getHour();    // 结果:13
int hour1 = localTime.get(ChronoField.HOUR_OF_DAY); // 结果:13
//获取分
int minute = localTime.getMinute();  // 结果:51
int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR); // 结果:51
//获取秒
int second = localTime.getSecond();   // 结果:10
int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE); // 结果:10

LocalDateTime可以设置年月日时分秒,相当于LocalDate + LocalTime

// 获取当前日期时间
LocalDateTime localDateTime = LocalDateTime.now();
// 设置日期
LocalDateTime localDateTime1 = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
LocalDateTime localDateTime3 = localDate.atTime(localTime);
LocalDateTime localDateTime4 = localTime.atDate(localDate);
// 获取LocalDate
LocalDate localDate2 = localDateTime.toLocalDate();
// 获取LocalTime
LocalTime localTime2 = localDateTime.toLocalTime();

Instant

// 创建Instant对象
Instant instant = Instant.now();
// 获取秒
long currentSecond = instant.getEpochSecond();
// 获取毫秒
long currentMilli = instant.toEpochMilli();

如果只是为了获取秒数或者毫秒数,使用System.currentTimeMillis()来得更为方便

修改LocalDate、LocalTime、LocalDateTime、Instant

LocalDate、LocalTime、LocalDateTime、Instant为不可变对象,修改这些对象对象会返回一个副本。增加、减少年数、月数、天数等 以LocalDateTime为例。

// 创建日期:2019-09-10 14:46:56
LocalDateTime localDateTime = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
//增加一年
localDateTime = localDateTime.plusYears(1);  //结果: 2020-09-10 14:46:56
localDateTime = localDateTime.plus(1, ChronoUnit.YEARS); //结果: 2021-09-10 14:46:56
//减少一个月
localDateTime = localDateTime.minusMonths(1);  //结果: 2021-08-10 14:46:56
localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS); //结果: 2021-07-10 14:46:56

通过with修改某些值,年月日时分秒都可以通过with方法设置。

//修改年为2019
localDateTime = localDateTime.withYear(2020);
//修改为2022
localDateTime = localDateTime.with(ChronoField.YEAR, 2022);

/*/日期计算。//*比如有些时候想知道这个月的最后一天是几号、下个周末是几号,通过提供的时间和日期API可以很快得到答案 。TemporalAdjusters提供的各种日期时间格式化的静态类,比如firstDayOfYear是当前日期所属年的第一天

LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.with(TemporalAdjusters.firstDayOfYear());

/*/格式化时间。//*DateTimeFormatter默认提供了多种格式化方式,如果默认提供的不能满足要求,可以通过DateTimeFormatter的ofPattern方法创建自定义格式化方式

LocalDate localDate = LocalDate.of(2019, 9, 10);
String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
//自定义格式化
DateTimeFormatter dateTimeFormatter =   DateTimeFormatter.ofPattern("dd/MM/yyyy");
String s3 = localDate.format(dateTimeFormatter);

/*/解析时间。//*和SimpleDateFormat相比,DateTimeFormatter是线程安全的

LocalDate localDate1 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate2 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE);

Date与LocalDateTime转换。

/** * LocalDateTime转毫秒时间戳 * @param localDateTime LocalDateTime * @return 时间戳 */
public static Long localDateTimeToTimestamp(LocalDateTime localDateTime) {
    try {
        ZoneId zoneId = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zoneId).toInstant();
        return instant.toEpochMilli();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/** * 时间戳转LocalDateTime * @param timestamp 时间戳 * @return LocalDateTime */
public static LocalDateTime timestampToLocalDateTime(long timestamp) {
    try {
        Instant instant = Instant.ofEpochMilli(timestamp);
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/** * Date转LocalDateTime * @param date Date * @return LocalDateTime */
public static LocalDateTime dateToLocalDateTime(Date date) {
    try {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDateTime();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/** * LocalDateTime转Date * @param localDateTime LocalDateTime * @return Date */
public static Date localDateTimeToDate(LocalDateTime localDateTime) {
    try {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

SpringBoot中应用LocalDateTime

将LocalDateTime字段以时间戳的方式返回给前端 添加日期转化类

public class LocalDateTimeConverter extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeNumber(value.toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
    }

并在LocalDateTime字段上添加@JsonSerialize(using = LocalDateTimeConverter.class)注解,如下:

@JsonSerialize(using = LocalDateTimeConverter.class)
protected LocalDateTime gmtModified;

将LocalDateTime字段以指定格式化日期的方式返回给前端 在LocalDateTime字段上添加@JsonFormat(shape=JsonFormat.Shape.STRING, pattern=“yyyy-MM-dd HH:mm:ss”)注解即可,如下:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
protected LocalDateTime gmtModified;

对前端传入的日期进行格式化 在LocalDateTime字段上添加@DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)注解即可,如下:

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
protected LocalDateTime gmtModified;

总结:

LocalDateTime:Date有的我都有,Date没有的我也有,

相关文章