get time in days from random date in Go

huangapple go评论214阅读模式
英文:

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)
}

我有两个问题:

  1. 我无法在time.Time中找到任何能识别该时间格式的内容,所以我使用了字符串解析,只获取日期(在第一个空格处解析),然后将其作为变量插入到s1中。这样做没问题(代码未在此处列出),但我更希望time.Time能够直接解析该格式("2022-08-30 09:05:27.567995")的日期。

  2. 有没有更好的方法来计算自时间戳以来的天数,也许不需要导入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:

  1. 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").

  2. 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 (
	&quot;fmt&quot;
	&quot;time&quot;
)

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 := &quot;2009-11-11 23:00:00.000000&quot;

	parseLayout := &quot;2006-01-02 15:04:05.000000&quot;

	t, err := time.Parse(parseLayout, timeStr)
	if err != nil {
		fmt.Printf(&quot;Error parsing datetime value %v: %w&quot;, 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 := &quot;2022-08-30 09:05:27.567995&quot;
t := time.Parse(&quot;2006-01-02 15:04:05.999999&quot;, json)

You don't need the Math package:

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {

	s1 := &quot;2023-01-20&quot; // or &quot;2022-08-30 09:05:27.567995&quot;
	date1, _ := time.Parse(&quot;2006-01-02&quot;, s1)
	t1 := time.Now()

    // Unfortunately there isn&#39;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(&quot;days: &quot;, days)
}

EDIT: Extending to your JSON case, you would need truncation to date a lot. You could do something like this:

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

type myTime time.Time

func main() {

	s1 := &quot;2023-01-20 09:05:27.567995&quot; // or &quot;2022-08-30 09:05:27.567995&quot;
	date1, _ := time.Parse(&quot;2006-01-02 15:04:05.999999&quot;, s1)
	date1 = myTime(date1).DateOnly()
	t1 := myTime(time.Now()).DateOnly()

	days := t1.Sub(date1).Hours() / 24
	fmt.Println(&quot;days: &quot;, 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 (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {
	x := &quot;2022-08-30 09:05:27.567995&quot;

	fmt.Println(time.Parse(&quot;2006-01-02 15:04:05.999999&quot;, x))
}

See https://go.dev/play/p/v4TSXJyNOxg

huangapple
  • 本文由 发表于 2023年1月25日 21:53:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/75235002.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定