背景:爬虫需要抓取不同国家的网站的数据,并且都是在半夜零点,从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/