package nccloud.api.testcase.base;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
/**
* jdk1.8 java.time 包测试
* @author lenovo
*
*/
public class DateTimeTest {
/**
* Date-Time API 这是对java.util.Date强有力的补充,解决了 Date 类的大部分痛点: 非线程安全 时区处理麻烦
* 各种格式化、和时间计算繁琐 设计有缺陷,Date 类同时包含日期和时间;还有一个 java.sql.Date,容易混淆。
*
*
* java.time 主要类 java.util.Date 既包含日期又包含时间,而 java.time 把它们进行了分离
*
* @throws ParseException
*
*/
/**
* @param args
* @throws ParseException
*/
public static void main(String[] args) throws ParseException {
// 1、格式化:
// Java 8 之前:
// oldFormat();
// Java 8 之后
// newFormat();
// 2、 字符串转日期格式
// Java 8 之前:
// oldStrToDate();
// Java 8 之后
// newStrToDate();
// 3、日期计算
// 3.1 计算一周后日期 计算时间间隔
// Java 8 之前:
// oldAfterDate();
// Java 8 之后
// newAfterDate();
// 3.2 获取特定一个日期
// oldGetDay();
// newGetDay();
//4、时区
//时区:正式的时区划分为每隔经度 15° 划分一个时区,全球共 24 个时区,每个时区相差 1 小时。但为了行政上的方便,常将 1 个国家或 1 个省份划在一起,比如我国幅员宽广,大概横跨 5 个时区,实际上只用东八时区的标准时即北京时间为准。
//java.util.Date 对象实质上存的是 1970 年 1 月 1 日 0 点( GMT)至 Date 对象所表示时刻所经过的毫秒数。也就是说不管在哪个时区 new Date,它记录的毫秒数都一样,和时区无关。但在使用上应该把它转换成当地时间,这就涉及到了时间的国际化。
//java.util.Date 本身并不支持国际化,需要借助 TimeZone。
oldGetDayByTimeZone();
newGetDayByTimeZone();
//5、JDBC 和 java8
//现在 jdbc 时间类型和 java8 时间类型对应关系是
// Date ---> LocalDate
// Time ---> LocalTime
// Timestamp ---> LocalDateTime
//
// 而之前统统对应 Date,也只有 Date
}
/**
* 1.8之前格式化
*/
public static void oldFormat() {
System.out.println("----------oldFormat---begin---------");
Date now = new Date();
System.out.println(now);// Thu Feb 23 17:28:24 CST 2023
// format yyyy-MM-dd
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(now);
System.out.println(String.format("date format : %s", date));
// format HH:mm:ss
SimpleDateFormat sdft = new SimpleDateFormat("HH:mm:ss");
String time = sdft.format(now);
System.out.println(String.format("time format : %s", time));
// format yyyy-MM-dd HH:mm:ss
SimpleDateFormat sdfdt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String datetime = sdfdt.format(now);
System.out.println(String.format("dateTime format : %s", datetime));
}
/**
* 1.8之后格式化
*/
public static void newFormat() {
System.out.println("----------newFormat---begin---------");
// format yyyy-MM-dd
LocalDate date = LocalDate.now();// 日期 format: yyyy-MM-dd
System.out.println(String.format("date format : %s", date));
// format HH:mm:ss
LocalTime time = LocalTime.now().withNano(0);// 时间 format: HH:mm:ss
System.out.println(String.format("time format : %s", time));
// format yyyy-MM-dd HH:mm:ss
LocalDateTime dateTime = LocalDateTime.now(); 日期+时间 format: yyyy-MM-ddTHH:mm:ss.SSS
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateTimeStr = dateTime.format(dateTimeFormatter);
System.out.println(String.format("dateTime format : %s", dateTimeStr));
}
/**
* 1.8之前字符串转日期格式
*/
public static void oldStrToDate() throws ParseException {
System.out.println("----------oldStrToDate---begin---------");
// Java 8 之前 转换都需要借助 SimpleDateFormat 类,而Java 8 之后只需要
// LocalDate、LocalTime、LocalDateTime的 of 或 parse 方法。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2021-01-26 12:12:12");
System.out.println(String.format("oldStrToDate : %s", date));
}
/**
* 1.8之后字符串转日期格式
*/
public static void newStrToDate() {
System.out.println("----------newStrToDate---begin---------");
LocalDate dateof = LocalDate.of(2021, 1, 26);
LocalDate parse = LocalDate.parse("2021-01-26");
System.out.println(String.format("newStrToDate dateof : %s", dateof));
System.out.println(String.format("newStrToDate parse : %s", parse));
LocalTime timeof = LocalTime.of(12, 12, 22);
LocalTime parse2 = LocalTime.parse("12:12:22");
System.out.println(String.format("newStrToDate timeof : %s", timeof));
System.out.println(String.format("newStrToDate parse : %s", parse2));
LocalDateTime dateTimeof = LocalDateTime.of(2021, 1, 26, 12, 12, 22);
System.out.println(String.format("newStrToDate dateTimeof : %s", dateTimeof));
// LocalDateTime parse2 = LocalDateTime.parse("2021-01-26 12:12:12");//报错 识别不了空格
LocalDateTime parse3 = LocalDateTime.parse("2021-01-26T12:12:12");
System.out.println(String.format("newStrToDate parse : %s", parse3));
LocalDateTime parse4 = LocalDateTime.parse("2021-01-26 12:12:12", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(String.format("newStrToDate parse : %s", parse4));
}
/**
* 1.8之前 获取一周后时间 计算时间间隔
*
* @throws ParseException
*/
public static void oldAfterDate() throws ParseException {
System.out.println("----------oldAfterDate---begin---------");
// 一周后的日期
SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd");
Calendar ca = Calendar.getInstance();
ca.add(Calendar.DATE, 7);
Date d = ca.getTime();
String after = formatDate.format(d);
System.out.println("一周后日期:" + after);
// 算两个日期间隔多少天,计算间隔多少年,多少月方法类似
String dates1 = "2021-12-23";
String dates2 = "2021-02-26";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = format.parse(dates1);
Date date2 = format.parse(dates2);
int day = (int) ((date1.getTime() - date2.getTime()) / (1000 * 3600 * 24));
System.out.println(dates2 + "和" + dates1 + "相差" + day + "天");// 结果:2021-02-26和2021-12-23相差300天
}
/**
* 1.8之后 获取一周后时间 计算时间间隔
*
* @throws ParseException
*/
public static void newAfterDate() throws ParseException {
System.out.println("----------newAfterDate---begin---------");
// 一周后的日期
LocalDate localDate = LocalDate.now();
// 方法1
LocalDate after = localDate.plus(1, ChronoUnit.WEEKS);
System.out.println("一周后日期:" + after);
// 方法2
LocalDate after2 = localDate.plusWeeks(1);
System.out.println("一周后日期:" + after2);
// 算两个日期间隔多少天,计算间隔多少年,多少月
LocalDate date1 = LocalDate.parse("2021-02-26");
LocalDate date2 = LocalDate.parse("2021-12-23");
Period period = Period.between(date1, date2);
System.out.println("date1 到 date2 相隔:" + period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "天");// 打印结果是 “date1 到 date2 相隔:0年9月27天”
// 这里period.getDays()得到的天是抛去年月以外的天数,并不是总天数
// 如果要获取纯粹的总天数应该用下面的方法
long day = date2.toEpochDay() - date1.toEpochDay();
System.out.println(date1 + "和" + date2 + "相差" + day + "天");// 打印结果:2021-02-26和2021-12-23相差300天
}
/**
* 1.8之前 获取特定日期
*
*/
public static void oldGetDay() {
System.out.println("----------oldGetDay---begin---------");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//获取当前月第一天:
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, 1);
String first = format.format(c.getTime());
System.out.println("first day:" + first);
//获取当前月最后一天
Calendar ca = Calendar.getInstance();
ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
String last = format.format(ca.getTime());
System.out.println("last day:" + last);
//当年最后一天
Calendar currCal = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, currCal.get(Calendar.YEAR));
calendar.roll(Calendar.DAY_OF_YEAR, -1);
Date time = calendar.getTime();
System.out.println("last day:" + format.format(time));
}
/**
* 1.8之后 获取特定日期
*
*/
public static void newGetDay() {
System.out.println("----------newGetDay---begin---------");
LocalDate today = LocalDate.now();
//获取当前月第一天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("first day:" + firstDayOfThisMonth);
// 取本月最后一天
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("last day:" + lastDayOfThisMonth);
//取下一天:
LocalDate nextDay = lastDayOfThisMonth.plusDays(1);
System.out.println("next day:" + nextDay);
//当年最后一天
LocalDate lastday = today.with(TemporalAdjusters.lastDayOfYear());
System.out.println("last day:" + lastday);
//2021年最后一个周日,如果用Calendar是不得烦死。
LocalDate lastMondayOf2021 = LocalDate.parse("2022-12-31").with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
System.out.println("last sunday:" + lastMondayOf2021);
}
/**
* 1.8之前
*
*/
public static void oldGetDayByTimeZone() {
System.out.println("----------oldGetDayByTimeZone---begin---------");
//北京时间:Wed Jan 27 14:05:29 CST 2021
Date date = new Date();
System.out.println(date);
//北京时区
SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
System.out.println("毫秒数:" + date.getTime() + ", 北京时间:" + bjSdf.format(date));
//东京时区
SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo")); // 设置东京时区
System.out.println("毫秒数:" + date.getTime() + ", 东京时间:" + tokyoSdf.format(date));
}
/**
* 1.8之后
*
*/
public static void newGetDayByTimeZone() {
System.out.println("----------newGetDayByTimeZone---begin---------");
//当前时区时间
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println("当前时区时间: " + zonedDateTime);
//东京时间
ZoneId zoneId = ZoneId.of(ZoneId.SHORT_IDS.get("JST"));
ZonedDateTime tokyoTime = zonedDateTime.withZoneSameInstant(zoneId);
System.out.println("东京时间: " + tokyoTime);
//互转
// ZonedDateTime 转 LocalDateTime
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
System.out.println("时区时间转当地时间: " + localDateTime);
//LocalDateTime 转 ZonedDateTime
ZonedDateTime localZoned = localDateTime.atZone(ZoneId.systemDefault());
System.out.println("当地时间转时区时间: " + localZoned);
}
}