时间格式化和字符串转换

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

Time formatting and converting from string

问题

我对Go语言还不太熟悉,主要使用C#。我目前正在开发一个用作命令的东西,用于获取下一班公交车的时间。目前它无法编译,因为我不太理解如何在Go中使用time包。

我有一个字符串数组,格式化为预定的时间,还有一个字符串数组,格式化为常规服务的分钟数(这只是一个示例,实际上有更多时间):

var ScheduledTimes = []string{"06:34", "06:54", "17:09", "17:19"}
var RegularTimes = []string{"05", "50"}

目前我正在做的是获取当前时间,并检查它是否在常规服务时间内,代码如下:

func isWithinRegularService(check time.Time) bool {
    RegularStart, err := time.Parse(time.Kitchen, "10:05")
    RegularEnd, err := time.Parse(time.Kitchen, "13:52")
    return check.After(RegularStart) && check.Before(RegularEnd)
}

time := time.Now().UTC().Format("15:04")
if isWithinRegularService(time) { }

如果在常规服务时间内,我将确定需要查看的小时数(即当前小时或下一个小时内的服务):

if time.Minutes < 5 && time.Minutes >= 0 {
    RegularTimes[0] = fmt.Sprintf("%s%s", time.Hour+1, RegularTimes[0])
    RegularTimes[1] = fmt.Sprintf("%s%s", time.Hour+1, RegularTimes[1])
    RegularTimes[2] = fmt.Sprintf("%s%s", time.Hour+1, RegularTimes[2])
    RegularTimes[3] = fmt.Sprintf("%s%s", time.Hour+1, RegularTimes[3])
} else {
    RegularTimes[0] = fmt.Sprintf("%s%s", time.Hour, RegularTimes[0])
    RegularTimes[1] = fmt.Sprintf("%s%s", time.Hour, RegularTimes[1])
    RegularTimes[2] = fmt.Sprintf("%s%s", time.Hour, RegularTimes[2])
    RegularTimes[3] = fmt.Sprintf("%s%s", time.Hour, RegularTimes[3])
}

然后,我将将该数组传递给另一个函数,以获取要比较的时间段:

type BusTime struct {
    betweenStart string
    betweenEnd   string
}

func getBusTime(busTimes []array, iteration int) BusTime {
    var timesToReturn BusTime

    if iteration == busTimes.Count()-1 {
        timesToReturn.betweenStart = busTimes[iteration]
        timesToReturn.betweenEnd = busTimes[0]
    } else {
        timesToReturn.betweenStart = busTimes[iteration]
        timesToReturn.betweenEnd = busTimes[iteration+1]
    }

    return timesToReturn
}

busTimes := getBusTime(quaylinkRegularTimes, i)

最后,我将检查提供的时间是否在要比较的时间段内:

check.After(start) && check.Before(end)

这就是这个项目的大致情况。如果不在常规服务时间内,它将执行相同的操作,但跳过确定要查看的小时数的步骤。

目前无法构建该项目,因为我在应该使用时间的地方使用了字符串。我希望能够获得一些关于如何正确使用时间以实现我想要的功能的指导、示例和更正。到目前为止,我认为流程逻辑是正确的,但我无法编译它。

英文:

I'm quite new to Go and mainly work in C#. I am currently working on something that will be used as a command to get the next bus. Currently it does not compile because I am struggling with understanding how to use the time package in Go.

I have an array of strings formatted as times when it is scheduled and another for the minutes when it is a regular service like so (there are many more times these are just an example:

var ScheduledTimes = []string{&quot;06:34&quot;, &quot;06:54&quot;, &quot;17:09&quot;, &quot;17:19&quot;}
var RegularTimes = []string{&quot;05&quot;, &quot;50&quot;}

So what I am currently doing is getting the current time and checking if it is in regular service by doing this:

func isWithinRegularService(check time.Time) bool {
    RegularStart, err := time.Parse(time.Kitchen, &quot;10:05&quot;)
    RegularEnd, err := time.Parse(time.Kitchen, &quot;13:52&quot;)
    return check.After(RegularStart) &amp;&amp; check.Before(RegularEnd)
}

time := time.Now().UTC().Format(&quot;15:04&quot;)
if isWithinRegularService(time) { }

If it is in regular service, I will then determine what hour needs looking at (i.e this one or is the next service within the next hour)

if time.Minutes &lt; 5 &amp;&amp; time.Minutes &gt;= 0 {
	RegularTimes[0] = fmt.Sprintf(&quot;%s%s&quot;, time.Hour+1, RegularTimes[0])
	RegularTimes[1] = fmt.Sprintf(&quot;%s%s&quot;, time.Hour+1, RegularTimes[1])
	RegularTimes[2] = fmt.Sprintf(&quot;%s%s&quot;, time.Hour+1, RegularTimes[2])
	RegularTimes[3] = fmt.Sprintf(&quot;%s%s&quot;, time.Hour+1, RegularTimes[3])
} else {
	RegularTimes[0] = fmt.Sprintf(&quot;%s%s&quot;, time.Hour, RegularTimes[0])
	RegularTimes[1] = fmt.Sprintf(&quot;%s%s&quot;, time.Hour, RegularTimes[1])
	RegularTimes[2] = fmt.Sprintf(&quot;%s%s&quot;, time.Hour, RegularTimes[2])
	RegularTimes[3] = fmt.Sprintf(&quot;%s%s&quot;, time.Hour, RegularTimes[3])
}

Before I pass that array to another func to give me the times to check between

type BusTime struct {
betweenStart string
betweenEnd   string
}

func getBusTime(busTimes []array, iteration int) BusTime {

    var timesToReturn BusTime

    if iteration == busTimes.Count()-1 {
	    timesToReturn.betweenStart = busTimes[iteration]
	    timesToReturn.betweenEnd = busTimes[0]
    } else {
	    timesToReturn.betweenStart = busTimes[iteration]
	    timesToReturn.betweenEnd = busTimes[iteration+1]
    }

    return timesToReturn
}

busTimes := getBusTime(quaylinkRegularTimes, i)

And lastly I then check if the time provided is between the times to compare:

check.After(start) &amp;&amp; check.Before(end)

That is about it for this project. If it is not with regular service it will do the exact same but skip out determining what hour to look at.

Currently this does not build because I am using strings where I should be using times, I was hoping to get some guidance, some examples, and corrections on how to use times correctly to achieve what I'm looking to do. So far I believe my logic to the way this will flow is correct, but I'm stuck getting it to compile.

答案1

得分: 4

由于time.Time是特定时刻的表示,使用它来表示没有日期或时区的任意时钟时间可能会很麻烦。你真正需要的是从00:00开始的持续时间,因此使用time.Duration更合适。你甚至可以使用基于午夜分钟的自定义类型,但如果你使用time.Duration,你将能够更轻松地与time.Time组合使用。

这是一个示例函数,用于解析你的时钟时间和分钟,并返回一个time.Duration

func ParseTime(t string) (time.Duration, error) {
    var mins, hours int
    var err error

    parts := strings.SplitN(t, ":", 2)

    switch len(parts) {
    case 1:
        mins, err = strconv.Atoi(parts[0])
        if err != nil {
            return 0, err
        }
    case 2:
        hours, err = strconv.Atoi(parts[0])
        if err != nil {
            return 0, err
        }

        mins, err = strconv.Atoi(parts[1])
        if err != nil {
            return 0, err
        }
    default:
        return 0, fmt.Errorf("invalid time: %s", t)
    }

    if mins > 59 || mins < 0 || hours > 23 || hours < 0 {
        return 0, fmt.Errorf("invalid time: %s", t)
    }

    return time.Duration(hours)*time.Hour + time.Duration(mins)*time.Minute, nil
}

你还可以将其与自己的类型结合使用,使用相同的基础int64类型,这样你就可以轻松地格式化time.Duration并添加自己的方法。从ParseTime返回Timetime.Duration更方便,这取决于你。这两者可以直接转换。

type Time int64

func (t Time) Hours() int {
    return int(time.Duration(t) / time.Hour)
}

func (t Time) Minutes() int {
    return int((time.Duration(t) % time.Hour) / time.Minute)
}

func (t Time) String() string {
    return fmt.Sprintf("%02d:%02d", t.Hours(), t.Minutes())
}

你可以像这样组合它们:http://play.golang.org/p/E679m2wlUO

英文:

Since time.Time is a particular instant, at a particular location, using it for arbitrary clock time without a day or timezone can be awkward. What you're really looking for is the duration since 00:00, so a time.Duration makes more sense. You could even use your own type based on minutes since midnight for example, but if you use a time.Duration you'll be able to compose your times with time.Time more easily.

Here's an example function to parse your clock times, and minutes into a time.Duration

func ParseTime(t string) (time.Duration, error) {
	var mins, hours int
	var err error

	parts := strings.SplitN(t, &quot;:&quot;, 2)

	switch len(parts) {
	case 1:
		mins, err = strconv.Atoi(parts[0])
		if err != nil {
			return 0, err
		}
	case 2:
		hours, err = strconv.Atoi(parts[0])
		if err != nil {
			return 0, err
		}

		mins, err = strconv.Atoi(parts[1])
		if err != nil {
			return 0, err
		}
	default:
		return 0, fmt.Errorf(&quot;invalid time: %s&quot;, t)
	}

	if mins &gt; 59 || mins &lt; 0 || hours &gt; 23 || hours &lt; 0 {
		return 0, fmt.Errorf(&quot;invalid time: %s&quot;, t)
	}

	return time.Duration(hours)*time.Hour + time.Duration(mins)*time.Minute, nil
}

You can also combine this with your own type, using the same underlying int64 type, so that you can easily format the time.Duration and add your own methods. It's up to you if returning a Time or a time.Duration from ParseTime is more convenient. The two here are directly convertible.

type Time int64

func (t Time) Hours() int {
	return int(time.Duration(t) / time.Hour)
}

func (t Time) Minutes() int {
	return int((time.Duration(t) % time.Hour) / time.Minute)
}

func (t Time) String() string {
	return fmt.Sprintf(&quot;%02d:%02d&quot;, t.Hours(), t.Minutes())
}

You could combine these like so: http://play.golang.org/p/E679m2wlUO

huangapple
  • 本文由 发表于 2015年11月7日 05:25:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/33575967.html
匿名

发表评论

匿名网友

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

确定