Kotlin中如何判断用户是否已到解禁时间?
判断用户是否已到解禁时间的正确实现
现有方案的问题分析
字符串拆分比较的逻辑漏洞
你的第一个方案中,只要年份、月份、日期任意一个维度满足大于等于解禁时间,就直接返回true,忽略了更小维度的时间校验。比如当天还没到解禁的时分秒,但因为_year >= year && _month >= month && _day >= day条件成立,会错误返回true,导致判断逻辑失效。SimpleDateFormat方案的关键错误
你使用Calendar.HOUR获取小时,这是12小时制字段(返回值范围0-11),但日期格式用的是HH(24小时制)。比如下午3点(15时)会被Calendar.HOUR返回3,拼接成字符串后解析成凌晨3点,导致当前时间的解析值完全错误,比较结果自然不正确。
推荐方案:使用Java 8+的java.time API
java.time是Java 8引入的新时间API,线程安全且设计更清晰,是官方推荐替代Date、Calendar的方案。
代码实现
import java.time.LocalDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter fun isUnbanned(endBanned: String): Boolean { // 定义时间格式:HH为24小时制,yyyy需小写(大写YYYY是周年,易出错) val formatter = DateTimeFormatter.ofPattern("HH:mm:ss dd/MM/yyyy") // 解析解禁时间为LocalDateTime对象 val bannedEndTime = LocalDateTime.parse(endBanned, formatter) // 获取越南时区的当前时间 val currentTime = LocalDateTime.now(ZoneId.of("Asia/Ho_Chi_Minh")) // 直接比较时间大小:当前时间 >= 解禁时间则返回true return currentTime >= bannedEndTime } // 测试示例 fun main() { val endBanned = "15:05:00 12/01/2022" println(isUnbanned(endBanned)) }
关键说明
DateTimeFormatter替代SimpleDateFormat,避免旧API的线程安全问题。- 指定时区
ZoneId.of("Asia/Ho_Chi_Minh"),确保当前时间与解禁时间在同一时区下比较。 - 直接使用
LocalDateTime的比较运算符,逻辑清晰,无需手动拆分时间字段。
旧API修正方案(仅兼容旧项目)
如果必须使用Date和Calendar,需修正两个核心问题:
代码实现
import java.text.SimpleDateFormat import java.util.* fun isUnbannedOld(endBanned: String): Boolean { val timeZone = TimeZone.getTimeZone("Asia/Ho_Chi_Minh") val sdf = SimpleDateFormat("HH:mm:ss dd/MM/yyyy") sdf.timeZone = timeZone // 给SimpleDateFormat设置时区,保证解析和当前时间时区一致 // 解析解禁时间,解析失败返回false val bannedEndTime = sdf.parse(endBanned) ?: return false // 获取当前时区的时间 val currentTime = Calendar.getInstance(timeZone).time // 直接比较Date对象大小 return currentTime >= bannedEndTime } // 测试示例 fun main() { val endBanned = "15:05:00 12/01/2022" println(isUnbannedOld(endBanned)) }
修正点说明
- 给
SimpleDateFormat设置时区,确保解析的解禁时间与当前时间处于同一时区。 - 直接通过
Calendar.getInstance(timeZone)获取当前时间,避免手动拼接字符串导致的12/24小时制错误。 - 直接比较
Date对象,无需计算时间差,逻辑更直观。
内容的提问来源于stack exchange,提问作者Hồ Henry
相关产品推荐
相关产品推荐

