Java 学习笔记 - 时间日期常用案列

  • 获取当前时间
  • 创建一个指定时间
  • Date
  • Calendar
  • LocalDateTime
  • ZonedDateTime
  • OffsetDateTime
  • 转换
  • Instant
  • ZonedDateTime
  • LocalDateTime
  • OffsetDateTime
  • Date
  • 时间戳(毫秒数)
  • 格式化
  • 以前:DateFormat
  • Java8: DateTimeFormatter
  • 0. 自带的格式
  • 1. 自定义格式
  • 2. 自定义格式(支持默认值)
  • 3. 其它
  • 时间计算
  • 加减时间
  • 计算间隔
  • 时区
  • 添加时区信息
  • 时区间转换
  • ZoneOffset
  • ZoneId
  • 工具类 hutool
  • 参考资料


获取当前时间

以前

Date date = new Date();
Date date = new Date(System.currentTimeMillis());

Java8

LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
Instant now = Instant.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();

带时区的日期时间

ZonedDateTime zonedDateTimeDefault = ZonedDateTime.ofInstant(now, ZoneId.systemDefault());// 系统默认时区
ZonedDateTime zonedDateTimeE8 = ZonedDateTime.now().withZoneSameInstant(ZoneId.of("Asia/Shanghai")); // 指定东8区

创建一个指定时间

Date

Date 创建指定日期的方式已经 @Deprecated,仅供参观

Date date = new Date(2022-1900, 0, 5, 12, 30, 59);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
System.out.println(dateFormat.format(date)); // 2022-01-05 12:30:59:000

Calendar

Calendar 还有一大堆常量用于指定时间单位:年、月、日、时、分、秒、毫秒 等。。

Calendar instance = Calendar.getInstance();
// 月从 0 开始
instance.set(2022, 6, 5, 12, 30, 59);
// 补充一下毫秒
instance.set(Calendar.MILLISECOND, 369);
// 取得 日期对象
Date time = instance.getTime(); 
// 定义格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
// 输出格式化的日期字符串
System.out.println(sdf.format(time)); // 2022-07-05 12:30:59:369

LocalDateTime

LocalDateTime dateTime = LocalDateTime.of(2022, 6, 5, 12, 30, 59, 999999999);
String format = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(format);// 2022-06-05T12:30:59.999999999

ZonedDateTime

ZonedDateTime dateTime = ZonedDateTime.of(2022, 6, 5, 12, 30, 59, 999999999, ZoneId.of("Asia/Shanghai"));
String format = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(format); // 2022-06-05T12:30:59.999999999

ZonedDateTime.of 内部是封装了 LocalDateTime.of

public static ZonedDateTime of(
	int year, int month, int dayOfMonth,
	int hour, int minute, int second, int nanoOfSecond, ZoneId zone) {
	LocalDateTime dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
    return ofLocal(dt, zone, null);
}

OffsetDateTime

OffsetDateTime dateTime = OffsetDateTime.of(2022, 6, 5, 12, 30, 59, 999999999, ZoneOffset.of("+8"));
String format = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(format); // 2022-06-05T12:30:59.999999999

OffsetDateTime.of 内部是封装了 LocalDateTime.of

public static OffsetDateTime of(
	int year, int month, int dayOfMonth,
	int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset) {
    LocalDateTime dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
    return new OffsetDateTime(dt, offset);
}

转换

Instant

直接: LocalDateTime, ZonedDateTime, Date, Timestamp

Instant instant = Instant.now();

LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai"));
ZonedDateTime zonedDateTime1 = instant.atZone(ZoneId.systemDefault());
ZonedDateTime zonedDateTime2 = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
Date date = Date.from(instant);
Timestamp timestamp = Timestamp.from(instant);

ZonedDateTime

直接:LocalDate, LocalTime, LocalDateTime, Instant 间接:Date

ZonedDateTime zonedDateTime = ZonedDateTime.now();

LocalDate localDate = zonedDateTime.toLocalDate();
LocalTime localTime = zonedDateTime.toLocalTime();
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
Instant instant = zonedDateTime.toInstant();

Date date = Date.from(zonedDateTime.toInstant());

LocalDateTime

直接:LocalDate, LocalTime, ZonedDateTime, OffsetDateTime, Instant 间接:Date

LocalDateTime localDateTime = LocalDateTime.now();

LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
OffsetDateTime dateTime = new OffsetDateTime(localDateTime, ZoneOffset.of("+8"));
Instant instant = localDateTime.toInstant(ZoneOffset.of("+8"));

Date date = Date.from(instant);

OffsetDateTime

直接:LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant , long

OffsetDateTime offsetDateTime1 = Instant.now().atOffset(ZoneOffset.of("+8"));
OffsetDateTime offsetDateTime2 = OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.of("+8"));
OffsetDateTime offsetDateTime = OffsetDateTime.now();

LocalDate localDate = offsetDateTime.toLocalDate();
LocalTime localTime = offsetDateTime.toLocalTime();
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
ZonedDateTime zonedDateTime = offsetDateTime.toZonedDateTime();
Instant instant = offsetDateTime.toInstant();
long timestamp = offsetDateTime.toEpochSecond();

Date

直接:Instant 间接:LocalDate, LocalTime, LocalDateTime

Date date = new Date();

Instant instant = Instant.ofEpochMilli(date.getTime());
Instant instant1 = date.toInstant();

ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
LocalDate localDate = zonedDateTime.toLocalDate();
LocalTime localTime = zonedDateTime.toLocalTime();
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();

LocalDateTime localDateTime1 = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai"));
LocalTime localTime1 = localDateTime1.toLocalTime();
LocalDate localDate1 = localDateTime1.toLocalDate();

时间戳(毫秒数)

  • 直接获取当前时间戳
// 13 位
long timestamp = System.currentTimeMillis();
long timestamp1 = Instant.now().toEpochMilli();
long timestamp2 = new Date().getTime();
long timestamp4 = Clock.systemDefaultZone().millis();
// 10 位
long ts1= LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
long ts2= ZonedDateTime.now().toEpochSecond();
long ts3= OffsetDateTime.now().toEpochSecond();
  • LocalDate -> LocalDateTime -> Instant -> long
LocalDate localDateNow = LocalDate.now();
LocalDateTime now = localDateNow.atStartOfDay();
long time = now.toInstant(ZoneOffset.of("+8")).toEpochMilli();
  • LocalDate -> LocalDateTime -> Timestamp -> long
LocalDate localDate = LocalDate.now();
LocalDateTime now = localDate.atStartOfDay();
long time = Timestamp.valueOf(now).getTime();
  • long -> Instant -> Timestamp -> LocalDateTime
long now  = 1654068798634L;
Instant instant = Instant.ofEpochMilli(now);
Timestamp timestamp = Timestamp.from(instant);
LocalDateTime ldt = timestamp.toLocalDateTime();
System.out.println(ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss.SSS")));

格式化

以前:DateFormat

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

Date date = new Date();
System.out.println(dateFormat.format(date)); // 2022-06-02 12:53:35

Calendar cal = Calendar.getInstance();
System.out.println(dateFormat.format(cal.getTime())); // 2022-06-02 12:53:35

Java8: DateTimeFormatter

0. 自带的格式

格式不少,但感觉没几个用的上。 Predefined Formatters

String isoLocalDate = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(isoLocalDate);       // 2022-06-02
String isoLocalTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME);
System.out.println(isoLocalTime);       // 13:09:34.282
String isoLocalDateTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(isoLocalDateTime);   // 2022-06-02T13:09:34.283

1. 自定义格式

DateTimeFormatter默认还定义了一些常用的日期格式。满足不了需求我们再自定义。

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(LocalDateTime.now(ZoneOffset.of("+8")).format(dtf));

2. 自定义格式(支持默认值)

  • 只有【月、日】,其它设置默认值。
DateTimeFormatter df= new DateTimeFormatterBuilder()
		.appendPattern("MMdd")
		.parseDefaulting(ChronoField.YEAR_OF_ERA, 2046)
		.parseDefaulting(ChronoField.HOUR_OF_DAY, 23)
		.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 59)
		.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 59)
		.parseDefaulting(ChronoField.MILLI_OF_SECOND, 999) // 如果字符串中有毫秒,则会冲突。		
		.toFormatter();
System.out.println(LocalDateTime.parse("0524", df).toString());
// 2046-05-24T23:59:59.999
  • 只有毫秒,没有秒。将秒默认为 0
DateTimeFormatter df = new DateTimeFormatterBuilder()
		.appendPattern("yyMMddHHmm[ss].SSS")
		.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
		.toFormatter();
System.out.println(LocalDateTime.parse("2205241234.567", df).toString()); 
// 2022-05-24T12:34:00.567
  • 综合展示
DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder()
		.appendPattern("yyMMdd[[HH][mm][ss][.SSS]]")
		.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
		.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
		.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
		.toFormatter();
System.out.println(LocalDateTime.parse("220524", DATE_FORMAT).toString());
// 2022-05-24T00:00
System.out.println(LocalDateTime.parse("220524.567", DATE_FORMAT).toString());
// 2022-05-24T00:00:00.567
System.out.println(LocalDateTime.parse("22052412.567", DATE_FORMAT).toString());
// 2022-05-24T12:00:00.567
System.out.println(LocalDateTime.parse("2205241234.567", DATE_FORMAT).toString());
// 2022-05-24T12:34:00.567
System.out.println(LocalDateTime.parse("2205241234", DATE_FORMAT).toString());
// 2022-05-24T12:34

3. 其它

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");

String format = LocalDate.now().format(dateTimeFormatter);
String format1 = LocalTime.now().format(dateTimeFormatter);
String format2 = LocalDateTime.now().format(dateTimeFormatter);
String format3 = ZonedDateTime.now().format(dateTimeFormatter);

时间计算

加减时间

支持直接加减指定单位,返回结果。

java 业务历史表 java时间记录_java


java 业务历史表 java时间记录_时间日期_02

计算间隔

LocalDateTime now = LocalDateTime.now();
LocalDateTime target = now.plusDays(1);

long betweenDays = ChronoUnit.DAYS.between(now, target);
System.out.println(betweenDays);	// 1
long betweenHours = ChronoUnit.HOURS.between(now, target);
System.out.println(betweenHours);	// 24

时区

添加时区信息

LocalDateTime shanghai = LocalDateTime.now();
System.out.println(shanghai); // 2022-11-16T11:18:37.518
// 给日期时间直接加上时区信息
ZonedDateTime newYork = shanghai.atZone(ZoneId.of("America/New_York"));
System.out.println(newYork); // 2022-11-16T11:18:37.518-05:00[America/New_York]

时区间转换

ZoneOffset

// 指定东八区
ZoneOffset 东八区 = ZoneOffset.of("+8");

// 获取系统默认时区
ZoneOffset 默认时区 = OffsetDateTime.now().getOffset();
System.out.println(默认时区.equals(东八区)); // true

// 默认当前时间(使用系统默认时区)
LocalDateTime 北京 = LocalDateTime.now(); 
System.out.println(北京);
long l = 北京.toEpochSecond(东八区); // 获取逝去的秒数至 1970-01-01T00:00:00Z

// 转西五区时间
LocalDateTime 纽约 = LocalDateTime.ofEpochSecond(l, 0, ZoneOffset.of("-5"));
System.out.println(纽约);

ZoneId

// 获取时间,按系统默认时区(可能服务器不在国内)
LocalDateTime localDateTime = LocalDateTime.now();

// 将 localDateTime 转带时区格式:东八区上海时间
ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai");
ZonedDateTime 上海 = ZonedDateTime.of(localDateTime, shanghaiZoneId);

// 将 shanghai 转为西五区纽约时间
ZoneId newYorkZoneId = ZoneId.of("America/New_York");
ZonedDateTime 纽约 = 上海.withZoneSameInstant(newYorkZoneId);

System.out.println("默认时区: " + localDateTime);
System.out.println("东八区(上海): " + 上海.toLocalDateTime());
System.out.println("西五区(纽约): " + 纽约.toLocalDateTime());
// 日期时间,无时区信息
String dt = "2022-11-16T12:31:45";
LocalDateTime ldt = LocalDateTime.parse(dt, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(ldt);

// 指定为上海时间
ZonedDateTime 上海 = ldt.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(上海);
System.out.println(上海.toLocalDateTime());

// 转换为纽约时间
ZonedDateTime 纽约 = 上海.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(纽约);
System.out.println(纽约.toLocalDateTime());

工具类 hutool

DateTime now = DateUtil.date();
System.out.println(now); // 当地时间
DateTime dateTime = DateUtil.convertTimeZone(now, ZoneId.of("America/New_York"));
System.out.println(dateTime); // 纽约时间