基于java时区转换夏令时的问题及解决方法

一.准备知识

1.America/New_York的夏令时时间如下: 包左不包右

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.三字母时区 ID

为了与 JDK 1.1.x 兼容,一些三字母时区 ID(比如 "PST"、"CTT"、"AST")也受支持。

但是,它们的使用被废弃,这是因为相同的缩写经常用于多个时区

例如 CST:有4个意思,美国,澳大利亚,中国,古巴时间

3.标准

GMT:Green Mean Time格林威治标准时间,1960年前被作为标准时间参考 GMT+12-->GMT-12

java8的范围为GMT+18-->GMT-18

UTC:Coordinated Universal Time 时间协调世界时间 ,比GMT精确,在1972年1月1日成为新的标准;UTC,UTC+1,UTC+2...UTC+12,UTC-12...UTC-1

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

DST:Daylight Saving Time 夏令时间,指在夏天的时候,将时钟拨快一个小时,以提早日光的使用,在英国称为夏令时间;

目前有110多个国家采用夏令时;

在中国,从1986-1992只实行了6年,之后就取消了;原因如下:

1.中国东西方向跨度很大,而且采用的是统一的东八区,采用夏令时无法兼容东西部;

2.高纬度地区,冬夏昼夜时间变化大;意义不大;

4.表示东八区可以用 : GMT+8或者Etc/GMT-8(刚好相反,为什么呢,因为php开发者认为,东八区比标准时间快8小时,应该减去8小时,于是表示成了这样。参考的对象不同导致了不同的表示方法;)

5. 中国时区的表示方式

GMT+8
UTC+8
Asia/Harbin 哈尔滨 //中国标准时间
Asia/Chongqing 重庆//中国标准时间
Asia/Chungking 重庆//中国标准时间
Asia/Urumqi 乌鲁木齐//中国标准时间
Asia/Shanghai 上海(东8区)//中国标准时间
PRC
Asia/Macao 澳门 //中国标准时间
Hongkong 香港 //香港时间跟中国标准时间一致
Asia/Hong_Kong 香港
Asia/Taipei 台北(台湾的) //中国标准时间
新加坡跟中国的时间一样;
Asia/Singapore
Singapore

6. 标准时区的表示

UTC
UTC+0
UTC-0
GMT 格林尼治标准时间
GMT0 格林尼治标准时间
Etc/GMT 格林尼治标准时间
Etc/GMT+0 格林尼治标准时间
Etc/GMT-0 格林尼治标准时间
Etc/GMT0 格林尼治标准时间
注意:GMT+xx(-xx)有很大的包容性,还可以自动的识别各种时间的表示

二. 时区转换

环境:java8之前

1.将当前时间转换为指定时区显示

@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"));
 //把中国时区转为了美国纽约时区
 System.out.println(sf.format(a));
} 

2.指定时间转为指定时区显示

真能正确转换吗?好像有个坑,看了看网上的实现

关于夏令时,感觉有点问题

//实现方式1 没有考虑夏令时
 @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");//中国
 TimeZone york = TimeZone.getTimeZone("America/New_York"); //GMT-5
 //这里的时区偏移量是固定的,没有夏令时,错
 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));
} 
 //实现方式2 你可能回想,用Calendar类的Calendar.DST_OFFSET
 //还是不对Calendar.DST_OFFSET这个是死的
	@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、取得本地时间:
		Calendar cal = Calendar.getInstance();
		cal.setTime(time);
		cal.setTimeZone(TimeZone.getTimeZone("America/New_York"));
		// 2、取得时间偏移量:这个是固定的
		int zoneOffset = cal.get(Calendar.ZONE_OFFSET)/(1000*60*60);
		// 3、取得夏令时差:这个是固定的,不是根据时间动态判断,只要时区存在夏令时,就是1
		int dstOffset = cal.get(Calendar.DST_OFFSET)/(1000*60*60);

		System.out.println(zoneOffset);
		System.out.println(dstOffset);
		// 4、从本地时间里扣除这些差量,即可以取得UTC时间:
//		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));
		}
//实现方式3 

准备工作
  // 不是说java会自动替我们处理夏令时吗
	//先来个简单的测试,看夏令时判断方法是否是正确,就可以推断,java的自动处理是否正确
	//已知2016年:America/New_York的夏令时时间是: 2016-3-13 02:00:00 到 2016-11-06 01:59:59 
  @Test
 	public void test4() throws Exception {
 	//转换为0时区时间作为参照点
 	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
  	//现在发现了,对于夏令时开始的时间判断确实没问题,但是对于夏令时的结束时间判断错误,准确说,提前了一个小时判断了
  	//看下面验证就知道了,那么为什么提前了一个小时,不知道,怎么解决? 目前想到的只能用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("目标时区是否使用了夏令时:"+isDaylight(york, d1));
  System.out.println("目标时区是否使用了夏令时:"+isDaylight(york, d2));
  System.out.println("目标时区是否使用了夏令时:"+isDaylight(york, d3));
  System.out.println("目标时区是否使用了夏令时:"+isDaylight(york, d4));
 	}

 //判断是否在夏令时
 private boolean isDaylight(TimeZone zone,Date date) {
		return zone.useDaylightTime()&&zone.inDaylightTime(date);
 }
 //实现方式3
 //通过上面的验证我们知道了系统的判断是有问题的,通过设置时区,程序自动处理夏令时也不是那么正确,起码我现在无法理解为什么
  @Test
	public void test5() throws Exception {
 	//中间相隔13个小时  中国+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
  //这个结果是不对的,应该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
 }
 	//具体的实现如下:
 //思路是没问题的
 public static void ChangeZone(String time, String srcID, String destID,
 	 String pattern) throws ParseException {
 	 //设置默认时区
   TimeZone zone = TimeZone.getTimeZone(srcID);
 	 TimeZone.setDefault(zone);
 	 Date date = new SimpleDateFormat(pattern).parse(time);
 	//设置目标时区
 	TimeZone destzone = TimeZone.getTimeZone(destID);
 	SimpleDateFormat sdf = new SimpleDateFormat(pattern);
 	//设置要格式化的时区
 	sdf.setTimeZone(destzone);
 	String changTime = sdf.format(date);
 	// 获取目标时区
 	System.out.println("修改时区后" + destzone.getID() + "的时间:" + changTime);
  }

小结:以上的三种实现方式得到的结果对夏令时都有点问题

三,java8的实现

1.先看看java8的支持时区变化

//jdk8的可用时区
	@Test
	public void testName1() throws Exception {
		//jdk8的所有时区
		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个 595

		//jdk8之前的所有时区
		String[] id2 = TimeZone.getAvailableIDs();
		System.out.println(id2.length); //623

		//找出没jdk8中没有的
		for (String id : id2) {
			if (!idss.contains(id+",")) {
				System.out.print(id+",");
			}
		}

		//结论:jdk8里面的所有时区,在之前 全部都有
		//jdk8删除的时区如下:
		//都是一些容易引起歧义的时区表示方法
//		 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,

		// 但是这些短名称的其实还是可以使用的,只是支持列表里面没有了而已
		LocalDateTime date = LocalDateTime.ofInstant(Instant.now(),
				ZoneId.of(ZoneId.SHORT_IDS.get("PST")));
		System.out.println("\nDate = " + date);

	}

2.如何添加时区信息呢,或者说转换

//LocalDate,LocalDateTime,Instant添加时区信息
	@Test
	public void testName3() {
		LocalDate date=LocalDate.now();
		//LocalDate添加时区信息
		//方式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添加时区信息
		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时区信息
		ZonedDateTime atZone = Instant.now().atZone(ZoneId.of("GMT+0"));
		System.out.println(atZone);//变

	}

3.如何获取当前时间的指定时间(测试略)

 //获取当前时间的指定时区时间,参照点:0时区
		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()+"对应得标准时区:"+zoneDesc);
			 System.out.println("目标时区"+dest+"的时间"+time2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
			 return time2;
		}
//获取标准时区,方式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
	 //得到时区的标准偏移量,ZoneRules.getStandardOffset
	 //得到时区的实际偏移量(得到的偏移量会根据夏令时改变)
   // 方式1:ZonedDateTime.getOffset
	 // 方式2:ZoneRules.getOffset
	 private String getZoneDesc2(ZoneId dest) {
	 	Objects.requireNonNull(dest);
	 	ZoneRules rule=dest.getRules();
	 	//获取时区的标准偏移量
	 	String standardOffset = rule.getStandardOffset(ZonedDateTime.now(dest).toInstant()).getId();
	 	String s = standardOffset.split(":")[0];
	 	int Offset = Integer.parseInt(s);
	 	//返回方式1:带小时分钟
//	 	return "GMT"+standardOffset;
	 	//返回方式2:只带小时数
	 	if (Offset>0) {
	 		return "GMT+"+Offset;
			}else{
				return "GMT"+Offset;
			}
	 }
	 

4.如何获取指定时区的指定时间

开始实现上面留下的时区问题啦

同理先看下使用java8的夏令时判断方法是否正确

  //先手写个判断美国的时间是否在夏令时
	 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("不在夏令时"+a);
			return false;
		}
			System.out.println("在夏令时"+a);
			return true;
		}

	 //其实java8 已经有现成的方法啦,比我的好用
	 //传入指定时间和时区
	 public boolean isDaylightTime(LocalDateTime a,ZoneId dest) {
	 	ZonedDateTime z1 = a.atZone(dest);
	 	//或者这样转
//	 	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;
	 }

//测试一下,发现java8的夏令时方法判断完全正确噢

//已知2016年:America/New_York的夏令时时间是: 2016-3-13 02:00:00 到 2016-11-06 01:59:59 
//	   (每年3月的第二个星期日,11月的第一个星期日)
	 @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
		}

开始实现:

版本1:

//获取指定时间的 指定时区时间 参照点:默认时区
  public LocalDateTime getZongTime(LocalDateTime time,ZoneId dest) {
   Objects.requireNonNull(dest);
   return getZongTime(time, null, dest);
  } 
//不能用2个时区的ZonedDateTime相减,因为这里一旦指定时区,那个时间就是这个时区了
 public LocalDateTime getZongTime(LocalDateTime time,ZoneId src,ZoneId dest) {
   //难点就是如何求偏移量
  //这里使用默认时区,在中国的就是中国,在美国的就是美国,这样估计更合适
   Objects.requireNonNull(dest);
   ZonedDateTime z1=null;
   if (src==null) {
    z1 = time.atZone(ZoneId.systemDefault());
   }else{
    z1 = time.atZone(src);
   }
      // 时区及时响应变化
   ZonedDateTime z2 = z1.withZoneSameInstant(dest); 

   System.out.println(dest.getId()+"对应得标准时区:"+getZoneDesc( TimeZone.getTimeZone(dest)));
   System.out.println("目标时区"+dest+"的时间"+z2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
   System.out.println("-------------");
   return time;
 } 

测试如下:

@Test
 public void test6() throws Exception {
   //预计不在夏令时 2016-03-13 01:59:59
   LocalDateTime time4= LocalDateTime.of(2016, 3, 13, 14, 59, 59);
   getZongTime(time4,ZoneId.of("America/New_York")); 

   //预计在夏令时 2016-03-13 03:00:00
   LocalDateTime time1= LocalDateTime.of(2016, 3, 13, 15, 00, 00);
   getZongTime(time1,ZoneId.of("America/New_York")); 

   //预计在夏令时 结果呢:2016-11-06 01:59:59
   //感觉又失败了,应该是2016-11-06 02:59:59
   //也就是说,此时java8对夏令时的结束处理之前的 方式3 一模一样,提前了一小时判断
   //即把夏令时结束时间当成了2016-11-6 00:59:59,但是java8的判断方法是正确的呀,是不是有点奇怪
   LocalDateTime time2= LocalDateTime.of(2016, 11, 6, 14, 59, 59);
   getZongTime(time2,ZoneId.of("America/New_York"));
    //预计不在夏令时2016-11-06 02:00:00
   LocalDateTime time3= LocalDateTime.of(2016, 11, 6, 15, 00, 00);
   getZongTime(time3,ZoneId.of("America/New_York"));
 } 

所以我现在怀疑这种结果到底是不是系统计算问题呢,还是我不了解纽约的习俗呢?

但是还是可以得到我想要的结果的,运用2个方法:

withEarlierOffsetAtOverlap(), withLaterOffsetAtOverlap()

版本2:

    //获取指定时间的 指定时区时间 参照点:默认时区
		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) {
			 //难点就是如何求偏移量
			//这里使用默认时区,在中国的就是中国,在美国的就是美国,这样估计更合适
			 Objects.requireNonNull(dest);
			 ZonedDateTime z1=null;
			 if (src==null) {
				 z1 = time.atZone(ZoneId.systemDefault());
			 }else{
				 z1 = time.atZone(src);
			 }
//
			 ZonedDateTime z2 = z1.withZoneSameInstant(dest);
			 //处理重叠问题
			 long hours = Duration.between(z2.withEarlierOffsetAtOverlap(), z2.withLaterOffsetAtOverlap()).toHours();
			 z2= z2.plusHours(hours);

			 System.out.println(dest.getId()+"对应得标准时区:"+getZoneDesc( TimeZone.getTimeZone(dest)));
			 System.out.println("目标时区"+dest+"的时间"+z2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
			 System.out.println("-------------");
			 return time;
		}

测试:OK了

@Test
 public void test4() throws Exception {
   //预计不在夏令时 2016-03-13 01:59:59
  LocalDateTime time4= LocalDateTime.of(2016, 3, 13, 14, 59, 59);
  getZongTime2(time4,ZoneId.of("America/New_York")); 

  //预计在夏令时 2016-03-13 03:00:00
  LocalDateTime time1= LocalDateTime.of(2016, 3, 13, 15, 00, 00);
  getZongTime2(time1,ZoneId.of("America/New_York")); 

  //预计在夏令时 2016-11-06 02:59:59
  LocalDateTime time2= LocalDateTime.of(2016, 11, 6, 14, 59, 59);
  getZongTime2(time2,ZoneId.of("America/New_York"));
  //预计不在夏令时2016-11-06 02:00:00
  LocalDateTime time3= LocalDateTime.of(2016, 11, 6, 15, 00, 00);
  getZongTime2(time3,ZoneId.of("America/New_York")); 

 } 

结果:

America/New_York对应得标准时区:GMT-5
目标时区America/New_York的时间2016-03-13 01:59:59

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

America/New_York对应得标准时区:GMT-5
目标时区America/New_York的时间2016-03-13 03:00:00

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

America/New_York对应得标准时区:GMT-5
目标时区America/New_York的时间2016-11-06 02:59:59

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

America/New_York对应得标准时区:GMT-5
目标时区America/New_York的时间2016-11-06 02:00:00

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

以上这篇基于java时区转换夏令时的问题及解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java中指定时区的3种方法

    这两天在做与某知名一卡通公司的单点登录集成(我们的产品使用Java编写,对方的程序使用.Net编写)其中有一项参数是时间戳.即当前时间相对于公元1970-1-1 00:00:00的秒数.按照他们给出的文档我完成了Java部分的编写,时间戳部分很简单,一句话: 复制代码 代码如下: private String createTimestamp() //timestamp     {         return System.currentTimeMillis() / 1000 + ""

  • java时间戳转日期格式的实现代码

    如下所示: 复制代码 代码如下: String beginDate="1328007600000"; SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); String sd = sdf.format(new Date(Long.parseLong(beginDate))); System.out.println(sd);

  • java时间戳与日期相互转换工具详解

    本文为大家分享了java日期与时间戳相互转换大全,供大家参考,具体内容如下 package com.crm.util; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * @auth

  • java时间日期使用与查询代码详解

    只要格式正确,直接比较字符串就可以了呀,精确到秒的也一样 String s1 = "2003-12-12 11:30:24"; String s2 = "2004-04-01 13:31:40"; int res = s1.compareTo(s2); 求日期差 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date begin=df.parse("

  • java转换时区时间过程详解

    这篇文章主要介绍了java转换时区时间过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一丶时区 由于世界各国家与地区经度不同,地方时也有所不同,因此会划分为不同的时区. 地球是自西向东自转,东边比西边先看到太阳,东边的时间也比西边的早.东边时刻与西边时刻的差值不仅要以时计,而且还要以分和秒来计算,这给人们带来不便. 为了克服时间上的混乱,1884年在华盛顿召开的一次国际经度会议(又称国际子午线会议)上,规定将全球划分为24个时区(东.西

  • 详解Java中的时区类TimeZone的用法

    一.TimeZone 简介 TimeZone 表示时区偏移量,也可以计算夏令时. 在操作 Date, Calendar等表示日期/时间的对象时,经常会用到TimeZone:因为不同的时区,时间不同. 下面说说TimeZone对象的 2种常用创建方式. 1.获取默认的TimeZone对象 使用方法: TimeZone tz = TimeZone.getDefault() 2.使用 getTimeZone(String id) 方法获取TimeZone对象 使用方法: // 获取 "GMT+08:0

  • Java时间转换成unix时间戳的方法

    java进行时间转换成unix timestamp的具体代码,供大家参考,具体内容如下 import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * @author kongqz kongqingzhu@gmail.com * @version 创建时间:2013-2-19 上午10:21:47 */ pub

  • Java时间类Date类和Calendar类的使用详解

    起因:写代码的时候经常会用到获取当前时间戳和日期,现总结如下 public void testDate() { //SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式 Date date = new Date(); String dateString = date.toString(); long times = date.getTime(); System.out.println("date.t

  • 基于java时区转换夏令时的问题及解决方法

    一.准备知识 1.America/New_York的夏令时时间如下: 包左不包右 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.三字母时区 ID 为了与 JDK 1.1.x 兼容,一些三字母时区 ID(比如 "PST"."CTT"."AST")也受支持. 但是,它们的使用被废弃,这是因为相同的缩写经常用于多个时区 例如 CST:有

  • Java String转换时为null的解决方法

    开发中经常遇到从集合类List.Map中取出数据转换为String的问题,这里如果处理不好,经常会遇到空指针异常java.lang.NullPointerException,在此总结一下常用转换为String的方法,以及转换后如何对其进行判null使用的问题. Java中对象转换为String的常用方法: 方法一:String  objStr  =  (String) obj: 强制类型转换,对象obj为null,结果也为null,但是obj必须保证其本质是String类型的值,即可转换的值.

  • java时区转换的理解及示例详解

    一.时区的基本概念 GMT(Greenwich Mean Time),即格林威治标准时,是东西经零度的地方.人们将地球人为的分为24等份,每一等份为一个时区,每时区横跨经度15度,时间正好为1小时.往西一个时区,则减去一小时:往东一个时区,则加上一小时.中国在东经120度上,(东经120°-东经0°)所得度数再除以15,即得8. UTC(Coordinated Universal Time),即世界协调时间,是经过平均太阳时(以格林威治时间GMT为准).地轴运动修正后的新时标以及以「秒」为单位的

  • Java时区转换及Date类实现原理解析

    这篇文章主要介绍了Java时区转换及Date类实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.时区的说明 地球表面按经线从东到西,被划成一个个区域,规定相邻区域的时间相差1小时.在同一区域内的东端和西端的人看到太阳升起的时间最多相差不过1小时.当人们跨过一个区域,就将自己的时钟校正1小时(向西减1小时,向东加1小时),跨过几个区域就加或减几小时 ,所以同一时刻在不同时区表示的时间是不一样的. 二.时间的表示 我们平时表示时间时通

  • 基于Java数组实现循环队列的两种方法小结

    用java实现循环队列的方法: 1.添加一个属性size用来记录眼下的元素个数. 目的是当head=rear的时候.通过size=0还是size=数组长度.来区分队列为空,或者队列已满. 2.数组中仅仅存储数组大小-1个元素,保证rear转一圈之后不会和head相等.也就是队列满的时候.rear+1=head,中间刚好空一个元素. 当rear=head的时候.一定是队列空了. 队列(Queue)两端同意操作的类型不一样: 能够进行删除的一端称为队头,这样的操作也叫出队dequeue: 能够进行插

  • 基于创建Web项目运行时出错的解决方法(必看篇)

    1.目录结构 2.各文件内容 index.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <form action="/Servlet" method="

  • java SpringBoot注解@Async不生效的解决方法

    目录 问题描述: 解决方案: 总结: SpringBoot 注解@Async不生效的解决方法 问题描述: 这里虽然加了@EnableAsync和@Async,但是异步请求依然没有生效 解决方案: 方法一: 同一个类中调用需要先获取代理对象,也就是手动获取对象 @Service @EnableAsync public class DemoService { public void add(){ DemoService bean = SpringUtil.getBean(DemoService.cl

  • Java序列化JSON丢失精度问题的解决方法(修复Long类型太长)

    目录 原因: 解决办法一: 解决办法(二): 总结 Java序列化JSON时long型数值,会出现精度丢失的问题. 原因: java中得long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值). 解决办法一: 使用ToStringSerializer的注解,让系统序列化时,保留相关精度 @JsonSerialize(using=ToStringSerializer.class) private Long createdBy; 上述方法需要在每个对象都配上该注

  • 基于CORS实现WebApi Ajax 跨域请求解决方法

    概述 ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题,特别各种APP万花齐放的今天,API的跨域请求是不能避免的. 在默认情况下,为了防止CSRF跨站的伪造攻击(或者是 javascript的同源策略(Same-Origin Policy)),一个网页从另外一个域获取数据时就会收到限制.有一些方法可以突破这个限制,那就是大家熟知的JSONP, 当然这只是众多

  • 基于bootstrap-datetimepicker.js不支持IE8的快速解决方法

    实例如下: if (!Array.prototype.indexOf) Array.prototype.indexOf = function (elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len;

随机推荐