欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于java時(shí)區(qū)轉(zhuǎn)換夏令時(shí)的問(wèn)題及解決方法

 更新時(shí)間:2017年11月27日 11:01:35   作者:尚云峰111  
下面小編就為大家分享一篇基于java時(shí)區(qū)轉(zhuǎn)換夏令時(shí)的問(wèn)題及解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

一.準(zhǔn)備知識(shí)

1.America/New_York的夏令時(shí)時(shí)間如下: 包左不包右

2016-3-13, 02:00:00到2016-11-6, 02:00:00 

2017-3-12, 02:00:00到2017-11-5, 02:00:00

2.三字母時(shí)區(qū) ID

為了與 JDK 1.1.x 兼容,一些三字母時(shí)區(qū) ID(比如 "PST"、"CTT"、"AST")也受支持。

但是,它們的使用被廢棄,這是因?yàn)橄嗤目s寫(xiě)經(jīng)常用于多個(gè)時(shí)區(qū)

例如 CST:有4個(gè)意思,美國(guó),澳大利亞,中國(guó),古巴時(shí)間

3.標(biāo)準(zhǔn)

GMT:Green Mean Time格林威治標(biāo)準(zhǔn)時(shí)間,1960年前被作為標(biāo)準(zhǔn)時(shí)間參考 GMT+12-->GMT-12

java8的范圍為GMT+18-->GMT-18

UTC:Coordinated Universal Time 時(shí)間協(xié)調(diào)世界時(shí)間 ,比GMT精確,在1972年1月1日成為新的標(biāo)準(zhǔn);UTC,UTC+1,UTC+2...UTC+12,UTC-12...UTC-1

java8的范圍 UTC-18-->UTC+18

DST:Daylight Saving Time 夏令時(shí)間,指在夏天的時(shí)候,將時(shí)鐘撥快一個(gè)小時(shí),以提早日光的使用,在英國(guó)稱(chēng)為夏令時(shí)間;

目前有110多個(gè)國(guó)家采用夏令時(shí);

在中國(guó),從1986-1992只實(shí)行了6年,之后就取消了;原因如下:

1.中國(guó)東西方向跨度很大,而且采用的是統(tǒng)一的東八區(qū),采用夏令時(shí)無(wú)法兼容東西部;

2.高緯度地區(qū),冬夏晝夜時(shí)間變化大;意義不大;

4.表示東八區(qū)可以用 : GMT+8或者Etc/GMT-8(剛好相反,為什么呢,因?yàn)閜hp開(kāi)發(fā)者認(rèn)為,東八區(qū)比標(biāo)準(zhǔn)時(shí)間快8小時(shí),應(yīng)該減去8小時(shí),于是表示成了這樣。參考的對(duì)象不同導(dǎo)致了不同的表示方法;)

5. 中國(guó)時(shí)區(qū)的表示方式

GMT+8
UTC+8
Asia/Harbin 哈爾濱 //中國(guó)標(biāo)準(zhǔn)時(shí)間
Asia/Chongqing 重慶//中國(guó)標(biāo)準(zhǔn)時(shí)間
Asia/Chungking 重慶//中國(guó)標(biāo)準(zhǔn)時(shí)間
Asia/Urumqi 烏魯木齊//中國(guó)標(biāo)準(zhǔn)時(shí)間
Asia/Shanghai 上海(東8區(qū))//中國(guó)標(biāo)準(zhǔn)時(shí)間
PRC
Asia/Macao 澳門(mén) //中國(guó)標(biāo)準(zhǔn)時(shí)間
Hongkong 香港 //香港時(shí)間跟中國(guó)標(biāo)準(zhǔn)時(shí)間一致
Asia/Hong_Kong 香港
Asia/Taipei 臺(tái)北(臺(tái)灣的) //中國(guó)標(biāo)準(zhǔn)時(shí)間
新加坡跟中國(guó)的時(shí)間一樣;
Asia/Singapore
Singapore

6. 標(biāo)準(zhǔn)時(shí)區(qū)的表示

UTC
UTC+0
UTC-0
GMT 格林尼治標(biāo)準(zhǔn)時(shí)間
GMT0 格林尼治標(biāo)準(zhǔn)時(shí)間
Etc/GMT 格林尼治標(biāo)準(zhǔn)時(shí)間
Etc/GMT+0 格林尼治標(biāo)準(zhǔn)時(shí)間
Etc/GMT-0 格林尼治標(biāo)準(zhǔn)時(shí)間
Etc/GMT0 格林尼治標(biāo)準(zhǔn)時(shí)間
注意:GMT+xx(-xx)有很大的包容性,還可以自動(dòng)的識(shí)別各種時(shí)間的表示

二. 時(shí)區(qū)轉(zhuǎn)換

環(huán)境:java8之前

1.將當(dāng)前時(shí)間轉(zhuǎn)換為指定時(shí)區(qū)顯示

@Test 
public void test() throws Exception { 
 Date a=new Date(); 
 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
 sf.setTimeZone(TimeZone.getTimeZone("America/New_York")); 
 //把中國(guó)時(shí)區(qū)轉(zhuǎn)為了美國(guó)紐約時(shí)區(qū) 
 System.out.println(sf.format(a)); 
} 

2.指定時(shí)間轉(zhuǎn)為指定時(shí)區(qū)顯示

真能正確轉(zhuǎn)換嗎?好像有個(gè)坑,看了看網(wǎng)上的實(shí)現(xiàn)

關(guān)于夏令時(shí),感覺(jué)有點(diǎn)問(wèn)題

//實(shí)現(xiàn)方式1 沒(méi)有考慮夏令時(shí) 
 @Test 
public void test2() throws Exception { 
/  Date dateTime=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-6 14:00:00"); 
 Date dateTime=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-10-6 14:00:00"); 
 TimeZone zhong = TimeZone.getTimeZone("GMT+8:00");//中國(guó) 
 TimeZone york = TimeZone.getTimeZone("America/New_York"); //GMT-5 
 //這里的時(shí)區(qū)偏移量是固定的,沒(méi)有夏令時(shí),錯(cuò) 
 long chineseMills = dateTime.getTime() + york.getRawOffset()-zhong.getRawOffset(); 
 Date date = new Date(chineseMills); 
 System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)); 
} 
 //實(shí)現(xiàn)方式2 你可能回想,用Calendar類(lèi)的Calendar.DST_OFFSET
 //還是不對(duì)Calendar.DST_OFFSET這個(gè)是死的
	@Test
	public void test3() throws Exception {

//		Date time =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-6 14:00:00");
//		Date time =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-6 1:00:00");
//		Date time =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-6 0:59:00");
//		Date time =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-6 1:59:59");
		Date time =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-6 3:00:00");
	
		// 1、取得本地時(shí)間:
		Calendar cal = Calendar.getInstance();
		cal.setTime(time);
		cal.setTimeZone(TimeZone.getTimeZone("America/New_York"));
		// 2、取得時(shí)間偏移量:這個(gè)是固定的
		int zoneOffset = cal.get(Calendar.ZONE_OFFSET)/(1000*60*60);
		// 3、取得夏令時(shí)差:這個(gè)是固定的,不是根據(jù)時(shí)間動(dòng)態(tài)判斷,只要時(shí)區(qū)存在夏令時(shí),就是1
		int dstOffset = cal.get(Calendar.DST_OFFSET)/(1000*60*60);
		
		System.out.println(zoneOffset);
		System.out.println(dstOffset);
		// 4、從本地時(shí)間里扣除這些差量,即可以取得UTC時(shí)間:
//		cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
		cal.add(Calendar.HOUR, -(zoneOffset + dstOffset));
		Date time2 = cal.getTime();
		System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time2));
		}
//實(shí)現(xiàn)方式3 

準(zhǔn)備工作 
  // 不是說(shuō)java會(huì)自動(dòng)替我們處理夏令時(shí)嗎
	//先來(lái)個(gè)簡(jiǎn)單的測(cè)試,看夏令時(shí)判斷方法是否是正確,就可以推斷,java的自動(dòng)處理是否正確
	//已知2016年:America/New_York的夏令時(shí)時(shí)間是: 2016-3-13 02:00:00 到 2016-11-06 01:59:59 
  @Test
 	public void test4() throws Exception {
 	//轉(zhuǎn)換為0時(shí)區(qū)時(shí)間作為參照點(diǎn)
 	SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 	sf.setTimeZone(TimeZone.getTimeZone("GMT+0"));
//  	Date dateTime=sf.parse("2016-11-6 5:59:59");
 	Date d1=sf.parse("2016-03-13 6:59:59");//false 
  	Date d2=sf.parse("2016-03-13 7:00:00");//true 
  	Date d3=sf.parse("2016-11-6 6:59:59");//false 
  	Date d4=sf.parse("2016-11-6 7:00:00");//false
  	//現(xiàn)在發(fā)現(xiàn)了,對(duì)于夏令時(shí)開(kāi)始的時(shí)間判斷確實(shí)沒(méi)問(wèn)題,但是對(duì)于夏令時(shí)的結(jié)束時(shí)間判斷錯(cuò)誤,準(zhǔn)確說(shuō),提前了一個(gè)小時(shí)判斷了
  	//看下面驗(yàn)證就知道了,那么為什么提前了一個(gè)小時(shí),不知道,怎么解決? 目前想到的只能用java8
  d3=sf.parse("2016-11-6 5:59:59");//true 
  d4=sf.parse("2016-11-6 6:00:00");//false 
  TimeZone york = TimeZone.getTimeZone("America/New_York"); //GMT-5
  	
  System.out.println("目標(biāo)時(shí)區(qū)是否使用了夏令時(shí):"+isDaylight(york, d1));
  System.out.println("目標(biāo)時(shí)區(qū)是否使用了夏令時(shí):"+isDaylight(york, d2));
  System.out.println("目標(biāo)時(shí)區(qū)是否使用了夏令時(shí):"+isDaylight(york, d3));
  System.out.println("目標(biāo)時(shí)區(qū)是否使用了夏令時(shí):"+isDaylight(york, d4));
 	}
 
 //判斷是否在夏令時(shí)
 private boolean isDaylight(TimeZone zone,Date date) {
		return zone.useDaylightTime()&&zone.inDaylightTime(date);
 }
 //實(shí)現(xiàn)方式3 
 //通過(guò)上面的驗(yàn)證我們知道了系統(tǒng)的判斷是有問(wèn)題的,通過(guò)設(shè)置時(shí)區(qū),程序自動(dòng)處理夏令時(shí)也不是那么正確,起碼我現(xiàn)在無(wú)法理解為什么
  @Test
	public void test5() throws Exception {
 	//中間相隔13個(gè)小時(shí)  中國(guó)+8 紐約-5
 	ChangeZone("2016-3-13 14:59:59", "PRC","America/New_York", "yyyy-MM-dd HH:mm:ss");//2016-03-13 01:59:59
 	ChangeZone("2016-3-13 15:00:00", "PRC","America/New_York", "yyyy-MM-dd HH:mm:ss");//2016-03-13 03:00:00
 	ChangeZone("2016-11-6 13:59:59", "PRC","America/New_York", "yyyy-MM-dd HH:mm:ss");//2016-11-06 01:59:59
  //這個(gè)結(jié)果是不對(duì)的,應(yīng)該02:00:00
  ChangeZone("2016-11-6 14:00:00", "PRC","America/New_York", "yyyy-MM-dd HH:mm:ss");//2016-11-06 01:00:00
 }
 	//具體的實(shí)現(xiàn)如下:
 //思路是沒(méi)問(wèn)題的
 public static void ChangeZone(String time, String srcID, String destID,
 	 String pattern) throws ParseException {
 	 //設(shè)置默認(rèn)時(shí)區(qū)
   TimeZone zone = TimeZone.getTimeZone(srcID);
 	 TimeZone.setDefault(zone);
 	 Date date = new SimpleDateFormat(pattern).parse(time);
 	//設(shè)置目標(biāo)時(shí)區(qū)
 	TimeZone destzone = TimeZone.getTimeZone(destID);
 	SimpleDateFormat sdf = new SimpleDateFormat(pattern);
 	//設(shè)置要格式化的時(shí)區(qū)
 	sdf.setTimeZone(destzone);
 	String changTime = sdf.format(date);
 	// 獲取目標(biāo)時(shí)區(qū)
 	System.out.println("修改時(shí)區(qū)后" + destzone.getID() + "的時(shí)間:" + changTime);
  }

小結(jié):以上的三種實(shí)現(xiàn)方式得到的結(jié)果對(duì)夏令時(shí)都有點(diǎn)問(wèn)題

三,java8的實(shí)現(xiàn)

1.先看看java8的支持時(shí)區(qū)變化

//jdk8的可用時(shí)區(qū)
	@Test
	public void testName1() throws Exception {
		//jdk8的所有時(shí)區(qū)
		Set<String> ids = ZoneId.getAvailableZoneIds();
		String[] id1 = ids.toArray(new String[ids.size()]);
		String idss = Arrays.toString(id1).replace("]", ",]");
		
		System.out.println(ids.size());//少了28個(gè) 595
		
		//jdk8之前的所有時(shí)區(qū)
		String[] id2 = TimeZone.getAvailableIDs();
		System.out.println(id2.length); //623
	
		//找出沒(méi)jdk8中沒(méi)有的
		for (String id : id2) {
			if (!idss.contains(id+",")) {
				System.out.print(id+",");
			}
		}
		
		//結(jié)論:jdk8里面的所有時(shí)區(qū),在之前 全部都有
		//jdk8刪除的時(shí)區(qū)如下:
		//都是一些容易引起歧義的時(shí)區(qū)表示方法
//		 EST, HST, MST, ACT, AET, AGT, ART, AST, BET, BST, CAT, CNT, CST, CTT, EAT, ECT, IET, IST, JST, MIT, NET, NST, PLT, PNT, PRT, PST, SST, VST,
		
		// 但是這些短名稱(chēng)的其實(shí)還是可以使用的,只是支持列表里面沒(méi)有了而已
		LocalDateTime date = LocalDateTime.ofInstant(Instant.now(),
				ZoneId.of(ZoneId.SHORT_IDS.get("PST")));
		System.out.println("\nDate = " + date);
		
	}

2.如何添加時(shí)區(qū)信息呢,或者說(shuō)轉(zhuǎn)換

//LocalDate,LocalDateTime,Instant添加時(shí)區(qū)信息
	@Test
	public void testName3() {
		LocalDate date=LocalDate.now();
		//LocalDate添加時(shí)區(qū)信息
		//方式1
		ZonedDateTime zone = date.atStartOfDay(ZoneId.of("GMT+08:00"));
		System.out.println(zone);
		zone = date.atStartOfDay(ZoneId.systemDefault()); 
		System.out.println(zone);
		//方式2
	 LocalDate date2 = LocalDate.now(ZoneId.of("GMT+0"));
		System.out.println(date2);
		
		System.out.println("------------------------------------");
		//LocalDateTime添加時(shí)區(qū)信息
		LocalDateTime time = LocalDateTime.now();
		//方式1
		ZonedDateTime zonetime = time.atZone(ZoneId.of("GMT+0"));
		//方式2
		ZonedDateTime zonetime2=ZonedDateTime.now(ZoneId.of("GMT+0"));
		//方式3
		LocalDateTime zonetime3 = LocalDateTime.now(Clock.system(ZoneId.of("GMT+0")));
		//方式4
		ZonedDateTime zonetime4 = ZonedDateTime.of(time, ZoneId.of("GMT+0"));
		System.out.println(zonetime); //不變
		System.out.println(zonetime2);//變
		System.out.println(zonetime3);//變
		System.out.println(zonetime4);//不變
		
		System.out.println("------------------------------------");
		
		//Instant時(shí)區(qū)信息
		ZonedDateTime atZone = Instant.now().atZone(ZoneId.of("GMT+0"));
		System.out.println(atZone);//變
		
	}

3.如何獲取當(dāng)前時(shí)間的指定時(shí)間(測(cè)試略)

 //獲取當(dāng)前時(shí)間的指定時(shí)區(qū)時(shí)間,參照點(diǎn):0時(shí)區(qū)
		public LocalDateTime getCurrentZoneTime(ZoneId dest) {
			 Objects.requireNonNull(dest);
			 LocalDateTime time2 = LocalDateTime.now(Clock.system(dest));
			 
			 String zoneDesc = getZoneDesc(TimeZone.getTimeZone(dest));
			 System.out.println(dest.getId()+"對(duì)應(yīng)得標(biāo)準(zhǔn)時(shí)區(qū):"+zoneDesc);
			 System.out.println("目標(biāo)時(shí)區(qū)"+dest+"的時(shí)間"+time2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
			 return time2;
		}
//獲取標(biāo)準(zhǔn)時(shí)區(qū),方式1
		//在jdk8之前的方法,利用TimeZone
	 private static String getZoneDesc(TimeZone destzone) {
	 	Objects.requireNonNull(destzone);
		 int Offset = destzone.getRawOffset() / (1000 * 60 * 60);
		 if (Offset <= 0) {
			return "GMT"+String.valueOf(Offset);
		 } else {
			return "GMT+" + String.valueOf(Offset);
		 }
	 }
 //java8的方法,方式2,利用ZoneRules
	 //得到時(shí)區(qū)的標(biāo)準(zhǔn)偏移量,ZoneRules.getStandardOffset
	 //得到時(shí)區(qū)的實(shí)際偏移量(得到的偏移量會(huì)根據(jù)夏令時(shí)改變) 
   // 方式1:ZonedDateTime.getOffset
	 // 方式2:ZoneRules.getOffset
	 private String getZoneDesc2(ZoneId dest) {
	 	Objects.requireNonNull(dest);
	 	ZoneRules rule=dest.getRules(); 
	 	//獲取時(shí)區(qū)的標(biāo)準(zhǔn)偏移量
	 	String standardOffset = rule.getStandardOffset(ZonedDateTime.now(dest).toInstant()).getId();
	 	String s = standardOffset.split(":")[0];
	 	int Offset = Integer.parseInt(s);
	 	//返回方式1:帶小時(shí)分鐘
//	 	return "GMT"+standardOffset;
	 	//返回方式2:只帶小時(shí)數(shù)
	 	if (Offset>0) {
	 		return "GMT+"+Offset;
			}else{
				return "GMT"+Offset;
			}
	 }
	 

4.如何獲取指定時(shí)區(qū)的指定時(shí)間

開(kāi)始實(shí)現(xiàn)上面留下的時(shí)區(qū)問(wèn)題啦

同理先看下使用java8的夏令時(shí)判斷方法是否正確

  //先手寫(xiě)個(gè)判斷美國(guó)的時(shí)間是否在夏令時(shí)
	 public boolean isDaylightTime(LocalDateTime a) {
   Objects.requireNonNull(a);
   LocalDateTime startDate = a.withMonth(3).toLocalDate().atTime(2, 0);
	LocalDateTime startlightDay = startDate.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.SUNDAY));
			//更新為11月
	LocalDateTime endDate = a.withMonth(11).toLocalDate().atTime(1, 59,59);
	LocalDateTime endlightDay = endDate.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.SUNDAY));
			
	if (a.isBefore(startlightDay) || a.isAfter(endlightDay)) {
			System.out.println("不在夏令時(shí)"+a);
			return false;
		}
			System.out.println("在夏令時(shí)"+a);
			return true;
		}
	 
	 //其實(shí)java8 已經(jīng)有現(xiàn)成的方法啦,比我的好用
	 //傳入指定時(shí)間和時(shí)區(qū)
	 public boolean isDaylightTime(LocalDateTime a,ZoneId dest) {
	 	ZonedDateTime z1 = a.atZone(dest);
	 	//或者這樣轉(zhuǎn)
//	 	ZonedDateTime z2 = ZonedDateTime.of(a, dest);
	 	System.out.println(z1.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
	 	
	  ZoneRules rules = dest.getRules();
	  boolean flag= rules.isDaylightSavings(z1.toInstant());
	  System.out.println(flag);
		return flag;
	 }

//測(cè)試一下,發(fā)現(xiàn)java8的夏令時(shí)方法判斷完全正確噢

//已知2016年:America/New_York的夏令時(shí)時(shí)間是: 2016-3-13 02:00:00 到 2016-11-06 01:59:59 
//	   (每年3月的第二個(gè)星期日,11月的第一個(gè)星期日)
	 @Test
		public void testName() throws Exception {
//			LocalDateTime a1=LocalDateTime.now();
	 	LocalDateTime a2=LocalDateTime.of(2016, 3, 13, 1, 59,59);
			LocalDateTime a3=LocalDateTime.of(2016, 3, 13, 2, 00);
			LocalDateTime a4=LocalDateTime.of(2016, 11, 6, 1, 59,59);
			LocalDateTime a5=LocalDateTime.of(2016, 11, 6, 2, 0,0);
//			isDaylightTime(a2);
//			isDaylightTime(a3);
//			isDaylightTime(a4);
//			isDaylightTime(a5);
			
			System.out.println("=================");
			isDaylightTime(a2,ZoneId.of("America/New_York"));//false
			isDaylightTime(a3,ZoneId.of("America/New_York"));//true
			isDaylightTime(a4,ZoneId.of("America/New_York"));//true
			isDaylightTime(a5,ZoneId.of("America/New_York"));//fasle
		}

開(kāi)始實(shí)現(xiàn):

版本1:

//獲取指定時(shí)間的 指定時(shí)區(qū)時(shí)間 參照點(diǎn):默認(rèn)時(shí)區(qū) 
  public LocalDateTime getZongTime(LocalDateTime time,ZoneId dest) { 
   Objects.requireNonNull(dest); 
   return getZongTime(time, null, dest); 
  } 
//不能用2個(gè)時(shí)區(qū)的ZonedDateTime相減,因?yàn)檫@里一旦指定時(shí)區(qū),那個(gè)時(shí)間就是這個(gè)時(shí)區(qū)了 
 public LocalDateTime getZongTime(LocalDateTime time,ZoneId src,ZoneId dest) { 
   //難點(diǎn)就是如何求偏移量 
  //這里使用默認(rèn)時(shí)區(qū),在中國(guó)的就是中國(guó),在美國(guó)的就是美國(guó),這樣估計(jì)更合適 
   Objects.requireNonNull(dest); 
   ZonedDateTime z1=null; 
   if (src==null) { 
    z1 = time.atZone(ZoneId.systemDefault()); 
   }else{ 
    z1 = time.atZone(src); 
   } 
      // 時(shí)區(qū)及時(shí)響應(yīng)變化 
   ZonedDateTime z2 = z1.withZoneSameInstant(dest); 
   
   System.out.println(dest.getId()+"對(duì)應(yīng)得標(biāo)準(zhǔn)時(shí)區(qū):"+getZoneDesc( TimeZone.getTimeZone(dest))); 
   System.out.println("目標(biāo)時(shí)區(qū)"+dest+"的時(shí)間"+z2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 
   System.out.println("-------------"); 
   return time; 
 } 

測(cè)試如下:

@Test 
 public void test6() throws Exception { 
   //預(yù)計(jì)不在夏令時(shí) 2016-03-13 01:59:59 
   LocalDateTime time4= LocalDateTime.of(2016, 3, 13, 14, 59, 59); 
   getZongTime(time4,ZoneId.of("America/New_York")); 
   
   //預(yù)計(jì)在夏令時(shí) 2016-03-13 03:00:00 
   LocalDateTime time1= LocalDateTime.of(2016, 3, 13, 15, 00, 00); 
   getZongTime(time1,ZoneId.of("America/New_York")); 
    
   //預(yù)計(jì)在夏令時(shí) 結(jié)果呢:2016-11-06 01:59:59 
   //感覺(jué)又失敗了,應(yīng)該是2016-11-06 02:59:59 
   //也就是說(shuō),此時(shí)java8對(duì)夏令時(shí)的結(jié)束處理之前的 方式3 一模一樣,提前了一小時(shí)判斷 
   //即把夏令時(shí)結(jié)束時(shí)間當(dāng)成了2016-11-6 00:59:59,但是java8的判斷方法是正確的呀,是不是有點(diǎn)奇怪 
   LocalDateTime time2= LocalDateTime.of(2016, 11, 6, 14, 59, 59); 
   getZongTime(time2,ZoneId.of("America/New_York")); 
    //預(yù)計(jì)不在夏令時(shí)2016-11-06 02:00:00 
   LocalDateTime time3= LocalDateTime.of(2016, 11, 6, 15, 00, 00); 
   getZongTime(time3,ZoneId.of("America/New_York")); 
 } 

所以我現(xiàn)在懷疑這種結(jié)果到底是不是系統(tǒng)計(jì)算問(wèn)題呢,還是我不了解紐約的習(xí)俗呢?

但是還是可以得到我想要的結(jié)果的,運(yùn)用2個(gè)方法:

withEarlierOffsetAtOverlap(), withLaterOffsetAtOverlap()

版本2:

    //獲取指定時(shí)間的 指定時(shí)區(qū)時(shí)間 參照點(diǎn):默認(rèn)時(shí)區(qū)
		public LocalDateTime getZongTime2(LocalDateTime time,ZoneId dest) {
			Objects.requireNonNull(dest);
			return getZongTime2(time, null, dest);
		}
		//版本2 
		public LocalDateTime getZongTime2(LocalDateTime time,ZoneId src,ZoneId dest) {
			 //難點(diǎn)就是如何求偏移量
			//這里使用默認(rèn)時(shí)區(qū),在中國(guó)的就是中國(guó),在美國(guó)的就是美國(guó),這樣估計(jì)更合適
			 Objects.requireNonNull(dest);
			 ZonedDateTime z1=null;
			 if (src==null) {
				 z1 = time.atZone(ZoneId.systemDefault());
			 }else{
				 z1 = time.atZone(src);
			 }
//		
			 ZonedDateTime z2 = z1.withZoneSameInstant(dest);
			 //處理重疊問(wèn)題
			 long hours = Duration.between(z2.withEarlierOffsetAtOverlap(), z2.withLaterOffsetAtOverlap()).toHours();
			 z2= z2.plusHours(hours);
			 
			 System.out.println(dest.getId()+"對(duì)應(yīng)得標(biāo)準(zhǔn)時(shí)區(qū):"+getZoneDesc( TimeZone.getTimeZone(dest)));
			 System.out.println("目標(biāo)時(shí)區(qū)"+dest+"的時(shí)間"+z2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
			 System.out.println("-------------");
			 return time;
		}

測(cè)試:OK了

@Test 
 public void test4() throws Exception { 
   //預(yù)計(jì)不在夏令時(shí) 2016-03-13 01:59:59 
  LocalDateTime time4= LocalDateTime.of(2016, 3, 13, 14, 59, 59); 
  getZongTime2(time4,ZoneId.of("America/New_York")); 
  
  //預(yù)計(jì)在夏令時(shí) 2016-03-13 03:00:00 
  LocalDateTime time1= LocalDateTime.of(2016, 3, 13, 15, 00, 00); 
  getZongTime2(time1,ZoneId.of("America/New_York")); 
   
  //預(yù)計(jì)在夏令時(shí) 2016-11-06 02:59:59 
  LocalDateTime time2= LocalDateTime.of(2016, 11, 6, 14, 59, 59); 
  getZongTime2(time2,ZoneId.of("America/New_York")); 
  //預(yù)計(jì)不在夏令時(shí)2016-11-06 02:00:00 
  LocalDateTime time3= LocalDateTime.of(2016, 11, 6, 15, 00, 00); 
  getZongTime2(time3,ZoneId.of("America/New_York")); 
    
 } 

結(jié)果:

America/New_York對(duì)應(yīng)得標(biāo)準(zhǔn)時(shí)區(qū):GMT-5
目標(biāo)時(shí)區(qū)America/New_York的時(shí)間2016-03-13 01:59:59

-------------

America/New_York對(duì)應(yīng)得標(biāo)準(zhǔn)時(shí)區(qū):GMT-5
目標(biāo)時(shí)區(qū)America/New_York的時(shí)間2016-03-13 03:00:00

-------------

America/New_York對(duì)應(yīng)得標(biāo)準(zhǔn)時(shí)區(qū):GMT-5
目標(biāo)時(shí)區(qū)America/New_York的時(shí)間2016-11-06 02:59:59

-------------

America/New_York對(duì)應(yīng)得標(biāo)準(zhǔn)時(shí)區(qū):GMT-5
目標(biāo)時(shí)區(qū)America/New_York的時(shí)間2016-11-06 02:00:00

-------------

以上這篇基于java時(shí)區(qū)轉(zhuǎn)換夏令時(shí)的問(wèn)題及解決方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot3生成本地文件url的實(shí)現(xiàn)示例

    springboot3生成本地文件url的實(shí)現(xiàn)示例

    本文主要介紹了springboot3生成本地文件url的實(shí)現(xiàn)示例,從而提供一種高效的文件管理方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • 簡(jiǎn)單講解在Java編程中實(shí)現(xiàn)設(shè)計(jì)模式中的單例模式結(jié)構(gòu)

    簡(jiǎn)單講解在Java編程中實(shí)現(xiàn)設(shè)計(jì)模式中的單例模式結(jié)構(gòu)

    這篇文章主要介紹了簡(jiǎn)單講解在Java編程中實(shí)現(xiàn)設(shè)計(jì)模式中的單例模式結(jié)構(gòu),設(shè)計(jì)模式是最基本直白簡(jiǎn)單的一種設(shè)計(jì)模式,需要的朋友可以參考下
    2016-04-04
  • Springboot?No?bean?named?'XXXXX'?available?問(wèn)題解決方法

    Springboot?No?bean?named?'XXXXX'?available?問(wèn)

    這篇文章主要介紹了Springboot?No?bean?named?'XXXXX'?available?問(wèn)題解決方法,解決方法也很簡(jiǎn)單,盡量規(guī)范類(lèi)的命名,注解中指定bean名稱(chēng),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • java如何連續(xù)執(zhí)行多條cmd命令

    java如何連續(xù)執(zhí)行多條cmd命令

    這篇文章主要介紹了java如何連續(xù)執(zhí)行多條cmd命令的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中Equals使用方法匯總

    Java中Equals使用方法匯總

    這篇文章主要采用問(wèn)答的方式集中講解了Java中Equals的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Netty分布式pipeline管道創(chuàng)建方法跟蹤解析

    Netty分布式pipeline管道創(chuàng)建方法跟蹤解析

    這篇文章主要為大家介紹了Netty分布式pipeline管道創(chuàng)建方法跟蹤解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • CentOS?7.9服務(wù)器Java部署環(huán)境配置的過(guò)程詳解

    CentOS?7.9服務(wù)器Java部署環(huán)境配置的過(guò)程詳解

    這篇文章主要介紹了CentOS?7.9服務(wù)器Java部署環(huán)境配置,主要包括ftp服務(wù)器搭建過(guò)程、jdk安裝方法以及mysql安裝過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Java socket通訊實(shí)現(xiàn)過(guò)程及問(wèn)題解決

    Java socket通訊實(shí)現(xiàn)過(guò)程及問(wèn)題解決

    這篇文章主要介紹了Java socket通訊實(shí)現(xiàn)過(guò)程及問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Java設(shè)計(jì)模式初識(shí)之備忘錄模式詳解

    Java設(shè)計(jì)模式初識(shí)之備忘錄模式詳解

    備忘錄設(shè)計(jì)模式(Memento Design Pattern)也叫作快照(Snapshot)模式,主要用于實(shí)現(xiàn)防丟失、撤銷(xiāo)、恢復(fù)等功能。本文將通過(guò)示例為大家介紹一些備忘錄模式的定義與使用,需要的可以參考一下
    2022-11-11
  • 解決Feign調(diào)用的GET參數(shù)傳遞的問(wèn)題

    解決Feign調(diào)用的GET參數(shù)傳遞的問(wèn)題

    這篇文章主要介紹了解決Feign調(diào)用的GET參數(shù)傳遞的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評(píng)論