Golang新手求助:如何正确使用time.Parse去除日期部分

Golang新手求助:如何正确使用time.Parse去除日期部分 在Go语言中迈出蹒跚学步的第一步(这个新奇而美妙的世界),我在时间格式化方面遇到了一个问题。使用下面的格式规范时,我期望时间戳的日期部分会消失,但结果并非如此。可能我完全误解了时间格式的用法,毕竟我过去习惯使用datetime惯例。代码如下:

import (
	"fmt"
	"time"
)

func main() {
	layout := "15:04:05.00"
	str := "19:05:16.88"
	t, err := time.Parse(layout, str)

	if err != nil {
    		fmt.Println(err)
	}
	fmt.Println(t)
	// 使用这个布局语句,我期望看到:19:05:16.88 +0000 UTC
	// 但Go给出的结果是:0000-01-01 19:05:16.88 +0000 UTC
}

代码演示:https://play.golang.org/p/4Xw3QmNdn8a

有什么好主意吗? 先谢谢了


更多关于Golang新手求助:如何正确使用time.Parse去除日期部分的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

请查看 time.Time 类型的 Layout 方法 - https://golang.org/pkg/time/#Time.Format

示例:https://play.golang.org/p/Qvgoh3lB6qF

更多关于Golang新手求助:如何正确使用time.Parse去除日期部分的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这听起来是一个非常棒的应用场景。😊 我猜GPS报告的时间与您的系统时钟之间的偏移量应该很小,应该不会成为问题。如果您身处欧洲时区且不是夜间骑行者,那么不处理午夜问题也是可以的。

夜间骑行确实不在使用场景范围内——我可以向你保证 😊 在时速250公里(约每秒70米)的情况下,存在诸多具有挑战性的问题,比如要实现系统范围内低于1米的分辨率。目前我能获得的最佳系统时钟无疑是GPS数据,他们告诉我这些数据相当精确 😉 因此,我将GPS时钟作为系统时钟,所有其他传感器都以此为准。我认为即使系统运行在Rock64上,这个使用场景对Go语言的并发处理能力也是个挑战。因此,即使我在硬件层面处理部分传感器融合数据,仍然需要对代码进行速度和并发优化。

Go 中的时间总是包含日期,因为它们代表时间轴上的一个点。你可以从当前日期复制日期:

func main() {
    fmt.Println("hello world")
}

请注意,这会在午夜时分带来问题,因此你需要根据时钟偏差的方向进行双向处理。也许可以假设时钟差异始终小于12小时,如果另一端没有参考日期,能做的也就这么多了。

(严格来说,GPS信号确实包含日期信息。只是可能没有通过你正在查看的接口发送。)

感谢 joncalhoun!这确实让我对 Go 语言中的格式化有了新的认识!话虽如此,我意识到我的问题提得有些不够清晰——抱歉。

我认为问题仍然存在,当我尝试使用 “t” 的值时,例如计算"现在"与这个任意时间 “t” 之间的时间差——或者 Go 会为我处理这个问题吗?

我想归根结底是:在 Go 中是否有办法获取"仅时间"(例如 hh:mm:ss.sss 或午夜过去的毫秒数或类似的东西)?您的解决方案优雅地解决了输出的格式化问题,但我担心存储的值(在 “t” 中)仍然包含日期?

为了让您了解背景,可能有助于更好地定义问题:我拥有的数据来自 GPS 接收器,卫星发送的时间戳是 hhmmss.ss——没有日期。因此,在计算来自卫星的最新样本与"现在"之间的差异时,任何日期信息都会搞乱我的计算。

最好的问候 /brusan

谢谢你,雅各布。是的,时间包含日期是合理的,正如你所说,它代表时间点,没有日期的话就变成了任意一天中的某个时间点。所以我最好在时间戳中包含日期。午夜时分的问题似乎很容易处理。

感谢你们两位为我澄清了这一点。

顺便提一下:关于GPS格式,虽然有点奇怪,但NMEA-0183标准通常不使用日期,只使用UTC时间。例如,包含我正在使用的经纬度信息的G+GGA和G+GNS消息只规定了格式为hhmmss.ss的UTC时间,这相当奇怪。为了获取卫星日期,我必须使用例如G+ZDA。这没什么大不了的,但由于我的应用程序需要跟踪我的摩托车(和我自己)在赛道上的活动,我尽可能以高频率(这里是10Hz)采样GPS数据,并对来自其他传感器(如加速度计、磁力计、RTK等)的信号进行大量数学运算,以在时速超过250公里/小时的情况下也能获得高精度。因此,我正尽力减少数据量。

在Go语言中,time.Parse 函数总是返回一个完整的 time.Time 值,包括日期部分。当你只提供时间部分进行解析时,Go会自动将缺失的日期字段设置为零值(即 0000-01-01,对应Go的零时间日期)。这是设计上的行为,无法通过更改布局字符串来去除日期部分。

如果你需要仅处理时间部分而不包含日期,可以考虑以下两种方法:

方法1:使用自定义时间类型或结构体

定义一个只包含时间字段的结构体,并在需要时进行转换:

import (
    "fmt"
    "time"
)

type TimeOnly struct {
    Hour, Minute, Second int
    Nanosecond int
}

func parseTimeOnly(layout, value string) (TimeOnly, error) {
    t, err := time.Parse(layout, value)
    if err != nil {
        return TimeOnly{}, err
    }
    return TimeOnly{
        Hour:       t.Hour(),
        Minute:     t.Minute(),
        Second:     t.Second(),
        Nanosecond: t.Nanosecond(),
    }, nil
}

func (t TimeOnly) String() string {
    return fmt.Sprintf("%02d:%02d:%02d.%02d", 
        t.Hour, t.Minute, t.Second, t.Nanosecond/10000000)
}

func main() {
    layout := "15:04:05.00"
    str := "19:05:16.88"
    timeOnly, err := parseTimeOnly(layout, str)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(timeOnly) // 输出: 19:05:16.88
}

方法2:格式化输出时忽略日期部分

如果你只需要在显示时隐藏日期部分,可以直接格式化时间值:

import (
    "fmt"
    "time"
)

func main() {
    layout := "15:04:05.00"
    str := "19:05:16.88"
    t, err := time.Parse(layout, str)
    if err != nil {
        fmt.Println(err)
        return
    }
    
    // 格式化为只显示时间部分
    fmt.Println(t.Format("15:04:05.00")) // 输出: 19:05:16.88
}

方法3:使用固定日期(如果需要完整的时间操作)

如果需要使用Go标准库的时间操作方法,但不想显示日期,可以固定日期部分:

import (
    "fmt"
    "time"
)

func main() {
    layout := "15:04:05.00"
    str := "19:05:16.88"
    t, err := time.Parse(layout, str)
    if err != nil {
        fmt.Println(err)
        return
    }
    
    // 创建一个固定日期的时间(例如使用Unix纪元)
    fixedTime := time.Date(0, 1, 1, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC)
    fmt.Println(fixedTime.Format("15:04:05.00")) // 输出: 19:05:16.88
}

这些方法可以根据你的具体需求选择使用。如果只需要显示时间,方法2是最简单的解决方案;如果需要单独处理时间逻辑,方法1更合适。

回到顶部