我怎样才能排除周末golang

时间:2015-07-09 20:02:00

标签: go

到目前为止,我已计算使用http://golang.org/pkg/time/的天数,但我不知道如何排除周末,只计算工作日

package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.Now()
    f := time.Date(2015, time.August, 21, 24, 0, 0, 0, time.UTC)
    diff := f.Sub(t)

    // convert diff to days
    days := int(diff.Hours() / 24)

    fmt.Printf("days  %d\n", days)
}

7 个答案:

答案 0 :(得分:1)

这是一个简单的小解决方案。

days := 0
for {
     if (t.Equal(f)) {
         return days
     }
     if (t.Weekday() != 6 && t.Weekday() != 7) {
          days++
     }
     t.Add(time.Hour*24)
}

您可能不想使用原始t变量,但保持示例简单。我循环直到t等于f,如果它们相等,我会返回我的日期计数。如果他们不是我检查以确定它是工作日,并增加我的日期计数,如果是。我无条件地在我的开始时间增加了一天。

答案 1 :(得分:1)

我想要一个不需要循环即可计算天数的解决方案。 (md2perpevincegScott Owens发布的答案对我不起作用,并计算出错误的结果。)

这是不需要循环的解决方案:

(该解决方案分别计算整周和休息日,然后再添加。)

func calculateWorkingDays(startTime time.Time, endTime time.Time) int {
    // Reduce dates to previous Mondays
    startOffset := weekday(startTime)
    startTime = startTime.AddDate(0, 0, -startOffset)
    endOffset := weekday(endTime)
    endTime = endTime.AddDate(0, 0, -endOffset)

    // Calculate weeks and days
    dif := endTime.Sub(startTime)
    weeks := int(math.Round((dif.Hours() / 24) / 7))
    days := -min(startOffset, 5) + min(endOffset, 5)

    // Calculate total days
    return weeks*5 + days
}

func weekday(d time.Time) int {
    wd := d.Weekday()
    if wd == time.Sunday {
        return 6
    }
    return int(wd) - 1
}

func min(a int, b int) int {
    if a < b {
        return a
    }
    return b
}

首先,计算开始日期和结束日期的工作日偏移,并将两个日期都减少到上一个星期一。然后,计算完整周数和宽松天数。 (如果偏移量大于5(星期五),则仅使用5天。)最后,计算总天数。

答案 2 :(得分:0)

这是一个解决方案,谢谢你evanmcdonnal和luc回答

package main

  import (
"fmt"
"time"
)

func main() {
t := time.Date(2015, time.Now().Month(), time.Now().Day(), time.Now().Hour(), time.Now().Minute(), time.Now().Second(), time.Now().Nanosecond()*0, time.UTC)
fmt.Printf("%s\n",t)
f := time.Date(2015, time.August, 22, time.Now().Hour(), time.Now().Minute(), time.Now().Second(), time.Now().Nanosecond()*0, time.UTC)
fmt.Printf("%s\n",f)
days :=0


for{
    if(t.Equal(f)){

        break

    }

    if(t.Weekday()!=6 && t.Weekday()!=0){
        days++

    }
t=t.Add(time.Hour*24)


}




 fmt.Printf("days  %d\n", days)

}

输出32

答案 3 :(得分:0)

最好使用AddDate进行超过24小时的时间计算:

package main

import (
    "fmt"
    "time"
)

func AddWorkDays(t time.Time, workdays int) time.Time {
    curDate := t
    for curWorkdays := 0; curWorkdays <= workdays; {
        curDate = curDate.AddDate(0, 0, 1)
        if curDate.Weekday() != 6 && t.Weekday() != 7 {
            curWorkdays++
        }
    }
    return curDate
}

func main() {
    now := time.Now()
    workdays := 3
    t := AddWorkDays(now, workdays)
    fmt.Printf("  now %-9v %v\n", now.Weekday(), now)
    fmt.Printf("later %-9v %v\n", t.Weekday(), t)
}

我回答的那天输出:

  now Friday    2017-03-10 21:33:28.395198671 +0000 UTC
later Wednesday 2017-03-15 21:33:28.395198671 +0000 UTC

答案 4 :(得分:0)

意识到我们正在计算积分并记住积分通常是使用原始函数计算的,可以将其视为某个固定时间的积分,我们可以编写以下代码。

函数primitive()给出自2000年1月3日以来的工作日数,选择为星期一以简化公式。两天之间的工作日数由两天primitive()的差异给出。

package main

import (
    "fmt"
    "time"
)

type Date struct {
    year int
    month time.Month
    day int
}

func date2unix(d Date, loc *time.Location) int64 {
    return time.Date(d.year, d.month, d.day, 0, 0, 0, 0, loc).Unix()
}

func primitive(d Date, loc *time.Location) int64 {
    // 3 January 2000 was a Monday
    base := Date{2000, time.January, 3}
    seconds := date2unix(d, loc) - date2unix(base, loc)
    weeks := seconds / (7*24*60*60)
    seconds_into_week := seconds % (7*24*60*60)
    workdays := seconds_into_week / (24*60*60)
    if workdays > 5 {
        workdays = 5
    }

    return 5*weeks + workdays
}

func DayCountExcludingWeekends(from, to Date, loc *time.Location) int {
    return int(primitive(to, loc) - primitive(from, loc))
}

func main() {
    loc, err := time.LoadLocation("Europe/Stockholm")
    if err != nil {
        panic(err)
    }

    f := Date{2017, 6, 28}
    t := Date{2017, 7,  6}

    fmt.Println(DayCountExcludingWeekends(f, t, loc))
}

答案 5 :(得分:0)

CalcBusinessDays计算两个日期之间的营业日,而不是假期。 两个日期的计算都包括在内。

func CalcBusinessDays(from *time.Time, to *time.Time) int {

totalDays := float32(to.Sub(*from) / (24 * time.Hour))
weekDays := float32(from.Weekday()) - float32(to.Weekday())
businessDays := int(1 + (totalDays*5-weekDays*2)/7)
if to.Weekday() == time.Saturday {
    businessDays--
}
if from.Weekday() == time.Sunday {
    businessDays--
}

return businessDays
}

答案 6 :(得分:0)

我知道这已经完成了一段时间,但是由于种种原因,我最近不得不确定两个日期之间的工作日数,这可能相隔数十年。

因此,如果有人需要,可以使用O(1)解决方案。

func GetWeekdaysBetween(start, end time.Time) int {
    offset := -int(start.Weekday())
    start = start.AddDate(0, 0, -int(start.Weekday()))

    offset += int(end.Weekday())
    if end.Weekday() == time.Sunday {
        offset++
    }
    end = end.AddDate(0, 0, -int(end.Weekday()))

    dif := end.Sub(start).Truncate(time.Hour * 24)
    weeks := float64((dif.Hours() / 24) / 7)
    return int(math.Round(weeks)*5) + offset
}

但是,如果您想要工作日,则不会考虑到公众假期,这需要一些额外的计划。