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

Grails 2.5.5:如何将带区域的date.struct转为UTC的java.util.Date

重写StructuredDateEditor将date.struct转换为UTC日期(Grails 2.5.x)

Grails的GrailsParameterMap默认通过StructuredDateEditor把date.struct格式的参数转换为java.util.Date,默认会用系统或请求关联的时区处理。要实现将用户时区的日期转换为UTC,可按以下步骤重写该编辑器:

1. 自定义StructuredDateEditor子类

继承原StructuredDateEditor类,重写核心的parse方法,先按用户时区解析日期,再转换为UTC时间:

import org.codehaus.groovy.grails.web.servlet.mvc.StructuredDateEditor
import java.util.TimeZone
import java.text.SimpleDateFormat

class UtcStructuredDateEditor extends StructuredDateEditor {

    private final TimeZone userTimeZone

    UtcStructuredDateEditor(TimeZone userTimeZone) {
        this.userTimeZone = userTimeZone
    }

    @Override
    protected Date parse(String text) throws IllegalArgumentException {
        // 按用户时区解析输入的日期字符串
        def sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        sdf.timeZone = userTimeZone
        Date userDate = sdf.parse(text)

        // 转换为UTC时间
        TimeZone utcZone = TimeZone.getTimeZone("UTC")
        long utcTimestamp = userDate.time + (userTimeZone.getOffset(userDate.time) - utcZone.getOffset(userDate.time))
        return new Date(utcTimestamp)
    }
}

注:如果需要支持多日期格式,可以扩展parse方法的格式处理逻辑,或复用原类的格式解析逻辑后再做时区转换。

2. 注册自定义编辑器到Grails参数绑定

通过自定义PropertyEditorRegistrar替换默认编辑器,确保Grails启动时加载:

import org.springframework.beans.PropertyEditorRegistrar
import org.springframework.beans.PropertyEditorRegistry
import java.util.TimeZone

class UtcDateEditorRegistrar implements PropertyEditorRegistrar {

    // 示例固定用户时区,实际可从配置/请求上下文动态获取
    private TimeZone userTimeZone = TimeZone.getTimeZone("Asia/Shanghai")

    @Override
    void registerCustomEditors(PropertyEditorRegistry registry) {
        // 覆盖默认的StructuredDateEditor
        registry.registerCustomEditor(Date.class, "date.struct", new UtcStructuredDateEditor(userTimeZone))
    }
}

然后在grails-app/conf/spring/resources.groovy中注册该Registrar:

beans = {
    utcDateEditorRegistrar(UtcDateEditorRegistrar)
}

3. 验证转换效果

在控制器中接收参数,打印日期信息确认已转为UTC:

class TestController {
    def index() {
        Date utcDate = params.date
        println "UTC时间: ${utcDate}"
        println "UTC时区偏移: ${TimeZone.getTimeZone("UTC").getOffset(utcDate.time)}"
        render "转换后的UTC日期: ${utcDate}"
    }
}

内容的提问来源于stack exchange,提问作者Jordi Romero Sallent

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 16:04:53