一文搞懂jdk8时区、日期、时间:Instant、LocalDateTime、ZonedDateTime,以及与旧版本代码的互操作

与之前版本的日期时间代码的互操作

旧版本的 java.util.Date 相当于 jdk 8的Instant ,两者可以互转,代码见下。

旧版本的 java.util.GregorianCalendar 相当于 jdk 8的 LocalDateTime,两者可以互转,代码见下。

旧版本的 java.util.TimeZone 与 jdk8的 ZoneId 可以互转,方法都在TimeZone中,代码见下。

其它java.sql中的日期时间与jdk8的日期时间之间的互操作,见下。

Instant instant = Instant.now();
LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();


// Date 与  Instant 互转
Date date = new Date();
System.out.println(date.toInstant());	// Date 转 Instant
System.out.println(Date.from(instant));	// Instant 转 Date

// GregorianCalendar 与 ZoneDateTime 互转
GregorianCalendar calendar = new GregorianCalendar(); // 默认时区为根据服务器操作系统的配置获得的时区
System.out.println(calendar.toZonedDateTime());		 
System.out.println(GregorianCalendar.from(zonedDateTime));

// 与以上类似地:
// java.sql.Date 与 LocalDate 可以互转,方法都在java.sql.Date类中。
// java.sql.Time 与 LocalTime 可以互转,方法都在java.sql.Time类中。
// java.sql.Timestamp 与 LocalDateTime / Instant 可以互转,方法都在java.sql.Timestamp类中。

// java.util.TimeZone 与 ZoneId 可以互转,方法都在TimeZone中。TimeZone.getTimeZone(ZoneId)

// DateTimeFormatter 的对象可以转成 java.text.DateFormat 对象: formatter.toFormat();

Locale

一个Locale对象代表一个特定的地理、政治或文化区域。需要指定一个Locale对象来执行其任务的操作称为区域敏感的操作,并使用Locale对象为用户提供特定区域的定制信息。例如,打印日期是一个区分区域设置的操作,该文本应该根据用户所在国家、地区或文化的习俗和惯例进行格式化。

一个Locale对象由客户端给出的 language & country & script(比如四川话) & varient(变体语种) 等信息确定。

Locale.getDefault();静态方法,会给出根据服务器操作系统中设置的 language / country 等信息,得到系统默认的Locale对象。

Locale类中定义了以下常量实例:

static public final Locale CHINESE = createConstant("zh", "");

static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");

static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");	

static public final Locale CHINA = SIMPLIFIED_CHINESE;

static public final Locale PRC = SIMPLIFIED_CHINESE;


static public final Locale ENGLISH = createConstant("en", "");

static public final Locale UK = createConstant("en", "GB");


static public final Locale US = createConstant("en", "US");

static public final Locale FRENCH = createConstant("fr", "");

static public final Locale FRANCE = createConstant("fr", "FR");


static public final Locale CANADA = createConstant("en", "CA");

static public final Locale CANADA_FRENCH = createConstant("fr", "CA");
......

Locale类中还提供了以下工具方法:

public static Locale[] getAvailableLocales() 					{	......    }
public static synchronized void setDefault(Locale newLocale) 	{	......    }
public static String[] getISOCountries() 						{	......    }
public static String[] getISOLanguages() 						{	......    }	

ZoneId - 时区标识对象

由于世界各国家与地区经度不同,地方时也有所不同,因此划分了不同的时区。

每隔经度15°划分一个时区,以该时区的时区中心线的地方时作为该时区的区时。相邻两个时区相差1小时。

正式的时区划分包括24个时区,每一时区由一个英文字母表示。

规定以英国伦敦的格林威治天文台旧址所在经线为0°经线,也是中时区(零时区)的时区中心线。
7.5°W - 7.5°E 为 零时区,代号UTC, 时区中心线为0°经线,英文字母为Z(zero)。
7.5°E - 22.5°E 为 东一区,代号UTC+1,时区中心线为15°E经线,
22.5°E - 37.5°E 为 东一区,代号UTC+2,时区中心线为30°E经线,
依次类推 …
7.5°W - 22.5°W 为 西一区,代号UTC-1,时区中心线为15°E经线,
22.5°W - 37.5°W 为 西二区,代号UTC-2,时区中心线为30°E经线,

在JDK中,使用IANA(互联网编码分配管理机构,Internet Assigned Numbers Authority )定义的时区编码,根据IANA的时区数据库中的数据,为每个时区定义一个ZoneId对象用于标识。

ZoneId对象用于在 Instant 和 LocalDateTime 之间进行转换的规则。

在ZoneId类中定义了一个常量Map,用于存储IANA(互联网编码分配管理机构,Internet Assigned Numbers Authority )的数据库中的时区ID数据。如下:

 map.put("CTT", "Asia/Shanghai");     	// CTT 为时区ID Asia/Shanghai的简写形式。
 map.put("ACT", "Australia/Darwin");
 map.put("AET", "Australia/Sydney");
 map.put("AGT", "America/Argentina/Buenos_Aires");
 map.put("ART", "Africa/Cairo");
 map.put("AST", "America/Anchorage");
 map.put("BET", "America/Sao_Paulo");        
 ......

ZoneId类中的常用静态方法:

ZoneId.of("Asia/Shanghai");		// 可以获得时区 Asia/Shanghai 的ZoneId对象。
ZoneId.systemDefault();		//	获取当前服务器操作系统设置的时区
ZoneId.getAvailableZoneIds();	// 获取所有时区ID对象的displayName

IANA的时区编码每年会更新数次,而批量更新会处理夏令时的变更规则:当夏令时开始时,时钟会向前拨快一小时,当你构建的时间恰好落入了这跳过去的1小时内时,jdk会直接返回给你+1hour后的时间。如:在2013年,中欧地区(时区ID为Europe/Berlin)在3月31日2:00切换到当年的夏令时,直接将时间拨到3:00,同时时区偏移量由+01:00变更为+02:00。如果你试图构建 [Europe/Berlin] 时区的 2013年的 3月31日2:30,那么jdk会返回给你2013-03-31T3:30+02:00[Europe/Berlin]。当夏令时结束,进入冬令时时,会将时钟向后拨慢1小时,并将时区偏移量-1hour。比如2013年10月27日的2:30,中欧地区进入冬令时,当时钟到3:30时,会将时钟向后拨慢1小时,即拨回2:30,并将时区偏移量-1hour,即由+02:00,变更为+01:00。

ZoneId是一个抽象类,ZoneRegion是其包内可见的实现类,ZoneOffset是ZoneId的公开实现类。

转借:5分钟搞懂计算机的各种时间(GMT、UTC、CST、unix时间戳-timestamp)

ZoneOffset - 时区偏移量对象

时区偏移量,是时区相对于格林威治时间精确到秒。
有三个常量实例:

public static final ZoneOffset UTC = ZoneOffset.ofTotalSeconds(0);  // 0时区,即UTC时间。偏移量为0秒。
public static final ZoneOffset MIN = ZoneOffset.ofTotalSeconds(-MAX_SECONDS);  // -18:00。偏移量为-18*60*60秒
public static final ZoneOffset MAX = ZoneOffset.ofTotalSeconds(MAX_SECONDS);   // +18:00。偏移量为+18*60*60秒

可以通过静态方法ZoneOffset.of( String offsetId ) 获取一个ZoneOffset的实例。
offsetId 的格式可以如下列出的任意一种:

  • {@code Z} - for UTC
  • {@code +h}
  • {@code +hh}
  • {@code +hh:mm}
  • {@code -hh:mm}
  • {@code +hhmm}
  • {@code -hhmm}
  • {@code +hh:mm:ss}
  • {@code -hh:mm:ss}
  • {@code +hhmmss}
  • {@code -hhmmss}
ZoneOffset offset = ZoneOffset.of("+08:00");
System.out.println(offset);		
System.out.println(ZoneOffset.ofHours(8));
System.out.println(ZoneOffset.ofHoursMinutes(-8, -23));   //  时、分、秒的正负号必须完全一致
System.out.println(offset.getTotalSeconds());
System.out.println(ZoneOffset.ofTotalSeconds(28800));	
+08:00
+08:00
-08:23
28800
+08:00

ZoneOffset 是 ZoneId 的实现类

TemporalAmount / Duration - 时间量

TemporalAmount

TemporalAmount 接口是定义时间量的框架级接口,如“6小时”、“8天”或“2年零3个月”。

这里要厘清几个时间概念:

  1. 时间量:如“6个小时”、“8天”或“2年零3个月”。
  2. 时间点(Date / Instant / LocalDatetime):如 2020年1月1日 8点8分。
  3. 计时单位:如 年、月、日、时、分、秒。

Duration

Duration类是TemporalAmout接口的实现类,类中定义了一些生成Duration实例的静态方法:

System.out.println( Duration.ofDays(2));	// 2天
System.out.println( Duration.ofHours(2));	// 2小时
System.out.println( Duration.ofMinutes(2));
System.out.println( Duration.ofSeconds(2));
System.out.println( Duration.ofMillis(2));
System.out.println( Duration.ofNanos(2));	// 2纳秒,注意毫秒和纳秒中间没有微秒:micro

Duration类使用两个实例字段:long seconds; int nanos;来存储Duration实例的所表示的时间量的值。
由于闰年和闰秒的原因,年等度量单位并不进准,因此Duration.ofXxx(amount),中没有用ofYear()这样的方法。

Days / Hours / minutes / seconds 都会转换为相应的second秒的量,相加后存到seconds字段中。
millis / nanos 会转换为相应的nano纳秒的量,相加后存储到nanos字段中。

TemporalUnit / ChronoUnit - 计时单位

TemporalUnit 是个接口,ChronoUnit是它的一个实现类。

TemporalUnit 接口表示日期时间单位,如天或小时。时间的度量是基于单位的,例如年、月、日、小时、分钟和秒。

该接口的实现类的一个实例就代表上述的一个时间单位。

ChronoUnit类中定义了常用时间单位,它是一个枚举类,有两个字段:String name; Duration duration。name 是单位名称,duration的值是单位的基本时间量。

由于 闰秒 和 闰年 的原因,所有时间长度大于秒的时间单位,其Duration都用Duration.ofSeconds( secondAmout)来表示。

ChronoUnit中的枚举实例:

public enum ChronoUnit implements TemporalUnit {

    NANOS("Nanos", Duration.ofNanos(1)),		// 单位:纳秒,这个单位的基本时间量是:1纳秒
   
    MICROS("Micros", Duration.ofNanos(1000)),	// 单位:微秒,这个单位的基本时间量是:1000纳秒
   
    MILLIS("Millis", Duration.ofNanos(1000_000)),	// 单位:毫秒,这个单位的基本时间量是:1000000纳秒
    
    SECONDS("Seconds", Duration.ofSeconds(1)),		// 单位:秒,这个单位的基本时间量是:1秒
   
    MINUTES("Minutes", Duration.ofSeconds(60)),		// 单位:分钟,这个单位的基本时间量是:60秒
   
    HOURS("Hours", Duration.ofSeconds(3600)),		// 单位:小时,这个单位的基本时间量是:3600秒
   
    HALF_DAYS("HalfDays", Duration.ofSeconds(43200)),		// 半天
    
    DAYS("Days", Duration.ofSeconds(86400)),		// 日
   
    WEEKS("Weeks", Duration.ofSeconds(7 * 86400L)),		// 周
   
    MONTHS("Months", Duration.ofSeconds(31556952L / 12)),	// 月
    
    YEARS("Years", Duration.ofSeconds(31556952L)),		//	年
    
    DECADES("Decades", Duration.ofSeconds(31556952L * 10L)),	// 十年,年代
   
    CENTURIES("Centuries", Duration.ofSeconds(31556952L * 100L)),	// 世纪、百年
   
    MILLENNIA("Millennia", Duration.ofSeconds(31556952L * 1000L)),	// 千年
   
    ERAS("Eras", Duration.ofSeconds(31556952L * 1000_000_000L)),	// 纪元,十万年
    
    FOREVER("Forever", Duration.ofSeconds(Long.MAX_VALUE, 999_999_999));	
    ....
}    

Instant

Instant类定义的是零时区-UTC时间,即格林威治时间、零时区的时间。不是UTC+1 或者UTC-1时区时间,也不是UTC+2或者UTC-2时区时间。

不论当前服务器所在本地时区是什么,Instant对象永远只表示UTC时间。

因此如果服务器操作系统设置的本地时区不是0时区,那么Instant给出的时间会与服务器本地时间不一致。
假如服务器本地时区为北京时间(时区ID为:Asia/Shanghai,时区偏移量为:+08:00)是:
2022-05-11 15:03:06
那么:

System.out.println(Instant.now());
2022-05-11T07:03:06.491Z    // 其中T是Date和Time的分隔符,Z表示零时区。

System.currentTimeMillis()

这个方法,获取的毫秒数,也是直接获取当前0时区即UTC时间,距离1970-01-01的毫秒数。
与之相对应的,假如使用服务器本地时间(比如北京时间)来获取,那么应当是获取服务器本地时间、距离1970-01-01 00:00:00对应的本地时间(如果是北京时间,则应该是1970-01-01 08:00:00)的毫秒数。

LocalDate

不带时区信息的本地日期对象。
如:

System.out.println(LocalDate.now());
2022-05-11

应当注意到:

Instant.now().toString();	// 是带时区信息的,Z,即零时区。体现在 2022-07-13T11:35:26.752Z 的最后一个字符Z上。
new Date().toString();	// 	也是带有时区信息的,CST,即零时区。Wed Jul 13 19:34:25 CST 2022

LocalTime

不带时区信息的本地时间对象。

System.out.println(LocalTime.now());
15:18:42.284

LocalDateTime

不带时区信息的本地日期时间对象。

System.out.println(LocalDateTime.now());
2022-05-11T17:49:38.321

ZoneDateTime

带时区信息的本地日期时间

ZonedDateTime.now().toString();  // 2022-07-13T19:48:18.162+08:00[Asia/Shanghai],"+08:00[Asia/Shanghai]"即为时区信息。时区会默认为当前服务器所在时区,时间为本地时间
System.out.println(2022, 5, 11, 15, 20, 06, 00, ZoneId.of("Asia/Shanghai")); // 会直接使用给定的日期时间、和时区,构造ZoneDateTime对象。
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2020-01-01T12:23:56.768+08:00[Asia/Shanghai]");

假如,当前本地时间是:2022-05-11 15:20:05

2022-05-11T15:20:05.754+08:00[Asia/Shanghai]    // 其中,T是Date与Time的分隔符;+08:00代表时区偏移量,+代表比0时区时间快8个小时,即东八区;如果是西五区,则是-05:00;[Asia/Shanghai]则是具体的时区的displayName。
2022-05-11T15:20:06+08:00[Asia/Shanghai]

OffsetDateTime

带有时区偏移量信息的日期时间对象。
与ZoneDateTime的区别是,只有时区偏移量信息,没有时区ID。即仅记录时区偏移量,而不记录时区ID。

System.out.println(OffsetDateTime.now());
System.out.println(OffsetDateTime.of(2011, 5, 11, 15, 43, 23, 0, ZoneOffset.of("+08:00")));

假如当前服务器上显式的时间是:2022-05-11 15:35:20

2022-05-11T15:35:20.837+08:00
2011-05-11T15:43:23+08:00

DateTimeFormatter - 格式化

DateTimeFormatter类提供了三种用于打印日期时间值的格式器。

预定义的格式器

一种是预定义的格式器,例如:

ZonedDateTime zDateTime = ZonedDateTime.now();
System.out.println(		zDateTime.format(DateTimeFormatter.BASIC_ISO_DATE));
System.out.println(		zDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE));
System.out.println(		zDateTime.format(DateTimeFormatter.ISO_DATE));
System.out.println(		zDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE));
System.out.println(		zDateTime.format(DateTimeFormatter.ISO_INSTANT));
System.out.println(		zDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
System.out.println(		zDateTime.format(DateTimeFormatter.ISO_ORDINAL_DATE));
System.out.println(		zDateTime.format(DateTimeFormatter.ISO_WEEK_DATE));		
20220511+0800
2022-05-11
2022-05-11+08:00
2022-05-11+08:00
2022-05-11T12:36:36.575Z
2022-05-11T20:36:36.575+08:00[Asia/Shanghai]	//  ISO_ZONED_DATE_TIME
2022-131+08:00		// ISO_ORDINAL_DATE,131是指给定日期是2022年的第131天。
2022-W19-3+08:00	// ISO_WEEK_DATE ,W19是指2022年的第19周,3是指周三

其它类似的预定义的DateTimeFormatter常量还有:

预定义格式解释
ISO_LOCAL_DATE无时区信息的日期
ISO_LOCAL_TIME无时区信息的时间
ISO_LOCAL_DATE_TIME无时区信息的日期时间
ISO_DATE带时区偏移量信息的日期,2022-05-11+08:00
ISO_TIME带时区偏移量信息的时间
ISO_DATE_TIME带时区偏移量信息的日期时间
ISO_OFFSET_DATE带时区偏移量信息的日期,2022-05-11+08:00
ISO_OFFSET_TIME带时区偏移量信息的时间
ISO_OFFSET_DATE_TIME带时区信息的日期时间,包括偏移量和时区ID,2022-05-11T20:36:36.575+08:00[Asia/Shanghai]

与Locale相关的格式器

对于日期时间,有4种相关的格式化风格:

  • FormatStyle.SHORT,
  • FormatStyle.MEDIUM,
  • FormatStyle.LONG,
  • FormatStyle.FULL

DateTimeFormatter类中提供了获取这些风格的实例的静态方法:

  • ofLocalizedDate(FormatStyle)
  • ofLocalizedTime(FormatStyle)
  • ofLocalizedDateTime(FormatStyle)

可以使用DateTimeFormatter的静态方法来获取这些风格的实例,并且这些风格随着Locale改变而不同,如:

ZonedDateTime zDateTime = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
System.out.println(formatter.format(zDateTime));	// 默认的Locale是根据当前服务器操作系统设置的language、country而获得的Locale。即Locale.CHINESE
System.out.println(formatter.withLocale(Locale.CANADA).format(zDateTime));	// 将Locale设置为CANADA
System.out.println(formatter.withLocale(Locale.ENGLISH).format(zDateTime));
22-5-11
11/05/22
5/11/22

相互转换

  1. 由于本地日期时间没有时区信息,而Instant时间则是0时区的时间,因此两者相互转换时必须加上时区信息。
Instant instant = Instant.now();
LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();

// 转成Instant
System.out.println(	localDateTime.toInstant(ZoneOffset.ofHours(8)));
System.out.println(	zonedDateTime.toInstant());
System.out.println(	offsetDateTime.toInstant());

// 转成LocalDateTime
System.out.println(	LocalDateTime.from(zonedDateTime));
System.out.println(	LocalDateTime.from(offsetDateTime));
System.out.println(	LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai")));  // 由于Instant总是0时区的时间,要转成local的本地时间,必须要给出当地的时区,才能转换

// 转成ZonedDateTime
System.out.println(	ZonedDateTime.from(offsetDateTime));
System.out.println(	ZonedDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai")));  // 转成本地时区时间 
System.out.println(	ZonedDateTime.of(localDateTime, ZoneId.of("Asia/Shanghai")));	// 转成本地时区时间

TemporalAdjuster

这个接口只有一个接口方法,功能是:将调用者的字段数据调整给参数中的temporal。
注意是,“调整给”,而不是“调整为”。也就是说将参数中的temporal,调整为调用者的数据。

Temporal  adjustInto(Temporal  temporal);

Instant / LocalDateTime / LocalDate / LocalTime / OffsetDateTime 等日期时间类都实现了这个接口。

日期时间调整器 - TemporalAdjusters

temporal.with(ajuster)
所有实现了Temporal接口的类的实例,都可以调用自身的with( ajuster )方法,来调整自身的日期时间。

需要注意的是,Instant / LocalDateTime / LocalDate / LocalTime / OffsetDateTime 等类,也都实现了TemporalAdjuster接口,因此这些类的实例对象本身也都是一个ajuster实例,也都可以作为with(ajuster)的参数,用来调整调用者的日期时间。

实际上,由于大部分的日期时间类,都同时实现了 Temporal 接口和 TemporalAdjuster接口,因此,这些日期时间类对于temporal.with(adjuster)方法的实现,很多都是直接调用接口方法:adjuster .adjustInto( temporal ),直接将函数参数和调用方一对调。

工具类TemporalAdjusters提供了许多生成adjuster实例的静态方法,这些adjuster可以实现复杂的日期调整。
需要注意的是,TemporalAdjusters只提供了调整日期、星期的adjuster生成器,没有年、月、时、分、秒相关的生成器。


LocalDateTime localDateTime = LocalDateTime.now();

System.out.println(localDateTime.with(    TemporalAdjusters.firstDayOfMonth()));   // 将instant的日期调整为本月第一天,注意只是day变了,年月、时间都没变。
System.out.println(localDateTime.with(    TemporalAdjusters.firstDayOfYear()));
System.out.println(localDateTime.with(    TemporalAdjusters.firstDayOfNextMonth()));
System.out.println(localDateTime.with(    TemporalAdjusters.firstDayOfNextYear()));
System.out.println(localDateTime.with(    TemporalAdjusters.lastDayOfMonth()));
System.out.println(localDateTime.with(    TemporalAdjusters.lastDayOfYear()));
System.out.println(localDateTime.with(    TemporalAdjusters.ofDateAdjuster(localDate->localDate.plusDays(2))));

System.out.println(localDateTime.with(    TemporalAdjusters.firstInMonth(DayOfWeek.FRIDAY)));  	// 当月的第一个周五
System.out.println(localDateTime.with(    TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY)));  	// 当月的最后一个周五
System.out.println(localDateTime.with(    TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY)));  	// 当月的第2个周五
System.out.println(localDateTime.with(    TemporalAdjusters.previous( DayOfWeek.FRIDAY)));  	// 今天之前、距离今天最近的周五
System.out.println(localDateTime.with(    TemporalAdjusters.next( DayOfWeek.FRIDAY)));  		// 今天之后、距离今天最近的周五
System.out.println(localDateTime.with(    TemporalAdjusters.previousOrSame( DayOfWeek.FRIDAY)));  // 今天或之前的最近的一个周五
System.out.println(localDateTime.with(    TemporalAdjusters.nextOrSame( DayOfWeek.FRIDAY)));  	// 今天或之后最近的一个周五

需要注意的是,调整只能对于日期时间支持的ChronoField进行。比如Instant类中,只定义了long second; int nanos;这两个字段,second存储现在距离1970-01-01 00:00:00的秒数,nanos存储当前秒的毫秒数(即 nanos_of_second),因此对instant实例的调整,只能对这两个ChronoField进行调整。同理,对于LocalTime,只能对其进行时分秒的调整。

TempralAmount - 时间量

在以上的

其中Instant类实现了以下接口:
在这里插入图片描述
LocalDate类也实现了Temporal接口:

public final class LocalDate
        implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {	...	}
        
// 其中, TemporalAdjuster 和 ChronoLocalDate 也都继承了 Temporal接口
public interface ChronoLocalDate
        extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate> {	...		}
        
// 而 TemporalAdjuster 是一个函数式接口
@FunctionalInterface
public interface TemporalAdjuster {

    Temporal adjustInto(Temporal temporal);

}

LocalTime 和 LocalDateTime 的类结构与 LocalDate 类似。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是关于JDK 8日期相关类的介绍和示例: 1. LocalDate类: - LocalDate类表示一个不可变的日期对象,它只包含日期部分(年、月、日)。 - 使用`now()`方法获取当前日期。 - 使用`of()`方法创建指定日期。 - 使用`getXXX()`方法获取日期的年、月、日等部分。 - 使用`plusXXX()`和`minusXXX()`方法进行日期的加减操作。 - 使用`isXXX()`方法判断日期的属性,如是否为闰年等。 示例代码: ```java import java.time.LocalDate; // 获取当前日期 LocalDate currentDate = LocalDate.now(); System.out.println("当前日期: " + currentDate); // 创建指定日期 LocalDate specificDate = LocalDate.of(2022, 1, 1); System.out.println("指定日期: " + specificDate); // 获取日期的年、月、日 int year = currentDate.getYear(); int month = currentDate.getMonthValue(); int day = currentDate.getDayOfMonth(); System.out.println("年: " + year + ", 月: " + month + ", 日: " + day); // 日期的加减操作 LocalDate futureDate = currentDate.plusDays(7); LocalDate pastDate = currentDate.minusMonths(1); System.out.println("未来日期: " + futureDate); System.out.println("过去日期: " + pastDate); // 判断是否为闰年 boolean isLeapYear = currentDate.isLeapYear(); System.out.println("是否为闰年: " + isLeapYear); ``` 2. LocalTime类: - LocalTime类表示一个不可变的时间对象,它只包含时间部分(时、分、秒、纳秒)。 - 使用`now()`方法获取当前时间。 - 使用`of()`方法创建指定时间。 - 使用`getXXX()`方法获取时间的时、分、秒等部分。 - 使用`plusXXX()`和`minusXXX()`方法进行时间的加减操作。 示例代码: ```java import java.time.LocalTime; // 获取当前时间 LocalTime currentTime = LocalTime.now(); System.out.println("当前时间: " + currentTime); // 创建指定时间 LocalTime specificTime = LocalTime.of(12, 30, 0); System.out.println("指定时间: " + specificTime); // 获取时间的时、分、秒 int hour = currentTime.getHour(); int minute = currentTime.getMinute(); int second = currentTime.getSecond(); System.out.println("时: " + hour + ", 分: " + minute + ", 秒: " + second); // 时间的加减操作 LocalTime futureTime = currentTime.plusHours(2); LocalTime pastTime = currentTime.minusMinutes(30); System.out.println("未来时间: " + futureTime); System.out.println("过去时间: " + pastTime); ``` 3. LocalDateTime类: - LocalDateTime类表示一个不可变的日期时间对象,它包含日期时间部分。 - 使用`now()`方法获取当前日期时间。 - 使用`of()`方法创建指定日期时间。 - 使用`getXXX()`方法获取日期时间的年、月、日、时、分、秒等部分。 - 使用`plusXXX()`和`minusXXX()`方法进行日期时间的加减操作。 示例代码: ```java import java.time.LocalDateTime; // 获取当前日期时间 LocalDateTime currentDateTime = LocalDateTime.now(); System.out.println("当前日期时间: " + currentDateTime); // 创建指定日期时间 LocalDateTime specificDateTime = LocalDateTime.of(2022, 1, 1, 12, 30, 0); System.out.println("指定日期时间: " + specificDateTime); // 获取日期时间的年、月、日、时、分、秒 int year = currentDateTime.getYear(); int month = currentDateTime.getMonthValue(); int day = currentDateTime.getDayOfMonth(); int hour = currentDateTime.getHour(); int minute = currentDateTime.getMinute(); int second = currentDateTime.getSecond(); System.out.println("年: " + year + ", 月: " + month + ", 日: " + day); System.out.println("时: " + hour + ", 分: " + minute + ", 秒: " + second); // 日期时间的加减操作 LocalDateTime futureDateTime = currentDateTime.plusDays(7); LocalDateTime pastDateTime = currentDateTime.minusMonths(1); System.out.println("未来日期时间: " + futureDateTime); System.out.println("过去日期时间: " + pastDateTime); ``` 4. Calendar类: - Calendar类是Java旧版的日期时间处理类,JDK 8之后推荐使用新的日期时间API。 - Calendar类可以用于获取和设置日期时间的各个部分,如年、月、日、时、分、秒等。 - 使用`getInstance()`方法获取当前日期时间的Calendar实例。 - 使用`get()`方法获取日期时间的各个部分。 - 使用`set()`方法设置日期时间的各个部分。 示例代码: ```java import java.util.Calendar; // 获取当前日期时间的Calendar实例 Calendar currentCalendar = Calendar.getInstance(); System.out.println("当前日期时间: " + currentCalendar.getTime()); // 获取日期时间的年、月、日、时、分、秒 int year = currentCalendar.get(Calendar.YEAR); int month = currentCalendar.get(Calendar.MONTH) + 1; // 月份从0开始,需要加1 int day = currentCalendar.get(Calendar.DAY_OF_MONTH); int hour = currentCalendar.get(Calendar.HOUR_OF_DAY); int minute = currentCalendar.get(Calendar.MINUTE); int second = currentCalendar.get(Calendar.SECOND); System.out.println("年: " + year + ", 月: " + month + ", 日: " + day); System.out.println("时: " + hour + ", 分: " + minute + ", 秒: " + second); // 设置日期时间的年、月、日、时、分、秒 currentCalendar.set(Calendar.YEAR, 2022); currentCalendar.set(Calendar.MONTH, 0); // 月份从0开始,0表示1月 currentCalendar.set(Calendar.DAY_OF_MONTH, 1); currentCalendar.set(Calendar.HOUR_OF_DAY, 12); currentCalendar.set(Calendar.MINUTE, 30); currentCalendar.set(Calendar.SECOND, 0); System.out.println("设置后的日期时间: " + currentCalendar.getTime()); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值