douliao2493 2015-11-06 21:25
浏览 102
已采纳

时间格式化和从字符串转换

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{"06:34", "06:54", "17:09", "17:19"}
var RegularTimes = []string{"05", "50"}

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, "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 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 < 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])
}

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) && 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条回答 默认 最新

  • doutui7955 2015-11-07 02:53
    关注

    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, ":", 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
    }
    

    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("%02d:%02d", t.Hours(), t.Minutes())
    }
    

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了
  • ¥100 H5网页如何调用微信扫一扫功能?