热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

2019独角兽企业重金招聘Python工程师标准背景:爬虫需要抓取不同国家的网站的数据,并且都是在半夜零点,从cronjob启动&#

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

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


转:https://my.oschina.net/forrest420/blog/67602



推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了在Java中gt、gtgt、gtgtgt和lt之间的区别。通过解释符号的含义和使用例子,帮助读者理解这些符号在二进制表示和移位操作中的作用。同时,文章还提到了负数的补码表示和移位操作的限制。 ... [详细]
author-avatar
手机用户2602927807
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有