UTC时间与PST时间转换
因为我们公司主要是作用亚马逊跨境电商的,有自己的产品和app,app自己在运营,经常会在app上会做一些H5活动,有些活动需要限制每日次数次数和每日定制刷新,就会涉及到时区转换问题,额。。。
废话不多说看需求:
1.每个用户每日拥有15次翻牌次数。另外可通过分享游戏获取额外的2翻牌次数。
全部耗尽则无法翻牌。每日凌晨0点(PST)刷新翻牌次数限制,当日未使用完的次数不可累积到第二天。
2.每当所有卡牌都已被成功翻开,则会自动刷新整组新卡牌;每日凌晨0点后登录(PST时间),
自动刷新一整组新卡牌,前一天未完成的翻牌游戏不会被保存。
分析一下:
1、每日限制15次,限制每日分享1次(分享+2次机会),不叠加使用
可以用redis控制每日翻牌次数和分析次数,key是用户id和当前pst日期,value是用户剩余的翻牌机会,分享次数也是一样;先去从redis中获取,获取不到证明今天没有翻牌(也可以说没有进入过游戏),就初始化翻牌机会为15。拿到了就表示已经有翻牌可以继续操作,分享类比。
2、每日PST时间凌晨0点刷新翻牌次数和发的卡牌
每次发牌都会报错这次发牌的时间用户的是System.currentTimeMillis()
来作为创建时间,保存到数据库中,
问题:
如何获取当前PST的时间?
如何将保存在数据库中的时间转换为PST时间,然后判断是否是新的一天?
问题1: 获取PST时间
PST (北美太平洋标准时间) 是UTC-8时区的知名名称之一,比UTC(协调世界时)落后8个小时与UTC的时间偏差可写为-08:00.它在冬天使用。在夏季,PDT - 北美太平洋夏令时间 (UTC-7)正在使用中。有些地方全年使用PST 。
在java中我们可以用LocalDateTime
时间,指定获取对应时区的时间来作为PST时间(总有在PST地方~~~)
目前在使用PST时间的地区我们可查询到:
这个就是目前在使用PST时间的地区
LocalDateTime.now()
获取当前时间
使用TimeZone.getTimeZone("所在时区TimeZone").toZoneId()
获取对应的ZoneId
/**
* 根据PST时区时间
*
* @return 年月日
*/
public static String getPSTDateStringFormat() {
DateTimeFormatter dfDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime localNow = LocalDateTime.now(TimeZone.getTimeZone("America/Los_Angeles").toZoneId());
return dfDateTime.format(localNow);
}
这样我们就可以获取到当前PST的日期,需要时间的可以吧DateTimeFormatter.ofPattern("yyyy-MM-dd")
改为DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")
PS: hh:mm:ss 是12小时制 HH:mm:ss 是24小时制
手慢了一点~~~~
问题2:如何将UTC时间转换成PST时间
在发牌的时候我保存的时System.currentTimeMillis()
时间,这个时间是UTC时间,这个大家都是知道。
但是在很多人以为System.currentTimeMillis()
的返回值取决于Java运行时系统的本地时区,之前很长一段时间我也是这么认为的,但是事实是:
1、 System.currentTimeMillis()
的返回值与系统时区无关。他返回的是当前时间与 UTC 0 时的 1970年1月1日 0时0分0秒即 1970-01-01 00:00:00 UTC
的差值,也就是0时区的时间;
2、同一时刻,在地球上任意地点的两个人在时区和时间皆设置正确的机器上同时用 System.currentTimeMills()
获取当前系统时间,其返回值一定一样,与时区无关;
我们现在说现在是15点,并不准确,应该是北京时间15点,此时UTC时间是7点,差了8个小时,我们时间戳转换工具转换时间时是需要指定时区来转换的;
知道了这个我就不用去考虑我的服务器部署在什么鬼地方,会不会应该时间换算了~~~~
业务上我可以获取到上次发牌的创建时间(UTC时间),也可以获取到当前的PST时间,所以我将创建时间转成PST时间,然后计算2个PST时间是否垮天就可以了,跨天了就刷新卡牌就可以了(nice ~~~~)
UTC时间转换程PST时间:
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(”UTC时间戳“), TimeZone.getTimeZone("America/Los_Angeles").toZoneId());
通过UTC时间戳,加上时区,换算成当时的PST时间,简单来说就是UTC时间的此时,PST时间是多少;
然后就是计算2个时间是否相差一天,直接上代码:
/**
* UTC 时间转为PST时间,并判断与当前PST时间相差几天
* @param UTCTime UTC时间戳
* @return 相差天数
*/
public static long getPSTDistance(long UTCTime){
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(UTCTime), TimeZone.getTimeZone("America/Los_Angeles").toZoneId());
LocalDateTime now = LocalDateTime.now(TimeZone.getTimeZone("America/Los_Angeles").toZoneId());
Duration between = LocalDateTimeUtil.between(localDateTime, now);
return between.toDays();
}
我们获取一个2天前的时间戳:1669281490000
可以使用Duration类获取其他相差数据
Duration duration = Duration.between(now,end);
long days = duration.toDays(); //相差的天数
long hours = duration.toHours();//相差的小时数
long minutes = duration.toMinutes();//相差的分钟数
long millis = duration.toMillis();//相差毫秒数
long nanos = duration.toNanos();//相差的纳秒数
但是不可以用LocalDateTimeUtil.between(localDateTime, now);
他计算的是时间间隔
但这里问题就解决啦;还有什么不够全面的地方希望大家指正!
转载自:https://juejin.cn/post/7202231477253275703