Golang中自定义日期格式与字符串转换
Golang中自定义日期格式与字符串转换 我(作为一名经验不足的Go程序员)编写了一个程序(从网上“借鉴”而来),该程序读取通用的数据库表并将这些数据导出到CSV文件。程序将数据库记录扫描到一个字节切片中,然后简单地使用 string(raw) 代码将其分配给一个字符串切片。
对于日期时间类型的数据库字段,生成的字符串值是默认的“2006-01-02T15:04:05-0700” Go格式,所以问题是:我如何更改生成的格式?
提前感谢。
那么你期望得到什么输出呢?请注意,你目前使用的是 ISO 8601 格式,这是一种非常常见且通用的日期和日期时间表示格式。
好的,你说得对,我的意思是转换并不是由 string(raw) 这段代码完成的,我必须从数据库获取列的类型。
顺便说一下:是的,我想构建一个无需硬编码表结构的工具。很多工具都能做到这一点,但它们很慢。对于处理大型表,我的方法可以快得多,而且我也想测试一下 Go 语言 😊。
非常感谢。
我希望即使在运行时/执行时也能选择我想要的格式。我知道格式是ISO,但不幸的是,据我所知,Excel无法识别这种格式,而且99%的客户只是通过双击文件直接将CSV文件加载到Excel中。
关于time.Parse,它没问题,但问题在于我并不知道我正在处理一个日期,string([raw_value])在这方面为我工作得很好,但仅限于ISO日期格式。
Stefano_Terenzi:
writeCols[i] = string(raw)
这里你有一个字符串。所以,你可以对其应用 Time.Parse,前提是你确定它包含一个时间戳。你怎么知道呢?是否有任何迹象表明某列包含日期或日期时间?也许可以使用列名?
顺便问一下:你是想构建一个完全不了解表结构的工具吗?你怎么能期望它识别日期和日期时间呢?
也许使用你数据库的导出工具会是一个更好的主意。这些工具通常能够写入CSV并格式化列。
package main
import (
"fmt"
"time"
)
func main() {
t, _ := time.Parse(time.UnixDate, "Sat Mar 7 11:06:39 PST 2015")
fmt.Println(t)
s := t.Format("02.01.2006, 15:04:05")
fmt.Println(s)
}
输出:
2015-03-07 11:06:39 +0000 PST
07.03.2015, 11:06:39
好的,我(从网上获取代码)所做的是将数据读取到一个指向字节切片的接口切片中,然后使用 string(...) 进行转换,因此 rawdata 是一个字节切片:
// 创建一个接口切片来指向数据列
readCols := make([]interface{}, len(colNames))
// 创建一个字符串切片,用于写入文件
writeCols := make([]string, len(colNames))
// 创建一个字节切片来读取数据
rawResult := make([][]byte, len(colNames))
// 让接口指向字节
for i, _ := range writeCols {
readCols[i] = &rawResult[i]
}
for rows.Next() {
// 将一行数据读取到接口切片中,这样数据就会进入字节切片
err = rows.Scan(readCols...)
if err != nil {
fmt.Println("Failed to scan row", err)
return
}
// 我必须将字节复制到字符串中,因为字符串转换在数据库值为 null 时会出错
for i, raw := range rawResult {
if raw == nil {
writeCols[i] = ""
} else {
writeCols[i] = string(raw)
}
}
// 写入字符串行
writer.Write(writeCols)
}
在Go中处理日期时间格式转换,你可以使用time.Time类型的Format方法。数据库驱动通常会将日期时间字段扫描为time.Time类型,你需要确保正确扫描到该类型,然后使用自定义格式进行转换。
以下是一个示例,展示如何将数据库中的日期时间字段转换为自定义格式的字符串:
package main
import (
"database/sql"
"fmt"
"time"
_ "github.com/go-sql-driver/mysql" // 以MySQL为例
)
func main() {
db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
panic(err)
}
defer db.Close()
rows, err := db.Query("SELECT id, created_at FROM your_table")
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
var id int
var createdAt time.Time
// 正确扫描日期时间字段到time.Time类型
if err := rows.Scan(&id, &createdAt); err != nil {
panic(err)
}
// 自定义格式:例如 "02-Jan-2006 15:04:05"
formattedDate := createdAt.Format("02-Jan-2006 15:04:05")
fmt.Printf("ID: %d, Created At: %s\n", id, formattedDate)
}
}
如果你确实需要从字节切片直接处理,并且日期时间已经是字符串形式,可以先将其解析为time.Time类型,然后再格式化为自定义格式:
raw := []byte("2006-01-02T15:04:05-0700")
dateStr := string(raw)
// 解析为time.Time类型
parsedTime, err := time.Parse(time.RFC3339, dateStr)
if err != nil {
panic(err)
}
// 格式化为自定义格式
customFormat := parsedTime.Format("2006/01/02 15:04:05")
fmt.Println(customFormat) // 输出: 2006/01/02 15:04:05
关键点:
- 使用
time.Parse解析原始字符串为time.Time类型 - 使用
Format方法并传入自定义布局字符串进行格式化 - Go使用特定参考时间(2006-01-02 15:04:05)作为布局字符串的模板
常用格式示例:
"2006-01-02":标准日期格式"02/01/2006":日/月/年格式"2006-01-02 15:04:05":日期时间格式"Mon, 02 Jan 2006 15:04:05 MST":RFC1123格式

