Bootstrap

服务器的时区问题

1、需求:分别统计本月、本周、当天创建的优惠劵数量
2、需求分析:在后台分别获取本月、本周、当天的开始时间,用当天的开始时间举例,获取方式为将目前的系统时间的时分秒去掉,就获取到了当天的开始时间:代码为:

public static String getNowStartDay() {
        String property = System.getProperty("user.timezone");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        sdf.setTimeZone(TimeZone.getTimeZone(property));
        return sdf.format(Calendar.getInstance().getTime());
    }

这样就忽略了时区的问题,按正常情况下往前推8小时,就会算到前一天的16:00:00。
3、问题处理思路:以某个地区的时间为参照,比如以北京上海的时间为参照,计算出服务器当地的时间与北京上海时间的时间差,然后在计算当天开始时间将上面的时间差处理掉,本月和本周的开始时间同理,代码为:

	/**
     * 获得今天时间的开始时间:yyyy-MM-dd  HH:mm:ss
     */
    public static String getNowStartDay() {
        String property = System.getProperty("user.timezone");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone(property));
        Calendar instance = Calendar.getInstance();
        //处理当地时间与北京时间的时区偏差
        instance.set(Calendar.HOUR,0);
        instance.set(Calendar.MINUTE,0);
        instance.set(Calendar.SECOND,0);
        instance.add(Calendar.HOUR, getBetweenCurrentToBeijingTime());
        return sdf.format(instance.getTime());
    }

    /**
     * 获得当前时间:yyyy-MM-dd  HH:mm:ss
     */
    public static String getNowDateStr() {
        String property = System.getProperty("user.timezone");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone(property));
        return sdf.format(Calendar.getInstance().getTime());
    }

    /**
     * 获得本月第一天:yyyy-MM-dd  HH:mm:ss
     */
    public static String getMonthStartDay() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.getActualMaximum(Calendar.DAY_OF_MONTH), 23, 59, 59);
        SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //处理当地时间与北京时间的时区偏差
        c.set(Calendar.DAY_OF_MONTH,1);
        c.set(Calendar.HOUR,0);
        c.set(Calendar.MINUTE,0);
        c.set(Calendar.SECOND,0);
        c.add(Calendar.HOUR, getBetweenCurrentToBeijingTime());
        return startSdf.format(c.getTime());
    }

    /**
     * 获取本周的开始时间:yyyy-MM-dd  HH:mm:ss
     */
    public static Date getBeginDayOfCurrentWeek() {
        Date date = new Date();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getDayStartTime(cal.getTime());
    }

    // 获取某个日期的开始时间
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d)
            calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        //处理当地时间与北京时间的时区偏差
        calendar.set(Calendar.HOUR,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.add(Calendar.HOUR, getBetweenCurrentToBeijingTime());
        return new Timestamp(calendar.getTimeInMillis());
    }

    public static int getBetweenCurrentToBeijingTime(){
        //获取当前地区的时间毫秒
        Calendar calendar = Calendar.getInstance();
        long currentTimeInMillis = calendar.getTimeInMillis();
        //获取北京上海地区的时间毫秒
        calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Calendar beijingCalendar = Calendar.getInstance();
        beijingCalendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH),
                calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
        long beijingTimeInMillis = beijingCalendar.getTimeInMillis();
        //计算两个时间的小时差
        long between = currentTimeInMillis - beijingTimeInMillis;
        int hour = ((int)between / (60 * 60 * 1000));
        return hour;
    }
;