Change start of calendar week?

This is such a simple thing that I feel like I must be missing something.

At my work the timesheets go Sunday-Monday so in order to actually get my full week of work I can’t use the “Calendar week since end = 0” filtering to get my current week and the default views don’t match the days I need them to. Instead I need to use “Calendar days end less than 7”.

I often find it useful to look back at last week of work too (because I’m forgetful and don’t do my timesheet until Monday… oops) and if I could change the start of the Calendar week I could use the simple filtering of “Calendar week since end = 1” but instead I have to use multiple filters on Calendar Days (to filter out the current week, and then anything before last week.)

So you can use different filtering in order to get the categories to show the dates as I need them but it seems like there could be a setting to change the start of the “Calendar week” from Monday to Sunday and then the problem is solved much faster and simpler.

Is there any way to change the start of the Calendar Week in Grindstone 4?

1 Like

Hello, @MikeD314, welcome to the forum!

This was such an interesting question that I dug into it myself. There’s no obvious way to do this in Grindstone since there just isn’t a way to do it in Grindstone, so don’t feel bad about missing anything – you didn’t. The only alternative is to dive into the code, so let’s do that…

How does that value get set for a time slice in the UI? The code says…

namespace Quantum.Client.Views.Entities
{
    public class ViewPeriod : ViewEntityBase, IViewPeriod, IDisposable
    {
        // A bunch of stuff we don't care about

        internal void RecalculateCalendarProperties(DateTime localNow)
        {
            var nowDate = localNow.Date;
            var endDate = _End.ToLocalTime().Date;
            var daysSinceEnd = (int)((nowDate - endDate).TotalDays);
            if (_CalendarDaysSinceEnd != daysSinceEnd)
                CalendarDaysSinceEnd = daysSinceEnd;
            var weeksSinceEnd = nowDate.GetWeeksSince(endDate);
            if (_CalendarWeeksSinceEnd != weeksSinceEnd)
                CalendarWeeksSinceEnd = weeksSinceEnd;
            var monthsSinceEnd = nowDate.GetMonthsSince(endDate);
            if (_CalendarMonthsSinceEnd != monthsSinceEnd)
                CalendarMonthsSinceEnd = monthsSinceEnd;
        }

        // A bunch more stuff we don't care about
    }
}

It’s using an extension method called GetWeeksSince. What’s that say?

namespace Quantum
{
    public static class Extensions
    {
        // A bunch of stuff we don't care about

        public static DateTime GetWeeksFirstDate(this DateTime dt)
        {
            var firstDayOfWeek = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
            var result = dt.Date;
            while (result.DayOfWeek != firstDayOfWeek)
                result = result.AddDays(-1);
            return result;
        }

        public static int GetWeeksSince(this DateTime dt, DateTime earlierDt)
        {
            var myWeek = dt.GetWeeksFirstDate();
            var earlierWeek = earlierDt.GetWeeksFirstDate();
            return (int)((myWeek - earlierWeek).TotalDays / 7D);
        }

        // A bunch more stuff we don't care about
    }
}

Oh come on, darn developers with all their layers of indirection. Fine. So the real magic is happening in GetWeeksFirstDate? Well, in English it reads:

  1. get the first day of the week according to the date/time format of the current culture
  2. shave off the time of day
  3. while the date isn’t on the first day of the week, walk it back one day
  4. return the date

Okay, seems reasonable, but what does “the date/time format of the current culture” really mean? Let’s break that code up into links:

var firstDayOfWeek = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;

Okay, so, buried deep in that phonebook of technical documentation from Microsoft, we found that the CurrentCulture is determined:

By calling the GetUserDefaultLocaleName function on Windows or the uloc_getDefault function from ICU, which currently calls the POSIX setlocale function with category LC_MESSAGES , on Unix-like systems.

Great, but we still have questions:

  • Is the setting coming from Windows?
  • If so, is there a way to tell Windows what we want the first day of the week to be?
  • If we can find a way to change the setting in Windows, will Grindstone abide by that?

All of those have the same answer!

Okay nice, but how does one change that in Windows?

  1. click or tap the Start button
  2. click or tap the Settings icon (a gear)
  3. click or tap Time & Language
  4. click or tap Region (on the left)
  5. click or tap the Change date formats link
  6. select the desired day under First day of week

Once we restart Grindstone, it will behave in any week-based calculations as though the first day of the week is the one we picked. And, coincidentally, so will all other globalization-aware applications, including Windows itself.

Well, that was a fun adventure! The final outcome was even simpler than you might have expected: Grindstone doesn’t have this setting because Windows already does!

2 Likes

Thanks for such an in-depth (and prompt) response. That certainly does explain the nuts & bolts of it and gives an easy workable solution. (As long as you don’t need your system settings to differ from Grindstone… which, in my case, shouldn’t matter at all. So awesome!)

Cheers!