You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Haskell HDBC中直接获取SqlUTCTime?

如何通过Haskell HDBC从MariaDB直接获取SqlUTCTime?

我在使用Haskell HDBC查询MariaDB时遇到了问题:数据库的datetime列存储的是UTC时间,但直接执行SELECT查询时,返回的是SqlLocalTime类型,无法直接用fromSql转换为UTCTime;尝试用SQL的DATE_FORMAT()生成带+00:00或Z的ISO8601字符串时,又出现格式兼容错误。最终我通过手动转换解决了问题,但想知道有没有办法直接获取SqlUTCTime?

解决方案

要直接获取SqlUTCTime,可以从连接配置和数据库列类型两个方向处理:

1. 连接时指定UTC时区

HDBC的MariaDB/MySQL驱动支持在创建连接时设置时区参数,将连接时区设为UTC后,驱动会自动把数据库返回的datetime类型值解析为SqlUTCTime。

示例代码:

import Database.HDBC.MySQL

main = do
    conn <- connectMySQL MySQLConnectInfo {
        mysqlHost = "localhost",
        mysqlDatabase = "your_database",
        mysqlUser = "your_user",
        mysqlPassword = "your_password",
        mysqlPort = 3306,
        mysqlOptionGroups = [],
        mysqlOptions = [("timezone", "UTC")]  -- 核心:设置连接时区为UTC
    }
    results <- quickQuery conn "SELECT your_datetime_column FROM your_table" []
    -- 直接提取SqlUTCTime并转换为UTCTime
    let utcTime = fromSql (head $ head results) :: UTCTime
    print utcTime
    disconnect conn

2. 将列类型改为TIMESTAMP

如果数据库中的时间列使用TIMESTAMP类型而非DATETIME,结合连接时区为UTC的设置,驱动会更稳定地将其映射为SqlUTCTime。这是因为MariaDB的TIMESTAMP本身以UTC格式存储,当连接时区设为UTC时,返回的时间不会经过时区转换,直接对应UTC时间。

补充说明

你当前手动转换SqlLocalTime到UTCTime的方法是有效的,尤其适合无法修改连接配置或表结构的场景:

convertSqlValue :: SqlValue -> Maybe UTCTime
convertSqlValue sql = case sql of
    SqlString s -> iso8601ParseM s
    SqlUTCTime u -> Just u
    SqlLocalTime l -> Just $ localTimeToUTC utc l
    other -> Nothing

但通过上述两种方式,你可以省去手动转换的步骤,直接从查询结果中获取SqlUTCTime并转换为UTCTime。

内容的提问来源于stack exchange,提问作者vkubicki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:38:00