根据经度和unix时间戳推算用户时间

前言:《三国演义》第46回草船借箭,孔明对鲁肃说“为将而不通天文,不识地利,不知奇门,不晓阴阳,不看阵图,不明兵势,是庸才也。”那么程序员也一样,作为一个全能型的程序员,须得上知天文,下知地理。现在有一个统计全球各地的用户在一天当中的每个时段的使用频率。也就是说,我大天朝的15点和蛮夷小邦的15点统计在一起,所以要解决时区问题。

解决思路是这样的,我以一个时区作为参照点,其它时区的时间根据所处的时区进行时间相加减即可。用户上传的时间是unix时间戳,是0时区的时间,就以他作为参照点。现在的问题只剩下计算出用户的时区与0时区的时间差距即可。

怎么计算这个时间差距?用户给了gps信息,是不是可以调用第三方接口?

绝对不行!!!

因为这是大数据项目,网络传输都是致命的!况且接口有次数限制,超过免费次数后要收钱,这是最棘手的。那怎么搞?何不自己解析呢,虽然程序员大多理科出身,但是高中地理可不是白读的!

我们先来复习一下高中地理经纬度的课程:

这里写图片描述


经、纬度计算:经度差与地方时差算经度——地方时每相差1小时,经度相差15°;
经纬线上长度算经纬度——1°经线长111km,1°纬线长111cosфkm(ф为纬度)。
东西经-——东(西)经度的增大方向与地球自转方向相同(反)。


这里写图片描述


计算时区只用到经度即可,下面只看经度:

经度时间计算:
①某地时区数=该地经度÷15,对商取整数部分,尾数部分四舍五入;
②区时的计算:根据各时区中央经线的地方时即为本时区区时,相邻的两个时区的区时相差1小时,即求某地区区时=已知地区时±两地时区,注意东加西减;
③地方时的计算:找出已知的经度与时间,经度差=东边地点的经度-西边地点的经度 (不跨180°经线计算,东经度为正,西经度为负值), 时间差=经度差÷地球自转角速度15°/时或1°/4分,注意加减行程时间根据东早西晚。结果若小于0,则应加24小时,日期变为昨天。
⑤日期界线有两条:自然界线即地方时0:00经线,顺着地球的自转方向,跨过它时日期应加上1天;人为界线即国际日期变更线,也就是180°经线(但两者有三处并不完全重合),顺着地球的自转方向,跨过它时日期应减去1天。注意今天与昨天范围的描述。

综上所述,我们可以自己编写一个计算时区差的程序:

//根据毫秒数得到时间
    public static int getTimeByLongSecond(Long timeSecond, String gps) {
        Date date = new Date(timeSecond);
        //本初子午线的时间
        int zeroTime = date.getHours();
        String[] s_gps = gps.split(",");
        //经度
        int longitude = Integer.parseInt(s_gps[1].substring(0, s_gps[1].indexOf(".")));
        //经度所在时间
        int mytime;
        //每个时区为15度,遵循东加西减原则
        //东经
        if(longitude > 0) {
            mytime = zeroTime + longitude/15;
            if(mytime > 24) {
                mytime -= 24;
            }
        }
        //西经
        else
        {
            mytime = zeroTime - (Math.abs(longitude))/15;
            if(mytime < 0 ) {
                mytime += 24;
            }
        }
        return mytime;
    }

//测试一下
public static void main(String[] args) throws Exception {
        System.out.println(getTimeByLongSecond(1511106631240L, "22.726868,120.905893"));
    }

由于本地可以计算时区的差距,hadoop 直接挂载本地方法,用户时间的获取就方便快捷很多。


这里写图片描述


后记:自己动手,丰衣足食!

相关文章
相关标签/搜索