【Java 8 新特性】Java Clock 详解

本页将介绍Java Clock的例子。

Clock属于java.time包。

ClockJava 8开始可用,Java 8不带纳秒,Java 9有纳秒,博主采用的Java 8 输出略有差异。例如:

2021-06-10T06:33:38.860249300Z //Java 9
2021-06-10T06:33:38.860Z //Java 8

Clock提供了使用时区和最佳可用系统时钟访问当前的瞬间、日期和时间。

我们可以使用Clock来代替使用System.currentTimeMillis()TimeZone.getDefault()方法。

Clock提供了不同的方法来获取当前的瞬时、日期和时间。

例如,instant()方法返回即时时间。

systemDefaultZone使用默认时区返回当前即时时间。

systemUTC()使用UTC时区返回当前即时时间。

system 给出指定时区的时钟。

offset 给出在添加了指定的持续时间后返回即时的时钟。

tick 给出返回瞬时的时钟,从指定的时钟截断到最接近指定持续时间的出现。

systemDefaultZone

systemDefaultZone 方法签名。

public static Clock systemDefaultZone() 

systemDefaultZone 是一个静态方法,它让 Clock 使用默认时区返回当前时刻。

我们可以如下使用它。

Clock clock = Clock.systemDefaultZone(); 

我们可以使用ZoneId.systemDefault()Clock.system实现同样的行为,如下所示。

clock = Clock.system(ZoneId.systemDefault()); 

millis

millis方法的签名。

public long millis() 

millis 返回从 1970-01-01T00:00Z (UTC) 到开始测量的时钟的当前毫秒时刻。

对于高性能用例,我们应该使用millis

millis 的值等价于 System.currentTimeMillis()

import java.time.Clock;

public class MillisExample {
   public static void main(String[] args) {
 	Clock clock = Clock.systemDefaultZone();
	System.out.println(clock.millis());
   }
} 

输出

1623306818883

instant

Instant() 方法返回 Instant 对象。

Instant 是时间线上的一个瞬时点。

Instant() 返回由时钟定义的当前 Instant

import java.time.Clock;
import java.time.Instant;

public class InstantExample {
  public static void main(String[] args) {
     Clock clock = Clock.systemDefaultZone();
     Instant instant = clock.instant();
     System.out.println(instant);
  }
} 

输出

2021-06-10T06:33:38.860Z

offset

offset 方法的签名。

public static Clock offset(Clock baseClock, Duration offsetDuration) 

offset静态方法提供一个时钟,该时钟从指定的基本时钟返回即时,并添加了指定的持续时间。

如果持续时间为负,则获得的时钟时刻将早于给定的基本时钟。

使用offset,我们可以获得给定基本时钟的过去和未来时刻。

如果我们传递零持续时间,那么我们将获得与给定基本时钟相同的时钟。

import java.time.Clock;
import java.time.Duration;

public class OffsetExample {
   public static void main(String[] args) {
	Clock baseClock = Clock.systemDefaultZone();
		
        //Obtained clock will be later than baseClock
	Clock clock = Clock.offset(baseClock, Duration.ofHours(120));
	System.out.println(clock.instant());

	//Obtained clock will be earlier than baseClock		
	clock = Clock.offset(baseClock, Duration.ofHours(-120));
	System.out.println(clock.instant());
		
	//Obtained clock will be same as baseClock			
	clock = Clock.offset(baseClock, Duration.ZERO);
	System.out.println(clock.instant());
   }
} 

输出

2021-06-15T06:37:37.213Z
2021-06-05T06:37:37.250Z
2021-06-10T06:37:37.250Z

system

system 方法的签名。

public static Clock system(ZoneId zone) 

system 是一个静态方法,它返回给定 ZoneIdClock 对象。

现在这个时钟对象将使用指定的时区给出当前时刻。

下面是区域编码为 Asia/Shanghaisystem 方法示例。

import java.time.Clock;
import java.time.ZoneId;

public class SystemExample {
  public static void main(String[] args) {
  		ZoneId zone = ZoneId.of("Asia/Shanghai");
        Clock c = Clock.system(zone);
        System.out.println(c.instant());
        ZonedDateTime zdt = c.instant().atZone(c.getZone());
        System.out.println("给定区域的日期时间是: " + zdt.toString());
  }
} 

输出

2021-06-10T07:01:54.876Z
给定区域的日期时间是: 2021-06-10T15:01:54.901+08:00[Asia/Shanghai]

systemUTC

systemUTC() 返回使用 UTC 时区给出当前时刻的时钟。

import java.time.Clock;

public class SystemUTCExample {
  public static void main(String[] args) {
	 Clock clock = Clock.systemUTC();
	 System.out.println(clock.instant());
  }
} 

输出

2021-06-10T07:04:14.855Z

tick

tick 方法的签名。

public static Clock tick(Clock baseClock, Duration tickDuration) 

tick返回使用指定基础时钟的时钟。

这个时钟将提供最接近于指定持续时间的时刻。

时钟持续时间必须是正数。

import java.time.Clock;
import java.time.Duration;

public class TickExample {
  public static void main(String[] args) {
	Clock baseClock = Clock.systemDefaultZone();
	Clock clock = Clock.tick(baseClock, Duration.ofMillis(3));

	for(int i= 0; i < 5; i++) {
    	    System.out.println(clock.instant());
    	    try {
		Thread.sleep(2);
	    } catch (InterruptedException e) {
		e.printStackTrace();
	    }
	}
  }
} 

毫秒时间段相差必然是3 的乘积。

输出

2021-06-10T07:08:54.732Z
2021-06-10T07:08:54.762Z
2021-06-10T07:08:54.765Z
2021-06-10T07:08:54.768Z
2021-06-10T07:08:54.771Z

tickMillis

tickMillis 方法的签名。

public static Clock tickMillis(ZoneId zone) 

这个方法是在Java 9中引入的,它返回给定时区的时钟。

这个时钟将以整毫秒为单位。

纳秒字段将被截断为毫秒。

tickMillis的功能也可以通过tick方法实现。

Clock clock = Clock.tickMillis(zoneId); 

使用tick 可以实现相同的效果,如下所示。

Clock clock = Clock.tick(Clock.system(zoneId), Duration.ofMillis(1)); 

tickMillis 示例。

import java.time.Clock;
import java.time.ZoneId;

public class TickMillisExample {
   public static void main(String[] args) {
	   ZoneId zoneId = ZoneId.of("Asia/Shanghai");
	   Clock clock = Clock.tickMillis(zoneId);
	   for(int i= 0; i < 5; i++) {
	        System.out.println(clock.instant());
	    	try {
			Thread.sleep(2);
	        } catch (InterruptedException e) {
			e.printStackTrace();
		}
	   }
    }
} 

输出

2021-06-10T07:16:35.726Z
2021-06-10T07:16:35.775Z
2021-06-10T07:16:35.780Z
2021-06-10T07:16:35.787Z
2021-06-10T07:16:35.790Z

tickSeconds

tickSeconds 方法的签名。

public static Clock tickSeconds(ZoneId zone) 

tickSeconds给出了一个指定时区的时钟。

这个时钟将以整秒为单位返回当前瞬间的tickSeconds

纳秒字段将被设置为零。

tickSeconds的功能也可以通过tick方法实现。

找到使用tickSeconds的代码片段。

Clock clock = Clock.tickSeconds(zoneId); 

使用tick 可以实现相同的效果,如下所示。

Clock clock = Clock.tick(Clock.system(zoneId), Duration.ofSeconds(1)); 

tickSeconds 示例。

import java.time.Clock;
import java.time.ZoneId;

public class TickMillisExample {
   public static void main(String[] args) {
	   ZoneId zoneId = ZoneId.of("Asia/Shanghai");
	   Clock clock = Clock.tickSeconds(zoneId);
	   for(int i= 0; i < 5; i++) {
	      System.out.println(clock.instant());
	      try {
	 	  Thread.sleep(2000);
	      } catch (InterruptedException e) {
		  e.printStackTrace();
	      }
	   }
    }
} 

输出

2021-06-10T07:21:17Z
2021-06-10T07:21:19Z
2021-06-10T07:21:21Z
2021-06-10T07:21:23Z
2021-06-10T07:21:25Z

tickMinutes

tickMinutes 方法的签名。

public static Clock tickMinutes(ZoneId zone) 

tickMinutes 给出指定时区的时钟。

该时钟将在整分钟内立即返回。

Nano-of-secondsecond-of-minute 字段将设置为零。

我们将在整分钟内获得所有ticks

tickMinutes 的功能也可以通过 tick 方法来实现。

使用 tickMinutes 查找代码片段。

Clock clock = Clock.tickMinutes(zoneId); 

使用tick 可以实现相同的效果,如下所示。

Clock clock = Clock.tick(Clock.system(zoneId), Duration.ofMinutes(1)); 

tickMinutes 示例。

import java.time.Clock;
import java.time.ZoneId;

public class TickMinutesExample {
   public static void main(String[] args) {
      ZoneId zoneId = ZoneId.of("Asia/Shanghai");
      Clock clock = Clock.tickMinutes(zoneId);
      for(int i= 0; i < 3; i++) {
	 System.out.println(clock.instant());
	 try {
		Thread.sleep(90000);
	 } catch (InterruptedException e) {
	        e.printStackTrace();
 	 }
      }
   }
} 

输出

2021-06-10T07:26:00Z
2021-06-10T07:27:00Z
2021-06-10T07:28:00Z

fixed

fixed 方法的签名。

public static Clock fixed(Instant fixedInstant, ZoneId zone) 

fixed 方法总是返回指定的相同时刻。

它在测试中很有用。 ZoneId 提供用于将即时转换为日期时间的时区。

查找示例示例以使用fixed 方法。

import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;

public class FixedExample {
   public static void main(String[] args) {
	Instant instant = Instant.parse("2021-06-08T15:16:17.00Z");
	ZoneId zoneId = ZoneId.of("Asia/Shanghai");
	Clock clock = Clock.fixed(instant, zoneId);
	System.out.println(clock.instant());
   }
} 

输出

2021-06-08T15:16:17Z

withZone

withZone(ZoneId zone) 返回具有不同时区的时钟副本。

如果我们有一个时区的时钟实例,我们可以使用 withZone 方法为不同的时区制作该时钟的副本。

import java.time.Clock;
import java.time.ZoneId;

public class WithZoneExample {
  public static void main(String[] args) {
	ZoneId zone1 = ZoneId.of("Asia/Aden");   
	Clock clock1 = Clock.system(zone1);  
	System.out.println(clock1.instant());
	
	ZoneId zone2 = ZoneId.of("America/Cuiaba"); 
	Clock clock2 = clock1.withZone(zone2);
	System.out.println(clock2.instant());	
  }
} 

输出

2021-06-10T07:35:06.110Z
2021-06-10T07:35:06.136Z

getZone

getZone() 给出用于创建日期和时间的时区。

import java.time.Clock;
import java.time.ZoneId;

public class GetZoneExample {
  public static void main(String[] args) {
	Clock clock = Clock.systemDefaultZone();
	ZoneId zone = clock.getZone();
	System.out.println(zone.getId());
  }
} 

输出

Asia/Shanghai

equals

equals 方法检查两个时钟是否相等。

import java.time.Clock;

public class EqualsExample {
  public static void main(String[] args) {
	Clock clock = Clock.systemDefaultZone();
        System.out.println(clock.equals(Clock.systemDefaultZone()));
	System.out.println(clock.equals(Clock.systemUTC()));
  }
} 

输出

true
false 

参考文献

【1】Class Clock
【2】Java Clock

### Java 8 新特性及详细介绍 #### 接口的默认方法和静态方法 Java 8 引入了接口中的默认方法和静态方法的概念。这使得可以在不破坏现有实现类的情况下向接口添加新功能[^1]。 ```java public interface MyInterface { default void myDefaultMethod() { System.out.println("This is a default method."); } static void myStaticMethod() { System.out.println("This is a static method in an interface."); } } ``` #### Lambda 表达式 Lambda表达式的引入简化了匿名内部类的编写方式,提高了代码可读性和简洁度[^2]。 ```java // 使用匿名内部类的方式 button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Button clicked"); } }); // 使用lambda表达式的方式 button.addActionListener(e -> System.out.println("Button clicked")); ``` #### Stream API Stream API 提供了一种高效且易于理解的方式来处理集合数据结构。它可以链式调用多个操作来完成复杂的数据查询任务[^3]。 ```java List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); names.stream() .filter(name -> name.startsWith("A")) .forEach(System.out::println); ``` #### 新的时间日期API (java.time) 为了改善旧版`Date`和`Calendar`类存在的诸多问题,Java 8 增加了一个全新的时间日期库位于`java.time`包下。这个新的API设计得更为直观合理[^4]。 ```java LocalDateTime now = LocalDateTime.now(); System.out.println("Current Date and Time: " + now); Clock clock = Clock.systemUTC(); Instant instant = Instant.now(clock); System.out.println("Current Instant: " + instant); ``` #### Optional 类型 `Optional<T>` 是一个容器对象用于表示可能存在也可能不存在的值。其目的是为了避免程序中出现大量的null检查语句以及由此引发的NullPointerException异常[^5]。 ```java Optional<String> optionalValue = Optional.ofNullable(null); optionalValue.ifPresentOrElse( value -> System.out.println("Value present: " + value), () -> System.out.println("No value present") ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫巳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值