Golang中自定义日期格式与字符串转换

Golang中自定义日期格式与字符串转换 我(作为一名经验不足的Go程序员)编写了一个程序(从网上“借鉴”而来),该程序读取通用的数据库表并将这些数据导出到CSV文件。程序将数据库记录扫描到一个字节切片中,然后简单地使用 string(raw) 代码将其分配给一个字符串切片。

对于日期时间类型的数据库字段,生成的字符串值是默认的“2006-01-02T15:04:05-0700” Go格式,所以问题是:我如何更改生成的格式?

提前感谢。

8 回复

raw_value 的类型是什么?

更多关于Golang中自定义日期格式与字符串转换的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


那么你期望得到什么输出呢?请注意,你目前使用的是 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并格式化列。

使用 func (Time) Format

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

https://play.golang.com/p/6dN_hTAEIbS

好的,我(从网上获取代码)所做的是将数据读取到一个指向字节切片的接口切片中,然后使用 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

关键点:

  1. 使用time.Parse解析原始字符串为time.Time类型
  2. 使用Format方法并传入自定义布局字符串进行格式化
  3. 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格式
回到顶部