Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why calendar week number updates on Monday at 3 a.m., but not at midnight?

I am using iso_week.h from howardhinnant.github.io/iso_week.html to calculate the week number for a given date. However, it looks that it updates the week number on Monday at 3 a.m., instead of midnight.

For example code like this:

#include <iostream>
#include "iso_week.h"

int main() {
    using namespace iso_week;
    using namespace std::chrono;
    /* Assume we have two time points:
     * tp1 corresponds: Monday July 15 02:50:00 2019
     * tp2 corresponds: Monday July 15 03:00:00 2019
     */
    // Floor time points to convert to the sys_days:
    auto tp1_sys = floor<days>(tp1);
    auto tp2_sys = floor<days>(tp2);
    // Convert from sys_days to iso_week::year_weeknum_weekday format
    auto yww1 = year_weeknum_weekday{tp1_sys};
    auto yww2 = year_weeknum_weekday{tp2_sys};
    // Print corresponding week number of the year
    std::cout << "Week of yww1 is: " << yww1.weeknum() << std::endl;
    std::cout << "Week of yww2 is: " << yww2.weeknum() << std::endl;
}

The output is:

Week of yww1 is: W28
Week of yww2 is: W29

Why is this being done?

like image 677
Remis Avatar asked Nov 23 '25 02:11

Remis


1 Answers

At first I didn't notice your comment:

// Floor time points to convert to the sys_days:

This means that tp1 and tp2 are based on system_clock. And system_clock models UTC.

You can use the tz.h header (tz.cpp source) to get your current time zone, convert the UTC time points to local time points, and then feed them to year_weeknum_weekday. This will define the start of the day as your local midnight instead of midnight UTC.

This would look something like:

#include "date/iso_week.h"
#include "date/tz.h"
#include <iostream>

int
main()
{
    using namespace iso_week;
    using namespace date;
    using namespace std::chrono;
    auto tp1 = floor<seconds>(system_clock::now());
    zoned_seconds zt{current_zone(), tp1};
    auto tp1_local = floor<days>(zt.get_local_time());
    auto yww1 = year_weeknum_weekday{tp1_local};
    std::cout << "Week of yww1 is: " << yww1.weeknum() << std::endl;
}

current_zone() queries your computer for its current local time zone setting. If you prefer some other time zone, you can just replace current_zone() with the time zone name:

zoned_seconds zt{"Europe/Athens", tp1};

If you want to work in a precision finer than seconds, zoned_seconds is just a type alias for zoned_time<seconds>. So use whatever precision you need (e.g. zoned_time<milliseconds>).

Use of tz.h does require some installation. It is not header only.

like image 170
Howard Hinnant Avatar answered Nov 25 '25 18:11

Howard Hinnant