文章目录
Java8新特性二
了解Fork/Join框架
Fork/Join框架:就是在必要的情况下,将一个大任务进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个小任务的结果进行join汇总。
Fork/Join框架与线程池的区别
采用“工作窃取”模式
当执行新的任务时,它可以将其拆分成更小的任务执行,并将小任务添加到线程队列中,当一个线程在执行任务时获取不到时,从一个随机的线程队列末尾偷一个并把它放在自己的队列中。
import java.util.concurrent.RecursiveTask;
//RecursiveTask有返回值
//RecursiveAcation没有返回值
//Recursive是递归的意思
public class ForkJoinCalculate extends RecursiveTask<Long> {
private long start;
private long end;
private final long THRESHOLD = 10000;
public ForkJoinCalculate(long start, long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long len = end -start;
if(len<=THRESHOLD)
{
long sum = 0;
for(long i = start;i<=end;i++)
{
sum+=i;
}
return sum;
}
else
{
long middle = (start+end)/2;
ForkJoinCalculate left = new ForkJoinCalculate(start,middle);
left.fork();//拆分子任务,同时压入线程队列
ForkJoinCalculate right = new ForkJoinCalculate(middle+1,end);
right.fork();
return left.join()+right.join();
}
}
}
import org.junit.Test;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
/**
* @ClassName TestForkJoin
* @Description: TODO
* @Author renjie
* @Date 2021/5/20
**/
public class TestForkJoin {
@Test
public void test()
{
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinCalculate(0,100000000L);
Long sum = pool.invoke(task);
System.out.println(sum);
}
}
Java8并行流
import org.junit.Test;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
/**
* @ClassName TestForkJoin
* @Description: TODO
* @Author renjie
* @Date 2021/5/20
**/
public class TestForkJoin {
/**
* Java8并行流
*/
@Test
public void test1()
{
Instant start = Instant.now();
//串行流
LongStream.rangeClosed(0,100000000000L)
.reduce(0,Long::sum);
Instant end = Instant.now();
System.out.println("串行流耗费时间为:"+ Duration.between(start,end).toMillis());
start = Instant.now();
//并行流
LongStream.rangeClosed(0,100000000000L)
.parallel()
.reduce(0,Long::sum);
end = Instant.now();
System.out.println("并行流耗费时间为:"+ Duration.between(start,end).toMillis());
}
}
输出
串行流耗费时间为:38956
并行流耗费时间为:13387
Optional类
Optional容器类的常用方法:
- Optional.of(T t):创建一个Optional实例
- Optional.empty():创建一个空的Optional实例
- Optional.ofNullable(T t):若t不为null,创建Optional实例,否则创建空实例
- isPresent():判断是否包含值
- orElse(T t):如果调用对象包含值,返回该值,否则返回s获取的值。
- map(Function f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
- flatMap(Function mapper):与map类似,要求返回值必须是Optional
示例
public class TestOptional {
@Test
public void test()
{
Optional<Employee> op = Optional.of(new Employee());
Employee emp = op.get();
System.out.println(emp);
}
}
结果
Employee{name='null', age=0, salary=0.0, status=null}
例子2
public class TestOptional {
@Test
public void test1()
{
Optional<Object> empty = Optional.empty();
System.out.println(empty.get());
}
}
结果:抛出异常
java.util.NoSuchElementException: No value present
例子3
public class TestOptional {
@Test
public void test1()
{
Optional<Object> empty = Optional.empty();
//判断是否包含值
if(empty.isPresent())
{
System.out.println(empty.get());
}
else
System.out.println("啥都没有");
}
}
输出
啥都没有
例子4
有则获取,没有则替换
public class TestOptional {
@Test
public void test3()
{
Optional<Employee> op = Optional.ofNullable(new Employee());
Employee employee = op.orElse(new Employee("sss",20,1111.11,Employee.Status.BUSY));
System.out.println(employee);
}
}
输出
Employee{name='null', age=0, salary=0.0, status=null}
例子5
public class TestOptional {
@Test
public void test4()
{
Optional<Employee> op = Optional.ofNullable(new Employee("sss",20,1111.11,Employee.Status.BUSY));
Optional<String> str = op.map(Employee::getName);
System.out.println(str.get());
}
}
输出
sss
例子6
flatMap返回的必须是Optional 进一步避免空指针异常。
public class TestOptional {
@Test
public void test5()
{
Optional<Employee> op = Optional.ofNullable(new Employee("sss",20,1111.11,Employee.Status.BUSY));
Optional<String> str = op.flatMap((e)->Optional.of(e.getName()));
System.out.println(str.get());
}
}
输出
sss
例子7
class NewMan {
private Optional<Godness> godness = Optional.empty();
public NewMan() {
}
@Override
public String toString() {
return "NewMan{" +
"godness=" + godness +
'}';
}
public Optional<Godness> getGodness() {
return godness;
}
public void setGodness(Optional<Godness> godness) {
this.godness = godness;
}
public NewMan(Optional<Godness> godness) {
this.godness = godness;
}
}
public class TestOptional {
@Test
public void test6()
{
Optional<NewMan> op = Optional.ofNullable(null);
String str = getGodnessName(op);
System.out.println(str);
}
private String getGodnessName(Optional<NewMan> man) {
return man.orElse(new NewMan())
.getGodness()
.orElse(new Godness("Miss Li"))
.getName();
}
}
输出
Miss Li
接口中的默认方法与静态方法
以前接口中只可以有全局静态常量和抽象方法。
现在还可以有默认方法。使用default修饰符。
java8中允许接口包含具有具体实现的方法,该方法称为“默认方法”,默认方法使用default关键词修饰。
也允许包含静态方法
例如:
public interface MyFunc<T> {
T MyFunc(int a);
default String getName()
{
return "hello java8";
}
static int getAge()
{
return 18;
}
}
接口默认方法的“类优先”原则
若一个接口中定义了一个默认方法,而另外一个父类或接口中又定义了一个同名的方法时。
- 选择父类中的方法。如果一个父类提供了一个具体的实现,那么接口中具有相同名称和参数的默认方法会被忽略。
- 接口冲突,如果一个父接口提供了一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认),那么必须覆盖该方法来解决冲突。
新时间API
之前的时间相关的类:
- Date
- Calendar:每周第一天默认从星期日开始,是可变的,线程不安全,格式化日期用SimpleDateFormat
新的时间API
不可变,不管怎么变都会产生新的实例。
- 1、java.time下面的众多类,如LocalDate、LocalTime等,时间戳Instant
- 2、时间日期格式化,java.time.format包下的类
旧API中SimpleDateFormat存在的线程安全问题
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
/**
* @ClassName TestSimpleDateFormat
* @Description: TODO
* @Author renjie
* @Date 2021/5/22
**/
public class TestSimpleDateFormat {
public static void main(String[] args) throws ExecutionException, InterruptedException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return sdf.parse("20161218");
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<Date>> result = new ArrayList<>();
for (int i = 0 ;i<10;i++) {
result.add(pool.submit(task));
}
for(Future<Date> future:result)
{
System.out.println(future.get());
}
}
}
结果
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NumberFormatException: multiple points
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at TestSimpleDateFormat.main(TestSimpleDateFormat.java:32)
Caused by: java.lang.NumberFormatException: multiple points
java.lang.NumberFormatException: multiple points问题
一般这种问题主要是因为SimpleDateFormat在多线程环境下,是线程不安全的,所以如果你在多线程环境中共享了SimpleDateFormat的实例,比如你在类似日期类中定义了一个全局的SimpleDateFormat对象,这样子肯定会出现上述的报错。
使用ThreadLocal进行改进
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
class DateFormatThreadLocal {
public static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
public static Date convert(String source) throws ParseException {
return df.get().parse(source);
}
}
public class TestDateFormatThreadLocal {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return DateFormatThreadLocal.convert("20161218");
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<Date>> result = new ArrayList<>();
for (int i = 0 ;i<10;i++) {
result.add(pool.submit(task));
}
for(Future<Date> future:result)
{
System.out.println(future.get());
}
pool.shutdown();
}
}
输出
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
Sun Dec 18 00:00:00 CST 2016
新时间日期API
LocalDate、LocalTime、LocalDateTime
使用LocalDate、LocalTime、LocalDateTime
- LocalDate、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。
注:ISO-8601日历系统说国际标准化组织制定的现代公民的日期和时间的表示法。
import org.junit.Test;
import java.time.LocalDateTime;
/**
* @ClassName TestLocalDateTime
* @Description: TODO
* @Author renjie
* @Date 2021/5/22
**/
public class TestLocalDateTime {
@Test
public void test()
{
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
LocalDateTime ldt2 = LocalDateTime.of(2021,5,22,14,20,16);
System.out.println(ldt2);
LocalDateTime ldt3 = ldt2.plusYears(2);
System.out.println(ldt3);
LocalDateTime ldt4 = ldt3.minusMonths(2);
System.out.println(ldt4);
System.out.println(ldt4.getYear());
System.out.println(ldt4.getMonthValue());
System.out.println(ldt4.getDayOfMonth());
System.out.println(ldt4.getHour());
System.out.println(ldt4.getMinute());
System.out.println(ldt4.getSecond());
}
}
从上面可以看出,不管做什么样的改变都会拿到一个新的实例。
输出
2021-05-22T14:41:39.915
2021-05-22T14:20:16
2023-05-22T14:20:16
2023-03-22T14:20:16
2023
3
22
14
20
16
Instant:时间戳
以Unix元年:1970年1月1日00:00:00到某个时间之间的毫秒值。
import org.junit.Test;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
/**
* @ClassName TestLocalDateTime
* @Description: TODO
* @Author renjie
* @Date 2021/5/22
**/
public class TestLocalDateTime {
@Test
public void test2()
{
Instant ins1 = Instant.now(); //默认获取UTC时区
System.out.println(ins1);
//将日期格式转换成时间戳格式
System.out.println(ins1.toEpochMilli());
//带偏移量的时间日期
OffsetDateTime odt = ins1.atOffset(ZoneOffset.ofHours(2));
System.out.println(odt);
//将秒转换为日期格式
Instant instant = Instant.ofEpochSecond(61);
System.out.println(instant);
}
}
输出
2021-05-22T06:57:26.394Z
1621666646394
2021-05-22T08:57:26.394+02:00
1970-01-01T00:01:01Z
计算时间间隔、日期间隔
Duration:计算两个"时间"之间的间隔
public class TestLocalDateTime {
@Test
public void test4()
{
//默认获取etc时区
Instant ins1 = Instant.now();
try {
Thread.sleep(1000);
}
catch (Exception e)
{
}
Instant ins2 = Instant.now();
Duration between = Duration.between(ins1, ins2);
System.out.println(between.toMillis());
}
}
输出
1003
Period:计算两个日期之间的间隔
import org.junit.Test;
import java.time.*;
public class TestLocalDateTime {
@Test
public void test5()
{
LocalDate ld1 = LocalDate.of(2015,1,1);
LocalDate ld2 = LocalDate.now();
Period period = Period.between(ld1,ld2);
//P6Y4M21D表示period 1Year 4Month 21Day
System.out.println(period);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
}
}
输出
P6Y4M21D
6
4
21
日期操作TemporalAdjusters
- TemporalAdjuster:时间矫正器,有时我们可能获取例如:将日期调整到“下个周日”等操作
- TemporalAdjusters:该类通过静态方法提供了大量的常用TemporalAdjuster的实现
import org.junit.Test;
import java.time.*;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
public class TestLocalDateTime {
//时间矫正器
@Test
public void test6()
{
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
//将日期指定成10号
LocalDateTime ldt2 = ldt.withDayOfMonth(10);
System.out.println(ldt2);
//将日期修改为下一个sunday
LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(ldt3);
//自定义:下一个工作日
LocalDateTime ldt5 = ldt.with(l->
{
LocalDateTime ldt4 = (LocalDateTime) l;
DayOfWeek dow = ldt4.getDayOfWeek();
if(dow.equals(DayOfWeek.FRIDAY))
return ldt4.plusDays(3);
else if(dow.equals(DayOfWeek.SATURDAY))
return ldt4.plusDays(2);
else
return ldt4.plusDays(1);
});
System.out.println(ldt5);
}
}
格式化时间/日期:DateTimeFormatter
public class TestLocalDateTime {
//DateTimeFormatter:格式化时间/日期
@Test
public void test7()
{
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE;
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
String format = ldt.format(dtf);
System.out.println(format);
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
String format2 = ldt.format(dtf2);
System.out.println(format2);
//将字符串转换为LocalDateTime
LocalDateTime res = ldt.parse(format2,dtf2);
System.out.println(res);
}
}
输出
2021-05-22T16:11:58.470
2021-05-22
2021年05月22日 16:11:58
2021-05-22T16:11:58
时区的处理
public class TestLocalDateTime {
@Test
public void test8()
{
Set<String> set = ZoneId.getAvailableZoneIds();
set.forEach(System.out::print);
}
}
输出
Asia/AdenAmerica/CuiabaEtc/GMT+9Etc/GMT+8Africa/NairobiAmerica/MarigotAsia/AqtauPacific/KwajaleinAmerica/El_SalvadorAsia/PontianakAfrica/CairoPacific/Pago_PagoAfrica/MbabaneAsia/KuchingPacific/HonoluluPacific/RarotongaAmerica/GuatemalaAustralia/HobartEurope/LondonAmerica/BelizeAmerica/PanamaAsia/ChungkingAmerica/ManaguaAmerica/Indiana/PetersburgAsia/YerevanEurope/BrusselsGMTEurope/WarsawAmerica/ChicagoAsia/KashgarChile/ContinentalPacific/YapCETEtc/GMT-1Etc/GMT-0Europe/JerseyAmerica/TegucigalpaEtc/GMT-5Europe/IstanbulAmerica/EirunepeEtc/GMT-4America/MiquelonEtc/GMT-3Europe/LuxembourgEtc/GMT-2Etc/GMT-9America/Argentina/CatamarcaEtc/GMT-8Etc/GMT-7Etc/GMT-6Europe/ZaporozhyeCanada/YukonCanada/AtlanticAtlantic/St_HelenaAustralia/TasmaniaLibyaEurope/GuernseyAmerica/Grand_TurkUS/Pacific-NewAsia/SamarkandAmerica/Argentina/CordobaAsia/Phnom_PenhAfrica/KigaliAsia/AlmatyUS/AlaskaAsia/DubaiEurope/Isle_of_ManAmerica/AraguainaCubaAsia/NovosibirskAmerica/Argentina/SaltaEtc/GMT+3Africa/TunisEtc/GMT+2Etc/GMT+1Pacific/FakaofoAfrica/TripoliEtc/GMT+0IsraelAfrica/BanjulEtc/GMT+7Indian/ComoroEtc/GMT+6Etc/GMT+5Etc/GMT+4Pacific/Port_MoresbyUS/ArizonaAntarctica/SyowaIndian/ReunionPacific/PalauEurope/KaliningradAmerica/MontevideoAfrica/WindhoekAsia/KarachiAfrica/MogadishuAustralia/PerthBrazil/EastEtc/GMTAsia/ChitaPacific/EasterAntarctica/DavisAntarctica/McMurdoAsia/MacaoAmerica/ManausAfrica/FreetownEurope/BucharestAsia/TomskAmerica/Argentina/MendozaAsia/MacauEurope/MaltaMexico/BajaSurPacific/TahitiAfrica/AsmeraEurope/BusingenAmerica/Argentina/Rio_GallegosAfrica/MalaboEurope/SkopjeAmerica/CatamarcaAmerica/GodthabEurope/SarajevoAustralia/ACTGB-EireAfrica/LagosAmerica/CordobaEurope/RomeAsia/DaccaIndian/MauritiusPacific/SamoaAmerica/ReginaAmerica/Fort_WayneAmerica/Dawson_CreekAfrica/AlgiersEurope/MariehamnAmerica/St_JohnsAmerica/St_ThomasEurope/ZurichAmerica/AnguillaAsia/DiliAmerica/DenverAfrica/BamakoEurope/SaratovGBMexico/GeneralPacific/WallisEurope/GibraltarAfrica/ConakryAfrica/LubumbashiAsia/IstanbulAmerica/HavanaNZ-CHATAsia/ChoibalsanAmerica/Porto_AcreAsia/OmskEurope/VaduzUS/MichiganAsia/DhakaAmerica/BarbadosEurope/TiraspolAtlantic/Cape_VerdeAsia/YekaterinburgAmerica/LouisvillePacific/JohnstonPacific/ChathamEurope/LjubljanaAmerica/Sao_PauloAsia/JayapuraAmerica/CuracaoAsia/DushanbeAmerica/GuyanaAmerica/GuayaquilAmerica/MartiniquePortugalEurope/BerlinEurope/MoscowEurope/ChisinauAmerica/Puerto_RicoAmerica/Rankin_InletPacific/PonapeEurope/StockholmEurope/BudapestAmerica/Argentina/JujuyAustralia/EuclaAsia/ShanghaiUniversalEurope/ZagrebAmerica/Port_of_SpainEurope/HelsinkiAsia/BeirutAsia/Tel_AvivPacific/BougainvilleUS/CentralAfrica/Sao_TomeIndian/ChagosAmerica/CayenneAsia/YakutskPacific/GalapagosAustralia/NorthEurope/ParisAfrica/NdjamenaPacific/FijiAmerica/Rainy_RiverIndian/MaldivesAustralia/YancowinnaSystemV/AST4Asia/OralAmerica/YellowknifePacific/EnderburyAmerica/JuneauAustralia/VictoriaAmerica/Indiana/VevayAsia/TashkentAsia/JakartaAfrica/CeutaAsia/BarnaulAmerica/RecifeAmerica/Buenos_AiresAmerica/NoronhaAmerica/Swift_CurrentAustralia/AdelaideAmerica/MetlakatlaAfrica/DjiboutiAmerica/ParamariboEurope/SimferopolEurope/SofiaAfrica/NouakchottEurope/PragueAmerica/Indiana/VincennesAntarctica/MawsonAmerica/KralendijkAntarctica/TrollEurope/SamaraIndian/ChristmasAmerica/AntiguaPacific/GambierAmerica/IndianapolisAmerica/InuvikAmerica/IqaluitPacific/FunafutiUTCAntarctica/MacquarieCanada/PacificAmerica/MonctonAfrica/GaboronePacific/ChuukAsia/PyongyangAmerica/St_VincentAsia/GazaEtc/UniversalPST8PDTAtlantic/FaeroeAsia/QyzylordaCanada/NewfoundlandAmerica/Kentucky/LouisvilleAmerica/YakutatAsia/Ho_Chi_MinhAntarctica/CaseyEurope/CopenhagenAfrica/AsmaraAtlantic/AzoresEurope/ViennaROKPacific/PitcairnAmerica/MazatlanAustralia/QueenslandPacific/NauruEurope/TiraneAsia/KolkataSystemV/MST7Australia/CanberraMETAustralia/Broken_HillEurope/RigaAmerica/DominicaAfrica/AbidjanAmerica/MendozaAmerica/SantaremKwajaleinAmerica/AsuncionAsia/Ulan_BatorNZAmerica/BoiseAustralia/CurrieEST5EDTPacific/GuamPacific/WakeAtlantic/BermudaAmerica/Costa_RicaAmerica/DawsonAsia/ChongqingEireEurope/AmsterdamAmerica/Indiana/KnoxAmerica/North_Dakota/BeulahAfrica/AccraAtlantic/FaroeMexico/BajaNorteAmerica/MaceioEtc/UCTPacific/ApiaGMT0America/AtkaPacific/NiueAustralia/Lord_HoweEurope/DublinPacific/TrukMST7MDTAmerica/MonterreyAmerica/NassauAmerica/JamaicaAsia/BishkekAmerica/AtikokanAtlantic/StanleyAustralia/NSWUS/HawaiiSystemV/CST6Indian/MaheAsia/AqtobeAmerica/SitkaAsia/VladivostokAfrica/LibrevilleAfrica/MaputoZuluAmerica/Kentucky/MonticelloAfrica/El_AaiunAfrica/OuagadougouAmerica/Coral_HarbourPacific/MarquesasBrazil/WestAmerica/ArubaAmerica/North_Dakota/CenterAmerica/CaymanAsia/UlaanbaatarAsia/BaghdadEurope/San_MarinoAmerica/Indiana/Tell_CityAmerica/TijuanaPacific/SaipanSystemV/YST9Africa/DoualaAmerica/ChihuahuaAmerica/OjinagaAsia/HovdAmerica/AnchorageChile/EasterIslandAmerica/HalifaxAntarctica/RotheraAmerica/Indiana/IndianapolisUS/MountainAsia/DamascusAmerica/Argentina/San_LuisAmerica/SantiagoAsia/BakuAmerica/Argentina/UshuaiaAtlantic/ReykjavikAfrica/BrazzavilleAfrica/Porto-NovoAmerica/La_PazAntarctica/DumontDUrvilleAsia/TaipeiAntarctica/South_PoleAsia/ManilaAsia/BangkokAfrica/Dar_es_SalaamPolandAtlantic/MadeiraAntarctica/PalmerAmerica/Thunder_BayAfrica/Addis_AbabaAsia/YangonEurope/UzhgorodBrazil/DeNoronhaAsia/AshkhabadEtc/ZuluAmerica/Indiana/MarengoAmerica/CrestonAmerica/Punta_ArenasAmerica/Mexico_CityAntarctica/VostokAsia/JerusalemEurope/AndorraUS/SamoaPRCAsia/VientianePacific/KiritimatiAmerica/MatamorosAmerica/Blanc-SablonAsia/RiyadhIcelandPacific/PohnpeiAsia/Ujung_PandangAtlantic/South_GeorgiaEurope/LisbonAsia/HarbinEurope/OsloAsia/NovokuznetskCST6CDTAtlantic/CanaryAmerica/Knox_INAsia/KuwaitSystemV/HST10Pacific/EfateAfrica/LomeAmerica/BogotaAmerica/MenomineeAmerica/AdakPacific/NorfolkEurope/KirovAmerica/ResolutePacific/TarawaAfrica/KampalaAsia/KrasnoyarskGreenwichSystemV/EST5America/EdmontonEurope/PodgoricaAustralia/SouthCanada/CentralAfrica/BujumburaAmerica/Santo_DomingoUS/EasternEurope/MinskPacific/AucklandAfrica/CasablancaAmerica/Glace_BayCanada/EasternAsia/QatarEurope/KievSingaporeAsia/MagadanSystemV/PST8America/Port-au-PrinceEurope/BelfastAmerica/St_BarthelemyAsia/AshgabatAfrica/LuandaAmerica/NipigonAtlantic/Jan_MayenBrazil/AcreAsia/MuscatAsia/BahrainEurope/VilniusAmerica/FortalezaEtc/GMT0US/East-IndianaAmerica/HermosilloAmerica/CancunAfrica/MaseruPacific/KosraeAfrica/KinshasaAsia/KathmanduAsia/SeoulAustralia/SydneyAmerica/LimaAustralia/LHIAmerica/St_LuciaEurope/MadridAmerica/Bahia_BanderasAmerica/MontserratAsia/BruneiAmerica/Santa_IsabelCanada/MountainAmerica/Cambridge_BayAsia/ColomboAustralia/WestIndian/AntananarivoAustralia/BrisbaneIndian/MayotteUS/Indiana-StarkeAsia/UrumqiUS/AleutianEurope/VolgogradAmerica/Lower_PrincesAmerica/VancouverAfrica/BlantyreAmerica/Rio_BrancoAmerica/DanmarkshavnAmerica/DetroitAmerica/ThuleAfrica/LusakaAsia/Hong_KongIranAmerica/Argentina/La_RiojaAfrica/DakarSystemV/CST6CDTAmerica/TortolaAmerica/Porto_VelhoAsia/SakhalinEtc/GMT+10America/ScoresbysundAsia/KamchatkaAsia/ThimbuAfrica/HarareEtc/GMT+12Etc/GMT+11NavajoAmerica/NomeEurope/TallinnTurkeyAfrica/KhartoumAfrica/JohannesburgAfrica/BanguiEurope/BelgradeJamaicaAfrica/BissauAsia/TehranWETEurope/AstrakhanAfrica/JubaAmerica/Campo_GrandeAmerica/BelemEtc/GreenwichAsia/SaigonAmerica/EnsenadaPacific/MidwayAmerica/JujuyAfrica/TimbuktuAmerica/BahiaAmerica/Goose_BayAmerica/VirginAmerica/PangnirtungAsia/KatmanduAmerica/PhoenixAfrica/NiameyAmerica/WhitehorsePacific/NoumeaAsia/TbilisiAmerica/MontrealAsia/MakassarAmerica/Argentina/San_JuanHongkongUCTAsia/NicosiaAmerica/Indiana/WinamacSystemV/MST7MDTAmerica/Argentina/ComodRivadaviaAmerica/Boa_VistaAmerica/GrenadaAsia/AtyrauAustralia/DarwinAsia/KhandygaAsia/Kuala_LumpurAsia/FamagustaAsia/ThimphuAsia/RangoonEurope/BratislavaAsia/CalcuttaAmerica/Argentina/TucumanAsia/KabulIndian/CocosJapanPacific/TongatapuAmerica/New_YorkEtc/GMT-12Etc/GMT-11Etc/GMT-10SystemV/YST9YDTEurope/UlyanovskEtc/GMT-14Etc/GMT-13W-SUAmerica/MeridaEETAmerica/RosarioCanada/SaskatchewanAmerica/St_KittsArctic/LongyearbyenAmerica/Fort_NelsonAmerica/CaracasAmerica/GuadeloupeAsia/HebronIndian/KerguelenSystemV/PST8PDTAfrica/MonroviaAsia/Ust-NeraEgyptAsia/SrednekolymskAmerica/North_Dakota/New_SalemAsia/AnadyrAustralia/MelbourneAsia/IrkutskAmerica/ShiprockAmerica/WinnipegEurope/VaticanAsia/AmmanEtc/UTCSystemV/AST4ADTAsia/TokyoAmerica/TorontoAsia/SingaporeAustralia/LindemanAmerica/Los_AngelesSystemV/EST5EDTPacific/MajuroAmerica/Argentina/Buenos_AiresEurope/NicosiaPacific/GuadalcanalEurope/AthensUS/PacificEurope/Monaco
修改时区
public class TestLocalDateTime {
@Test
public void test9()
{
LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Europe/Tallinn"));
System.out.println(ldt);
LocalDateTime ldt2 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime zdt = ldt2.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zdt);
}
}
输出
2021-05-22T11:28:21.787
2021-05-22T16:28:21.795+08:00[Asia/Shanghai]
+08:00表示与UTC有8小时的时差