Skip to content

time: add weekday helper functions #25469

@vituchon

Description

@vituchon

#Perhaps in future editions it would be nice to have a convenient function to get the following (or previous) week day of a given one.

Current Behaviour

As a client of time.Util library, for a given day if i rqquire to calculate the following one

today := time.Now()
tomorrow := today.Add(time.Duration(24) * time.Hour) // adds a day duration, could use (time.Time).AddDate  if really want to avoid the lead second
tomorrowWeekDay := tomorrow.WeekDay()

Motivation

the func (t Time) Weekday() Weekday does non-linear calculations (i do take a look at the code and see the logic behind and it is not trivial, and the order of the function could match a binary search "O(log n)" as the func (l *Location) lookup(sec int64) (name string, offset int, isDST bool, start, end int64) may be called during the process (look for l.lookup(sec) in time.Time source file) that could be simplified in the context of iterating through weekdays in a circular fashion (either forward or backward).

Possible Solution

// Gets the next week day, following golang time.WeekDay values convention
func next(day time.Weekday) time.Weekday {
	return time.Weekday((int(day) + 1) % 7)
}

The above was my implementation that works on my project.
As the language specs forbids: i can't use WeekDay as type receiver, thus, extending and binding the functionality to the concrete type; so i resort to write my own utility func.

Additional Test Code

func TestNextWeekDayWorks(t *testing.T) {
	// an entire loop over the week is enought to prove it works as it cover all posible values
	sunday := time.Sunday
	monday := getNextAndAssert(t, sunday, time.Monday)
	tuesday := getNextAndAssert(t, monday, time.Tuesday)
	wednesday := getNextAndAssert(t, tuesday, time.Wednesday)
	thursday := getNextAndAssert(t, wednesday, time.Thursday)
	friday := getNextAndAssert(t, thursday, time.Friday)
	saturday := getNextAndAssert(t, friday, time.Saturday)
	getNextAndAssert(t, saturday, time.Sunday)
}

func getNextAndAssert(t *testing.T, currentDay time.Weekday, expectedNextDay time.Weekday) (calculatedNextDay time.Weekday) {
	calculatedNextDay = next(currentDay)
	if calculatedNextDay != expectedNextDay {
		t.Errorf("Not equals.\nCalculated is: '%v', while expected is: '%v'", calculatedNextDay, expectedNextDay)
	}
	return
}

Context

My motivation arises for three reasons:

  1. by beign working with medical agendas that have plenty of relative time intervals (e.g: per day of week availability), and when the times comes to calculate the actual availabilties in a given lapse of time (that are consecutive days) i do find proper to work with time.WeekDay type in order to retrieve the relative availability information for the correspondent day.
  2. I would like to think that other persons already face or faced this scenario, i mean: to face the need of sequentially iterate over week days starting from a given absolute time.
  3. Need to be aware of golang convetion changes for days in a week concrete integer values.

I would love to receive some feedback about this including other professional's point of views.
Thanks and hope you find useful something of what i have just share.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions