关于时间
UTC时间戳是指1970年01月01日00时00分00秒到现在经过的总秒数,在任何国家地区,UTC时间都是一样的,但是如果所有地区都是用UTC这样对生活很不方便,因为由于地理位置的不同,这边是早上,那边可能是晚上。于是引入时区的概念,每个国家地区在UTC的基础上,进行时区的运算,这样得到的时间就可用于表示当地的时间。有了时区以后,我们就可以在一个时间规则下,拥有相同的作息。例如规定10点开始上班,经过时区的转换后可以保证全球各地的10点都处于白天。
那么时区的运算规则又是什么,其实就是简单的加减法,比如东8区,就是在UTC的基础上加8个小时。像平时看到的“+8”、“-5”都是说的时区。
有了时区似乎已经解决了关于时间统一的所有问题,确实如此,然而聪明的人类又发现了当夏天来临的时候,太阳会更早的升起更晚的落下,有没有办法让大家都潜移默化的早睡早起,从而达到更好的利用太阳升起的时间,减少夜晚的灯光使用,以充分利用光照资源,从而节约照明用电。
于是夏令时诞生了,夏令时规定了每年的X月到Y月期间,把时钟向前调整Z分钟,例如,每年的3月1号到7月1号为夏令时,夏令时期间时间向前调整1小时,这样当地的所有人都使用这个快了1小时的时间,大家所有的作息也就都提前了1小时。
Android 获取时间
使用java.util包中的时间获取相关API得到的时间,它会根据JAVA运行环境所在时区进行计算,这样有个问题就是无法获取到夏令时信息
TimeZone.getDefault().rawOffset // 获取JAVA运行环境所在时区 时差
TimeZone.getTimeZone(localInfo?.timezoneID).rawOffset // 获取指定timeZoneID 时区时差
System.currentTimeMillis() // 获取UTC时间
那么如何获取夏令时相关的库呢?在JAVA8中提供的java.time.*下就有我们想要的功能,但是当我们在Android使用的时候会提示:Call requires API level 26 (current min is 23) 所以还是要找兼容的库。org.threeten.bp.*这个库就包含了兼容版本的。
val zone: ZoneId = ZoneId.from(ZonedDateTime.now()) // 获取当前时区
val localTime: LocalDateTime = LocalDateTime.now() // 获取当前时间
val offsetSeconds = zone.rules?.getOffset(localTime)?.totalSeconds ?: 0 // 获取当前时间在当前时区下的时区偏差
ReactNative获取时间
JS获取时间使用Date方法,由Date获取的时区信息,是经过夏令时处理以后的。
const tempDate = new Date() // 获取当前时间
return -tempDate.getTimezoneOffset() // 获取当前运行环境下时区的时差信息
那如果我想获取没有经过夏令时处理的时差信息也就是标准时差,应该怎么办呢?此时就需要引入一个新的package了:moment-timezone
// 如果 timeZone 为空就拿系统时区ID
const timezone = CommonUtils.isEmptyDataSource(timeZone)
? moment.tz.zone(moment.tz.guess()) // moment.tz.guess()获取系统所在时区
: moment.tz.zone(timeZone)
return -timezone.utcOffset(0) // 获取 标准时差