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

如何在Golang Viper配置中正确表示天数时长以避免加载错误?

解决Golang配置中time.Duration不支持"d"单位的问题

问题背景

.env配置中的MAX_TOKEN_EXPIRY_DAYS=30d无法被Golang的time.Duration解析,因为标准库time包仅支持ns/us/ms/s/m/h这些单位,不包含天(d)。

可行解决方案

1. 直接转换为小时单位

将天数换算成小时(1天=24小时),修改.env配置:

MAX_TOKEN_EXPIRY_DAYS=720h
ACCESS_TOKEN_DURATION=30m

原结构体无需修改,time.Duration可直接解析720h。

2. 用整数接收天数后转换

调整结构体,用int类型接收天数配置,加载后手动转换为time.Duration:

type AppConfig struct {
    MaxTokenExpiryDays int           `mapstructure:"MAX_TOKEN_EXPIRY_DAYS"`
    AccessTokenDuration time.Duration `mapstructure:"ACCESS_TOKEN_DURATION"`
}

// 加载配置后转换
cfg := AppConfig{}
// 假设已通过viper等工具加载配置到cfg
maxTokenExpiry := time.Duration(cfg.MaxTokenExpiryDays) * 24 * time.Hour

.env配置保持MAX_TOKEN_EXPIRY_DAYS=30即可(无需加单位)。

3. 自定义支持"d"单位的Duration类型

实现自定义类型并支持UnmarshalText方法,让配置解析器能识别"d"单位:

import (
    "strconv"
    "strings"
    "time"
)

type DurationWithDays time.Duration

func (d *DurationWithDays) UnmarshalText(text []byte) error {
    s := string(text)
    // 处理天单位
    if strings.HasSuffix(s, "d") {
        daysStr := strings.TrimSuffix(s, "d")
        days, err := strconv.Atoi(daysStr)
        if err != nil {
            return err
        }
        *d = DurationWithDays(time.Duration(days) * 24 * time.Hour)
        return nil
    }
    // 兼容标准Duration单位
    dur, err := time.ParseDuration(s)
    if err != nil {
        return err
    }
    *d = DurationWithDays(dur)
    return nil
}

// 修改结构体使用自定义类型
type AppConfig struct {
    MaxTokenExpiry      DurationWithDays `mapstructure:"MAX_TOKEN_EXPIRY_DAYS"`
    AccessTokenDuration time.Duration    `mapstructure:"ACCESS_TOKEN_DURATION"`
}

// 使用时转换为标准time.Duration
expiry := time.Duration(cfg.MaxTokenExpiry)

这种方式可以保留.env中的30d写法,无需修改配置。

补充说明

标准库time.Duration不支持天单位,是因为天数并非固定的24小时(比如夏令时切换、闰年等场景),但在大多数业务场景下,按24小时/天换算完全满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:37:22