java之LocalDate

在这里插入图片描述

Instant 时间戳

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

// 2023-07-04T09:02:39.456Z
Instant instant1 = Instant.now();    // 默认获取UTC时区

// 2023-07-04T17:02:39.456+08:00
OffsetDateTime offsetDateTime = instant1.atOffset(ZoneOffset.ofHours(8));

// 获取时间戳 1688461359456
System.out.println(instant1.toEpochMilli());

// 以Unix元年为起点,进行偏移量运算
// 1970-01-01T00:01:00Z
Instant instant2 = Instant.ofEpochSecond(60);

Period 日期之间的差

两个类表示时间量或两个日期之间的差,两者之间的差异为:Period基于日期值,而Duration基于时间值。

LocalDate startDate = LocalDate.of(2015, 2, 20);
LocalDate endDate = LocalDate.of(2017, 1, 15);

// Period 类表示一段时间的年、月、日,使用between()方法获取两个日期之间的差作为Period 对象返回
Period period = Period.between(startDate, endDate);

// Years:1 months:10 days:26
System.out.println("Years:" + period.getYears() +
        " months:" + period.getMonths() +
        " days:"+period.getDays());



// 另一个创建Period类型对象是基于年、月、日和周

// 3 10 10
Period fromUnits = Period.of(3, 10, 10);
// 0 0 50
Period fromDays = Period.ofDays(50);
// 0 5 0
Period fromMonths = Period.ofMonths(5);
// 10 0 0
Period fromYears = Period.ofYears(10);
// 0 0 280
Period fromWeeks = Period.ofWeeks(40);




// period的值可以通过plusX()、minusX()方法进行增加或减少,其中X表示日期单元
// 330
int days = fromWeeks.plusDays(50).getDays();
// -2
int days2 = fromWeeks.minusMonths(2).getMonths();

Duration 时间之间的差

Duration类表示秒或纳秒时间间隔,适合处理较短的时间,需要更高的精确性。我们能使用between()方法比较两个瞬间的差。

Instant start = Instant.parse("2017-10-03T10:15:30.00Z");
Instant end = Instant.parse("2017-10-03T10:14:30.00Z");

Duration duration = Duration.between(start, end);

// 60
System.out.println(duration.getSeconds());

// 判断前面时间是否晚于后面时间 true
boolean negative = duration.isNegative();

// 我们能基于下面的方法获得Duration对象,ofDays(), ofHours(), ofMillis(), ofMinutes(), ofNanos(), ofSeconds():
Duration fromDays = Duration.ofDays(1);
Duration fromMinutes = Duration.ofMinutes(60);

// 可以使用toDays(), toHours(), toMillis(), toMinutes()方法把Duration对象可以转成其他时间单元
duration.toDays();

// 也可以通过 plusX()、minusX()方法增加或减少Duration对象,其中X表示days, hours, millis, minutes, nanos 或 seconds
// 也可以使用plus()和minus()方法带TemporalUnit 类型参数进行加减
duration.plus(60, ChronoUnit.SECONDS).getSeconds();
duration.minus(30, ChronoUnit.SECONDS).getSeconds();

Clock 时钟

Clock类提供了访问当前日期和时间的方法,Clock 是时区敏感的,可以用来取代 System.currentTimeMillis() 来获取当前的微秒数。某一个特定的时间点也可以使用 Instant 类来表示,Instant 类也可以用来创建老的 java.util.Date 对象。

Clock clock = Clock.systemDefaultZone();
// 1688376161352
long millis = clock.millis();

Instant instant = clock.instant();
// Mon Jul 03 17:22:41 CST 2023
Date legacyDate = Date.from(instant);   // legacy java.util.Date

Timezones时区

在新 AP I中时区使用 ZoneId 来表示。时区可以很方便的使用静态方法 of 来获取到。时区定义了到 UTS 时间的时间差,在 Instant 时间点对象到本地日期对象之间转换的时候是极其重要的。

// [Asia/Aden, America/Cuiaba, Etc/GMT+9, Etc/GMT+8, Africa/Nairobi, America/Marigot,
// Asia/Aqtau, Pacific/Kwajalein, America/El_Salvador, Asia/Pontianak, Africa/Cairo,
// 还有好多,应该是打印所有的时区
System.out.println(ZoneId.getAvailableZoneIds());
// prints all available timezone ids
// 德国柏林
ZoneId zone1 = ZoneId.of("Europe/Berlin");
// 可能是巴西时区
ZoneId zone2 = ZoneId.of("Brazil/East");
System.out.println(zone1.getRules());
System.out.println(zone2.getRules());
// ZoneRules[currentStandardOffset=+01:00]
// ZoneRules[currentStandardOffset=-03:00]

LocalDate 本地日期

LocalDate 表示了一个确切的日期,比如 2014-03-11。该对象值是不可变的,用起来和 LocalTime 基本一致。下面的例子展示了如何给 Date 对象加减天/月/年。另外要注意的是这些对象是不可变的,操作返回的总是一个新实例。

public class InterfaceDemo {

    public static void main(String[] args) {

		// 构造日期
        // 2023-07-04
        LocalDate today = LocalDate.now();

        // 设置日期,返回2099-02-28
        LocalDate now2 = LocalDate.of(2099, 2, 28);

		// 2022-07-04
        LocalDate independenceDay = LocalDate.of(2022, Month.JULY, 4);
        
        // 字符串转日期
        LocalDate endOfFeb = LocalDate.parse("2018-02-28");
        // 严格按照yyyy-MM-dd验证,02写成2都不行,当然也有一个重载方法允许自己定义格式



		


		// 获取当前日期的相关信息
        // 今天是几号 25
        int dayofMonth = today.getDayOfMonth();

        // 今年是一年中的哪一天,176
        int dayofYear = today.getDayOfYear();

		// MONDAY
        DayOfWeek dayOfWeek = independenceDay.getDayOfWeek();




		// 对当前日期进行操作
        // 2023-07-05
        LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);

        // 2023-07-03
        LocalDate yesterday = tomorrow.minusDays(2);

        // 取本月第1天:2023-07-01
        LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 2018-04-01


		// 取本月第2天:2023-07-02
        LocalDate secondDayOfThisMonth = today.withDayOfMonth(2); // 2018-04-02

		// 这些只是单纯的获取日期,可见其能够获取日期的种类多种多样,比原来的Date型好用太多,尤其是过去的Date型,月份计算居然是从0开始,不是一般的反人类了。
        // LocalDate更加强大的地方还没展示

		// 取本月最后一天,2023-07-31,再也不用计算是28,29,30还是31:
        LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); // 2018-04-30
        // 取下一天:2023-08-01
        LocalDate firstDayOfNextMonth = lastDayOfThisMonth.plusDays(1);
        // 取2017年1月第一个周一:2017-01-02
        LocalDate firstMondayOf2017 = LocalDate.parse("2017-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));

        
        
        

        System.out.println("========================================================");




        // 从字符串解析一个 LocalDate 类型和解析 LocalTime 一样简单。代码如下:
        DateTimeFormatter germanFormatter = DateTimeFormatter
                .ofLocalizedDate(FormatStyle.MEDIUM)
                .withLocale(Locale.GERMAN);
        // // 2014-12-24
        LocalDate xmas = LocalDate.parse("24.12.2014", germanFormatter);


        // 另外,LocalDate的格式化不要用SimpleDateFormat的方法。
        LocalDate today2 = LocalDate.now();
        DateTimeFormatter formatters = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        // 2023年07月04日
        String text = today2.format(formatters);

	}
}

LocalTime 本地时间

LocalTime定义了一个没有时区信息的时间,例如 晚上 10 点,或者 17:30:15。下面的例子使用前面代码创建的时区创建了两个本地时间。之后比较时间并以小时和分钟为单位计算两个时间的时间差。

// 获得当前时间
LocalTime now = LocalTime.now();

// 构造时间
LocalTime zero = LocalTime.of(0, 0, 0); // 00:00:00
// 字符串转时间
LocalTime mid = LocalTime.parse("12:00:00"); // 12:00:00

System.out.println(zero.isBefore(mid));  // true
long hoursBetween = ChronoUnit.HOURS.between(zero, mid);
long minutesBetween = ChronoUnit.MINUTES.between(zero, mid);
System.out.println(hoursBetween);       // 间隔12小时
System.out.println(minutesBetween);     // 间隔720分钟



// LocalTime提供了多种工厂方法来简化对象的创建,包括解析时间字符串。
DateTimeFormatter germanFormatter = DateTimeFormatter
// 本地化相关的格式
// FormatStyle是一个内置的枚举,提供了一些值FULL、LONG、MEDIUM和SHORT
//      FormatStyle 描述              日期样式            时间样式                    日期和时间样式
//      FULL	高度详细	            2020年8月13日星期四	上午12:43:00中欧夏令时	    2020年8月13日星期四上午12:43:48中欧夏令时
//      LONG	包含大部分细节	        2020年8月13日	    上午12:45:27中欧夏令时	    2020年8月13日上午12:44:40中欧夏令时
//      MEDIUM	包含一些细节	        2020年8月13日	    上午12:45:49	            2020年8月13日,上午12:46:29
//      SHORT	通常是数字和最短可能	20/8/13	            上午12:47	            20/8/13,上午12:47
.ofLocalizedTime(FormatStyle.SHORT)
// 德国,这个用English和Chinese都会报错
// 网上也找不到这个的具体用法
.withLocale(Locale.GERMAN);
LocalTime leetTime = LocalTime.parse("13:37", germanFormatter);
System.out.println(leetTime);   // 13:37

LocalDateTime 本地日期时间

LocalDateTime同时表示了时间和日期,相当于前两节内容合并到一个对象上了。LocalDateTime和LocalTime还有LocalDate一样,都是不可变的。

Java的Date,Calendar类型使用起来并不是很方便,而且Date类(据说)有着线程不安全等诸多弊端。同时若不进行封装,会在每次使用时特别麻烦。于是Java8推出了线程安全、简易、高可靠的时间包。并且数据库中也支持LocalDateTime类型,在数据存储时候使时间变得简单。

Java8这次新推出的包括三个相关的时间类型:

  • LocalTime时分秒纳秒
  • LocalDate年月日
  • LocalDateTime年月日时分秒
LocalDateTime sylvester = LocalDateTime.of(2014, Month.DECEMBER, 31, 23, 59, 59);
DayOfWeek dayOfWeek = sylvester.getDayOfWeek();
System.out.println(dayOfWeek);      // WEDNESDAY
Month month = sylvester.getMonth();
System.out.println(month);          // DECEMBER
long minuteOfDay = sylvester.getLong(ChronoField.MINUTE_OF_DAY);
System.out.println(minuteOfDay);    // 1439



// 只要附加上时区信息,就可以将其转换为一个时间点Instant对象,Instant时间点对象可以很容易的转换为老式的java.util.Date。代码如下:
Instant instant = sylvester
        .atZone(ZoneId.systemDefault())
        .toInstant();
Date legacyDate = Date.from(instant);
System.out.println(legacyDate);     // Wed Dec 31 23:59:59 CET 2014



// 格式化LocalDateTime和格式化时间和日期一样的,除了使用预定义好的格式外,我们也可以自己定义格式。代码如下:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy - HH:mm");
LocalDateTime parsed = LocalDateTime.parse("Nov 03, 2014 - 07:13", formatter);
String string = formatter.format(parsed);
System.out.println(string);     // Nov 03, 2014 - 07:13
// 和java.text.NumberFormat不一样的是新版的DateTimeFormatter是不可变的,所以它是线程安全的。

日期格式化

package com.example.javasestudy.localdatetime;


import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@SpringBootTest
public class TestLocalDateTime {

    @Test
    void contextLoads() {

        // DateTimeFormatter 代替 Calendar的SimpleDateFormat,
        LocalDateTime of = LocalDateTime.of(2024, 4, 1, 11, 40, 50);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
        String format = dateTimeFormatter.format(of);
        DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
        LocalDateTime parse = LocalDateTime.parse(format, dateTimeFormatter2);

        // T的问题暂时没有好的解决办法,网上说可以使用配置类来解决,还没尝试过,可以的话这是最好的办法
        // 或者在字段上加注解,或者使用字符串替换(这应该是最逼不得已的办法吧)
        // 这个问题的原因是,LocalDateTime的重写toString的时候加上的
        // return date.toString() + 'T' + time.toString();
        // 2024-04-01T11:40:50
        System.out.println(of);
        // 2024年04月01日 11时40分50秒
        System.out.println(format);
        // 2024-04-01T11:40:50
        System.out.println(parse);


    }
}

JDBC映射

最新JDBC映射将把数据库的日期类型和Java 8的新类型关联起来:

SQL -> Java
--------------------------
date -> LocalDate
time -> LocalTime
timestamp -> LocalDateTime

部分内容转载自:
https://blog.csdn.net/u011055819/article/details/80070429
https://www.cnblogs.com/wmyskxz/p/13527583.html
https://blog.csdn.net/neweastsun/article/details/88770592

有的时候,人们把他们装出的那一面做的如此完美,随着时间的推移,他们似乎真的变成了他们所装扮的那个人了。

月亮与六便士

威廉·萨默赛特·毛姆

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值