7-Date+Calendar+LocalDate

Date

        Date可以表示一个特定的瞬间,精确到毫秒

        DateFormat,SimpleDateFormat 类:时间格式化类

  • Date:
import java.util.Date;
public class Demo {
	public static void main(String[] args) {
		//创建时间对象
        Date date = new Date();
        //date对象获取是当前的时间Wed Apr 03 23:18:01 CST 2019
        System.out.println(date);

        //返回以毫秒为单位的当前时间(当前时间 - 1970.1.1 午夜)
        long now = System.currentTimeMillis();
        System.out.println(now);
        //转换为当前时间
        Date date2 = new Date(now);
        System.out.println(date2);

        //获取从1970年1月1日到当前日期的总时间(毫秒),同now
        System.out.println(date2.getTime());

        System.out.println("中国风格的时间:"+date2.toLocaleString());
	}
}

        运行结果:

        通常很多人都习惯使用new Date()来获取当前时间,new Date()所做的事情其实就是调用了System.currentTimeMillis()

        如果仅仅是需要或者毫秒数,那么完全可以使用System.currentTimeMillis()去代替new Date(),效率上会高一点

    //Date源码:
    public Date() {
        this(System.currentTimeMillis());
    }

格式化(format):Date类型对象 ---> String类型 String format(Date date)
解析(parse):String类型时间 --> Date类型类 Date parse(String source)

        DateFormat转换的格式是固定的(以与语言无关的方式格式化并解析日期或时间),DataFormat是无法完成根据需求定制时间的

        SimpleDateFormat:可以自定义时间规则,是DataFormat的子类 


DateFormat

        时间格式化:

import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
public class Demo {
	public static void main(String[] args) throws ParseException {
		Date d = new Date();
        System.out.println(d);//当前时间
        
        //格式化: Date类型转换为String字符串
        // SHORT风格(短)
        DateFormat df = DateFormat.getInstance();
        String time = df.format(d);
        System.out.println(time);
        //LONG风格
        df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
        System.out.println(df.format(d));

        //解析:String类型的时间 --> date对象
        df = DateFormat.getInstance();
        time = df.format(d);
        Date d2 = df.parse(time);//从给定字符串的开始解析文本,以生成一个日期
        System.out.println(d2);
	}
}

        运行结果:


SimpleDateFormat

        自定义时间格式化:以与语言环境有关的方式来格式化和解析日期的具体类,它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo {
	public static void main(String[] args) throws ParseException {
		String pattern = "yyyy-MM-dd HH:mm:ss";//给定一个时间格式
        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.applyPattern(pattern);//确定使用格式
        //等价于SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //格式化
        String time = sdf.format(new Date());
        System.out.println(time);
        //解析 使用了什么风格格式化,就必须使用相同风格解析(使用同一个对象操作即可)
        Date date = sdf.parse(time);
        System.out.println(date);
	}
}

        运行结果:


Calendar

        Calendar是一个日历类用来代替Date使用的

        Calendar类是一个抽象类,为一个特定的瞬间,为一套 calendar fields 如 YEAR, MONTH, DAY_OF_MONTH, HOUR之间的转换提供了方法

        获取日历类对象 getInstance();获取的是默认时区对应的语言环境的一个日历对象

import java.text.ParseException;
import java.util.Calendar;
public class Demo {
	public static void main(String[] args) throws ParseException {
		// 获取当前时间
        Calendar calendar = Calendar.getInstance();
//        System.out.println(calendar);//不能直接打印
        //java.util.GregorianCalendar[time=1553054809390,areFieldsSet=true,areAllFieldsSet=true,
        //lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,
        //dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,
        //minimDAY_alDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=2,WEEK_OF_YEAR=12,
        //WEEK_OF_MONTH=4,DAY_OF_MONTH=20,DAY_OF_YEAR=79,DAY_OF_WEEK=4,
        //DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=6,
        //SECOND=49,MILLISECOND=390,ZONE_OFFSET=28800000,DST_OFFSET=0]

        System.out.println("当前系统时间:");
        //获取年
        int year = calendar.get(Calendar.YEAR);
        //月
        int month = calendar.get(Calendar.MONTH);//此处的月需要+1
        //日期
        int day = calendar.get(Calendar.DATE);
        //小时 二十四小时
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        //分钟
        int minute = calendar.get(Calendar.MINUTE);
        //秒
        int second = calendar.get(Calendar.SECOND);
        String time = year + "年" + (month + 1) + "月" + day + "日" + " " + hour + "小时" + minute + "分钟" + second + "秒";
        System.out.println(time);
	}
}

        运行结果:

import java.util.Calendar;
public class Demo1 {
	public static void main(String[] args) {
		//获取2019年3月20日 是这一年的第几天, 第几周, 一个月中第几天
        Calendar c = Calendar.getInstance();
        /*
         * c.set(c.YEAR, 2019);设置时间使用set
         * 第一个是定义的属性,第二个是时间
         */
        //month 是从0开始到11结束 当前月份-1 才能获取对应的月份
        c.set(2019, 2, 20);
        int dayInYear = c.get(Calendar.DAY_OF_YEAR);//天数
        int weekInYear = c.get(Calendar.WEEK_OF_YEAR);//周数
        int dayInMonth = c.get(Calendar.DAY_OF_MONTH);//月中的天数
        String time = "这一年的第" + dayInYear + "天,第" + weekInYear + "周,这一月的第" + dayInMonth + "天";
        System.out.println(time);
	}
}

        运行结果:


LocalDate/LocalDateTime

        Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理

        在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:

        1、非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一
        2、设计很差 − Java 的日期/时间类的定义并不一致,在 java.util 和 java.sql 的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date 同时包含日期和时间,而java.sql.Date 仅包含日期,将其纳入 java.sql 包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计
        时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此 Java 引入了 java.util.Calendar和 java.util.TimeZone 类,但他们同样存在上述所有的问题

        Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:

        1、Local(本地) − 简化了日期时间的处理,没有时区的问题

        2、ZoneId (时区) − 通过定制的时区处理日期时间

  • 线程安全问题演示:
    public static void main(String[] args) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		Callable<Date> task = new Callable<Date>() {
			@Override
			public Date call() throws Exception {
				return sdf.parse(sdf.format(new Date()));
			}
		};
		//线程池
		ExecutorService pool = Executors.newFixedThreadPool(10);
		List<Future<Date>> results = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			Future<Date> submit = pool.submit(task);
			results.add(submit);
		}
		for (Future<Date> future : results) {
			try {
				System.out.println(future.get().toLocaleString());
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			} 
		}
		pool.shutdown();
	}

        运行结果(此演示基于Date的可变性):

        加锁后:

@Override
public Date call() throws Exception {
	synchronized (this) {
		return sdf.parse(sdf.format(new Date()));
	}
}

        运行结果:

  • LocalDate:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo1 {
	public static void main(String[] args) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		Callable<LocalDate> task = new Callable<LocalDate>() {
			@Override
			public LocalDate call() throws Exception {
				return LocalDate.parse("2019-04-07", formatter);
			}
		};
		//线程池
		ExecutorService pool = Executors.newFixedThreadPool(10);
		List<Future<LocalDate>> results = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			Future<LocalDate> submit = pool.submit(task);
			results.add(submit);
		}
		for (Future<LocalDate> future : results) {
			try {
				System.out.println(future.get());
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			} 
		}
		pool.shutdown();
	}
}

        运行结果:(不用加锁就线程安全)


LocalDateTime 

        LocalDate/LocalTime 和 LocalDateTime 类可以处理时区不是必须的情况

        LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息

        LocalDateTime 既包含日期,又包含时间,而且与1970无关

import java.time.LocalDateTime;
public class Demo1 {
	public static void main(String[] args) {
		//当前时间
		LocalDateTime ldt=LocalDateTime.now();
		System.out.println("当前时间"+ldt);
		//其他时间
		LocalDateTime ldt2=LocalDateTime.of(2012, 10, 1, 10, 10, 10);
		System.out.println("其他时间:"+ldt2);
		//加时间
		LocalDateTime ldt3=ldt2.plusDays(2);
		System.out.println("加时间:"+ldt3);
		//减时间
		LocalDateTime ldt4 = ldt3.minusHours(2);
		System.out.println("减时间:"+ldt4);
		//获取时间部分
		System.out.println(ldt.getYear());
		System.out.println(ldt.getMonthValue());
		System.out.println(ldt.getDayOfMonth());
		System.out.println(ldt.getHour());
		System.out.println(ldt.getMinute());
		System.out.println(ldt.getSecond());
	}
}

        运行结果:


Instant 和 ZoneId

        Instant 时间戳:它是以Unix元年(传统 的设定为UTC时区1970年1月1日午夜时分)开始 所经历的描述进行运算

        ZoneId 时区

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Set;
public class Demo3 {
	public static void main(String[] args) {
		//Instant
		System.out.println("----------------Instant--------------");
		Instant insNow = Instant.now();
		System.out.println("现在的时间:"+insNow.toString());
		//from the epochof 1970-01-01T00:00:00Z
		System.out.println("现在的时间距-过去多少秒:"+insNow.toEpochMilli());
		
		//Instant相当于之前的Date,也是毫秒数
		Instant instant = Instant.ofEpochMilli(1554629143473L);
		System.out.println("秒转时间:"+instant);
		
		//Duration:计算时间差
		long diff = Duration.between(instant, insNow).toMillis();
		System.out.println("时间差:"+diff);
		
		//Instant <-->  Date
		Date date = new Date();
		//Instant转Date
		Instant instant2 = date.toInstant();
		//Date转Instant
		Date dateFIns = (Date) Date.from(instant2);
		System.out.println(instant2+"\tInstant <-> Date\t"+dateFIns);
		
		//时区
		System.out.println("----------------ZoneId--------------");
		Set<String> strings = ZoneId.getAvailableZoneIds();
//		strings.forEach(System.out::println);
		ZoneId systemDefault = ZoneId.systemDefault();
		System.out.println("----------------systemDefault--------------");
		System.out.println(systemDefault);
		
		ZoneId tokyo = ZoneId.of("Asia/Tokyo");
		System.out.println(tokyo.getId());
		
		//LocalDateTime  <-->  Instant
		System.out.println("----------------LocalDateTime--------------");
		LocalDateTime localDateTime = LocalDateTime.now();
		LocalDateTime ldt = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
		System.out.println("LocalDateTime:"+ldt.toString());
		Instant insFLdt = ldt.atZone(ZoneId.systemDefault()).toInstant();
		System.out.println("Instant:"+insFLdt);
	}
}

        运行结果:


TemporalAdjuster

        TemporalAdjuster : 时间校正器。有时可能需要获取如将日期调整到“下个周日”等操作

        TemporalAdjusters : 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
public class Demo4 {
	public static void main(String[] args) {
		LocalDate date = LocalDate.now();
		System.out.println(date);
		//下个周五
		System.out.println(
				date.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)));
		//下个周二
		System.out.println(
				date.with(TemporalAdjusters.next(DayOfWeek.TUESDAY)));
		//下个周日
		System.out.println(
				date.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));
	}
}

        运行结果:


DateTimeFormatter

        java.time.format.DateTimeFormatter 类:

        该类提供了三种格式化方法: 预定义的标准格式,语言环境相关的格式,自定义的格式

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Demo5 {
	public static void main(String[] args) {
//		DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE;
//		DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
//		System.out.println(dtf.getLocale());
		DateTimeFormatter dateTimeFormatter = 
                                DateTimeFormatter.ofPattern("yyyy年MM月dd日\tHH:mm:ss\tE");
		LocalDateTime ldt = LocalDateTime.now();
		//时间 --> 字符串
		String stringDate = ldt.format(dateTimeFormatter);
		System.out.println(stringDate);
		//字符串 --> 时间
		LocalDateTime newLdt = ldt.parse(stringDate, dateTimeFormatter);
		System.out.println(newLdt);
	}
}

        运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值