获取不同时区的当前时间,批量获取方法,Java

1,397 阅读2分钟

前言

根据城市获取当前城市所在时区的当前时间,在一些业务场景上是刚需的要求。 比如到其他时区下单,查询商品,或者我们要去预订当地的酒店,等等场景,都需要获取当前城市的当前时间。

问题: 世界上N多个城市,大概3W多个,如何批量去获取,在不能确保网上copy的能准确的情况下,身为程序猿的我们,不能没有招。

方法

用Java的LocalDateTime

ZoneId zoneId = ZoneId.of(timeZoneId);
LocalDateTime now = LocalDateTime.now(zoneId);

那么问题来了,timeZoneId(时区ID) 哪里来,这个就不能确保网上的都对了,万一错误,我们的逻辑就取不到正确的时间。

image.png

如上图的第三列

有了这个时区ID,我们才能通过LocalDateTime去获取当前时间。

获取时区ID

百度api

通过经纬度,获取所在城市的时区ID

百度的有个限制,如果个人的,每天最多300个,一个key的话。如果要加就申请下,应该还是能加点量的。

private static String getBaiduTimeZone(BigInteger cityId, String latitude, String longitude){
    //http://api.map.baidu.com/timezone/v1?coord_type=wgs84ll&location=-36.52,174.46&timestamp=1473130354&ak=你的ak //GET请求
    try {
        log.debug("System.currentTimeMillis() ={} ",System.currentTimeMillis() / 1000);
        String url = "http://api.map.baidu.com/timezone/v1";
        Map<String, Object> params = new HashMap<>();
        params.put("location",latitude+","+longitude);
        params.put("timestamp",System.currentTimeMillis() / 1000);
        params.put("ak","youBaiduKey");
        HttpRequest httpRequest = HttpRequest.get(url).form(params).timeout(60000);
        String result =  httpRequest.execute().body();
        JsonNode jsonNode = JsonUtil.readTree(result);
        String timezone_id = jsonNode.get("timezone_id")!=null? jsonNode.get("timezone_id").toString():null;
        if(timezone_id == null){
            return null;
        }
        return timezone_id.replaceAll(""","");
    }catch (Exception e){
        log.error(e.getMessage());
    }
    return null;
}

Google地图的获取时区ID

谷歌地图的是要收费的, 但有 免费用一个月200$

image.png 获取时区代码如下:

public String getTimeZone(LatAndLonDTO latAndLon) {
    try{
        LatLng location = new LatLng(new BigDecimal(latAndLon.getLatitude()).doubleValue(), new BigDecimal(latAndLon.getLongitude()).doubleValue());
        PendingResult<TimeZone> timeZoneInfo = TimeZoneApi.getTimeZone(GoogleApiContext.getInstance(), location);
        if(timeZoneInfo != null) {
            return timeZoneInfo.await().getID();
        }
    } catch(Exception e) {
    //log info some message
        throw new Exception(e);
    }
    return null;
}

Python的时区库

Python的时区库 ,可以大批量的获取,重点是免费哈。但会有个别的解析不了。

通过时区ID获取时区的当前时间

最后就是获取时区的时间了

/**
 * 通过时区ID获取当前时区的当前时间戳 
 */
private Long getTimestampByTimeZoneId(String timeZoneId){
    if(timeZoneId == null){
        return LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }
    try {
        ZoneId zoneId = ZoneId.of(timeZoneId);
        LocalDateTime now = LocalDateTime.now(zoneId);
        return now.toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }catch (Exception e){
        log.error("getTimeByTimeZoneId error !! timeZoneId={}  ,and Exception = {}",timeZoneId,e.getMessage());
    }
    return LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
}

总结

获取时区ID获取要存下来,不要每次都去获取时区ID。

1、落库存储

2、存到缓存,方便快速使用