TimeZone计算时区及夏令时处理,可用于爬虫

背景:爬虫需要抓取不同国家的网站的数据,并且都是在半夜零点,从cron job启动,服务器所设置时间是UTC+0的时间,数据库存入的时间也是UTC+0的时间,假设控制时间点的字段为runAfter。

考虑到时区不同,我们可以去判断国家所在的时区提前去跑,如美国洛杉矶,UTC-7,那runAfter在服务器的前一天17:00就可以抓取美国洛杉矶网站的数据,因为这个时候正是当地的凌晨。

再如,瑞士,UTC+2(夏令时),我们可以让程序在服务器的02:00时间去跑,抓取瑞士当地网站的数据。

程序可以提权跑完,并且不影响所爬网站的本身性能。

使用TimeZone来处理夏令时,下面是java代码

package test;

import java.util.Date;
import java.util.ResourceBundle;
import java.util.TimeZone;

 

public class TimeZoneHandle {
	public static ResourceBundle rb = ResourceBundle.getBundle("timezone");

	/*
	 * use getOffset to handle the daylight saving time. the new Date() give us
	 * the UTC+0 date,and it is also the server time.
	 */
	public Date getLocalTime(Job job) {
		Date now = new Date();
		String country = job.getCountry();
		// if the configure file contain the country,we will compute the local
		// time.
		if (rb.containsKey(country)) {
			int crawlerCountryoffset = getCrawlerCountryoffset(country, now);
			int serverZoneOffset = TimeZone.getDefault().getOffset(now.getTime());
			Date localTime = new Date(now.getTime() - (serverZoneOffset - crawlerCountryoffset));
			return localTime;
		} else {
			return now;
		}
	}

	private int getCrawlerCountryoffset(String country, Date date) {
		String timezone_ID = rb.getString(country);
		int offset = TimeZone.getTimeZone(timezone_ID).getOffset(date.getTime());
		return offset;
	}

	  class Job {
		// other fields like Job id
		// ...

		String country;

		public String getCountry() {
			return country;
		}

		public void setCountry(String country) {
			this.country = country;
		}
		
		
	}
	public static void main(String[] argc) {
		TimeZoneHandle timezonehandle=new TimeZoneHandle();
		Job job=timezonehandle.new Job();
		job.setCountry("SE");
		Date d= timezonehandle.getLocalTime( job);
		System.out.println(d);
	}
}

配置文件放置在src source包下

AT= Europe/Vienna
BE= Europe/Brussels
BR= Brazil/East
CA= Canada/Eastern
CH= 
CN= 
DE= Europe/Berlin
DK= Europe/Copenhagen
ES= 
FI= 
FR= Europe/Paris
GR= 
IE= 
IN= 
IT= 
LU= 
NL= 
NO= 
PT= 
SE= Europe/Stockholm
UK= Europe/London
US= 

下面是对java.util.Date,SimpleDateFormat,java.util.Calendar整理

1.

java.util.Date代表一个时间点,其值为距公元1970年1月1日 00:00:00的毫秒数。所以它是没有时区和Locale概念的。

java中通过如下形式取得当前时间点: 

Date now = new Date(); //这个时间点与本地系统的时区无关,而正因为其与时区的无关性,才使得我们的存储数据(时间)是一致的(时区一致性)。

 

2.

一般的我们将now存储于数据库中,当我们需要展现数据时,将now格式化成想要的格式,如:2011-12-04 21:22:24

而这个功能一般交由java.text.DateFormat来实现。例如:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String snow = sdf.format(now);

我们发现snow是带时间(如2011-12-04 21:22:24)的字符串,那么 2011-12-04 21:22:24 这个时间是哪个时区的时间呢?

默认情况下,SimpleDateFormat 取得本地系统的时区(我的时区为GMT+8北京),然后按照 pattern("yyyy-MM-dd HH:mm:ss")格式化now,

此时输出的就是 GMT+8 区的时间了。如果想支持国际化时间,则先指定时区,然后再格式化date数据。

例如:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));

String snow = sdf.format(now); // snow = 2011-12-04 21:22:24

sdf.setTimeZone(TimeZone.getTimeZone("GMT+7"));

String snow2 = sdf.format(now); // snow2 = 2011-12-04 20:22:24 (可见:东八区比东七区早一个小时)

另外,你可以通过如下代码修改本地时区信息:

TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));

在linux系统中,通过如下命令可以得到当前时区

date -R

3.

java.util.Calendar类也代表时间点,但它为Date的facade工具类,提供了很多对时间点到年、月、日、时、分、秒、星期等的转换(计算)的方便方法。

Calendar calendar = Calendar.getInstance(timezone); 

Date d = calendar.getTime();

Calendar的计算也是基于时区的,例如:同一个date在不同时区下的小时数是不一样的。但是calendar.getTime();返回的date是没有时区的,因为它是Date类型的。例如:

 public static void main(String[] args) throws InterruptedException {

  Calendar calendar1 = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));

  Calendar calendar2 = Calendar.getInstance(TimeZone.getTimeZone("GMT+1"));

 

  System.out.println("Millis = " + calendar1.getTimeInMillis());

  System.out.println("Millis = " + calendar2.getTimeInMillis());

 

  System.out.println("hour = " + calendar1.get(Calendar.HOUR));

  System.out.println("hour = " + calendar2.get(Calendar.HOUR));

 

  System.out.println("date = " + calendar1.getTime());

  System.out.println("date = " + calendar2.getTime());

 }

输出:

Millis = 1342497217103

Millis = 1342497217104

hour = 11

hour = 4

date = Tue Jul 17 11:53:37 CST 2012

date = Tue Jul 17 11:53:37 CST 2012

引用的网址:

http://www.cnblogs.com/flying5/archive/2011/12/05/2276578.html

http://blog.163.com/haizai219@126/blog/static/444125552009101924912981/

你可能感兴趣的:(timezone,爬虫,时区,夏令时)