英文:
get time in days from random date in Go
问题
我有一个API端点,它会收集一些结构化数据,其中一个字段是一个时间戳,格式如下:
"2022-08-30 09:05:27.567995"
我的要求是计算自此时间戳以来的天数。
我有这段代码,它可以工作,但我正在寻求改进 goplayground:
package main
import (
"fmt"
"math"
"time"
)
func main() {
s1 := "2023-01-20"
date1, _ := time.Parse("2006-01-02", s1)
t1 := time.Now().Round(0)
days := int(math.Ceil(t1.Sub(date1).Hours() / 24))
fmt.Println("days: ", days)
}
我有两个问题:
-
我无法在time.Time中找到任何能识别该时间格式的内容,所以我使用了字符串解析,只获取日期(在第一个空格处解析),然后将其作为变量插入到
s1
中。这样做没问题(代码未在此处列出),但我更希望time.Time能够直接解析该格式("2022-08-30 09:05:27.567995"
)的日期。 -
有没有更好的方法来计算自时间戳以来的天数,也许不需要导入math包?我对这个问题感到有些惊讶,因为我以为time.Since()可以做到这一点,但我没有成功,所以我想出了这段代码。
英文:
I have an API endpoint which will gather some structured data and one of the fields is a time stamp with this format:
"2022-08-30 09:05:27.567995"
My requirement is to caculate the number of days since this timestamp style.
I have this code which is working but I am looking for improvements goplayground:
package main
import (
"fmt"
"math"
"time"
)
func main() {
s1 := "2023-01-20"
date1, _ := time.Parse("2006-01-02", s1)
t1 := time.Now().Round(0)
days := int(math.Ceil(t1.Sub(date1).Hours() / 24))
fmt.Println("days: ", days)
}
I have two questions:
-
I was not able to find anything in time.Time that recogizes that time format, so I have done string parsing instead, to get just the date (parsing at first white space), which I will insert into the
s1
as a variable. That is fine (code not listed here) but I would prefer if time.Time could parse just the date, from that format ("2022-08-30 09:05:27.567995"
). -
Is there a better way to calculate the days since the timestamp, perhaps without having to import the math package? I was somewhat suprised at how difficult this seemed to be because I thought time.Since() would be able to do this, but I was not successful with that, so I came up with this code.
</details>
# 答案1
**得分**: 1
我用`time.Since()`尝试了以下代码,结果如预期一样有效:
```Go
package main
import (
"fmt"
"time"
)
func main() {
// 这是来自JSON的输入
// 我在Go playground中使用它作为检查计算的示例
// Go playground的时间从2009-11-10 23:00:00 UTC开始
timeStr := "2009-11-11 23:00:00.000000"
parseLayout := "2006-01-02 15:04:05.000000"
t, err := time.Parse(parseLayout, timeStr)
if err != nil {
fmt.Printf("解析日期时间值 %v 时出错:%w", timeStr, err)
}
durationDays := int(time.Since(t).Abs().Hours() / 24)
fmt.Println(durationDays)
}
当你使用Matteo发布的格式字符串时,你的时间字符串应该能正确解析。请参阅https://pkg.go.dev/time#pkg-constants了解格式字符串的详细信息。
英文:
I tried the following with time.Since()
that works, as I think, as expected:
package main
import (
"fmt"
"time"
)
func main() {
// this is the input from JSON
// used this as an example for checking calculation in Go playground
// which starts time at 2009-11-10 23:00:00 UTC
timeStr := "2009-11-11 23:00:00.000000"
parseLayout := "2006-01-02 15:04:05.000000"
t, err := time.Parse(parseLayout, timeStr)
if err != nil {
fmt.Printf("Error parsing datetime value %v: %w", timeStr, err)
}
durationDays := int(time.Since(t).Abs().Hours() / 24)
fmt.Println(durationDays)
}
When you use the format string posted by Matteo your time string should be parsed correctly. See https://pkg.go.dev/time#pkg-constants for format string details.
答案2
得分: 1
JSON没有日期/时间数据类型,你需要从字符串中解析。
json := "2022-08-30 09:05:27.567995"
t := time.Parse("2006-01-02 15:04:05.999999", json)
你不需要使用Math包:
package main
import (
"fmt"
"time"
)
func main() {
s1 := "2023-01-20" // 或者 "2022-08-30 09:05:27.567995"
date1, _ := time.Parse("2006-01-02", s1)
t1 := time.Now()
// 不幸的是,没有直接截断到仅日期的方法
y, m, d := t1.Date()
t1 = time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
// 现在被截断为仅日期
days := t1.Sub(date1).Hours() / 24
fmt.Println("days: ", days)
}
编辑:扩展到你的JSON情况,你需要经常截断到日期。你可以这样做:
package main
import (
"fmt"
"time"
)
type myTime time.Time
func main() {
s1 := "2023-01-20 09:05:27.567995" // 或者 "2022-08-30 09:05:27.567995"
date1, _ := time.Parse("2006-01-02 15:04:05.999999", s1)
date1 = myTime(date1).DateOnly()
t1 := myTime(time.Now()).DateOnly()
days := t1.Sub(date1).Hours() / 24
fmt.Println("days: ", days)
}
func (t myTime) DateOnly() time.Time {
y, m, d := time.Time(t).Date()
return time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
}
英文:
JSON doesn't have date\datetime data type and you would parse from string.
json := "2022-08-30 09:05:27.567995"
t := time.Parse("2006-01-02 15:04:05.999999", json)
You don't need the Math package:
package main
import (
"fmt"
"time"
)
func main() {
s1 := "2023-01-20" // or "2022-08-30 09:05:27.567995"
date1, _ := time.Parse("2006-01-02", s1)
t1 := time.Now()
// Unfortunately there isn't a direct truncation to Date only
y, m, d := t1.Date()
t1 = time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
// now is truncated to Date
days := t1.Sub(date1).Hours() / 24
fmt.Println("days: ", days)
}
EDIT: Extending to your JSON case, you would need truncation to date a lot. You could do something like this:
package main
import (
"fmt"
"time"
)
type myTime time.Time
func main() {
s1 := "2023-01-20 09:05:27.567995" // or "2022-08-30 09:05:27.567995"
date1, _ := time.Parse("2006-01-02 15:04:05.999999", s1)
date1 = myTime(date1).DateOnly()
t1 := myTime(time.Now()).DateOnly()
days := t1.Sub(date1).Hours() / 24
fmt.Println("days: ", days)
}
func (t myTime) DateOnly() time.Time {
y, m, d := time.Time(t).Date()
return time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
}
答案3
得分: 0
对于你问题的第一个点,你可以使用模式2006-01-02 15:04:05.999999
进行解析,如下所示:
package main
import (
"fmt"
"time"
)
func main() {
x := "2022-08-30 09:05:27.567995"
fmt.Println(time.Parse("2006-01-02 15:04:05.999999", x))
}
参考链接:https://go.dev/play/p/v4TSXJyNOxg
英文:
For the first point of your question, you could parse using the pattern 2006-01-02 15:04:05.999999
like:
package main
import (
"fmt"
"time"
)
func main() {
x := "2022-08-30 09:05:27.567995"
fmt.Println(time.Parse("2006-01-02 15:04:05.999999", x))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论