到目前为止,我已计算使用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)
}
答案 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)
我想要一个不需要循环即可计算天数的解决方案。 (md2perpe
,vinceg
和Scott 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
}
但是,如果您想要工作日,则不会考虑到公众假期,这需要一些额外的计划。