在Oracle数据库中识别巴西圣保罗时区夏令时导致的无效日期
识别圣保罗夏令时无效日期的SQL查询方案
核心思路:巴西圣保罗夏令时开始当天,本地时间不存在00:00(时钟直接从23:00跳到次日01:00)。我们可以通过将存储的00:00时间在圣保罗时区与UTC之间来回转换,对比转换前后的时间是否一致——如果不一致,说明原00:00时间是无效的。
以下是主流数据库的具体实现:
1. PostgreSQL
使用AT TIME ZONE操作符完成时区转换:
SELECT your_date_column FROM your_table WHERE (your_date_column::TIMESTAMP AT TIME ZONE 'America/São Paulo') AT TIME ZONE 'UTC' AT TIME ZONE 'America/São Paulo' != your_date_column::TIMESTAMP;
- 逻辑:把date转成带00:00的timestamp,先视为圣保罗本地时间转UTC,再转回圣保罗时区。无效的00:00会被自动调整为01:00,和原时间不等,从而被筛选出来。
2. MySQL
用CONVERT_TZ函数处理时区转换:
SELECT your_date_column FROM your_table WHERE CONVERT_TZ( CONVERT_TZ( CONCAT(your_date_column, ' 00:00:00'), 'America/São Paulo', 'UTC' ), 'UTC', 'America/São Paulo' ) != CONCAT(your_date_column, ' 00:00:00');
- 逻辑:先把date拼接成带00:00的datetime字符串,两次转换时区后,无效时间会变成当天01:00,和原字符串对比不等即被筛选。
3. SQL Server(2016及以上版本)
结合AT TIME ZONE和SWITCHOFFSET函数:
SELECT your_date_column FROM your_table WHERE CAST(your_date_column AS DATETIME2) AT TIME ZONE 'America/São Paulo' != SWITCHOFFSET( SWITCHOFFSET( CAST(your_date_column AS DATETIME2) AT TIME ZONE 'America/São Paulo', '+00:00' ), 'America/São Paulo' );
- 逻辑:将date转为带圣保罗时区的datetimeoffset类型,先转UTC再转回圣保罗时区,无效时间会被调整为01:00,和原时间对比不等即被筛选。
内容的提问来源于stack exchange,提问作者Fernando Magalhães
相关产品推荐
相关产品推荐

