Thread: How do I get the first day of the week for the current locale?

  1. #1
    Registered User
    Join Date
    Jul 2012
    Location
    Санкт-Петербург, Russia
    Posts
    1

    Lightbulb How do I get the first day of the week for the current locale?

    How can I get in clear C a first day of week for the current system locale?
    Maybe some winAPI method? But it's better to find universal solution for diferent OS.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Locale info is stored differently in different OSes, so there is no one universal way. For Windows, check out GetLocaleInfo function. I did a quick Google search for *nix, but couldn't find anything. That should get you started at least.

    EDIT: For Linux, there is the locale command (check the section 1 man page). Sample output:
    Code:
    $ locale -k LC_TIME
    abday="Sun;Mon;Tue;Wed;Thu;Fri;Sat"
    day="Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday"
    abmon="Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec"
    mon="January;February;March;April;May;June;July;August;September;October;November;December"
    am_pm="AM;PM"
    d_t_fmt="%a %d %b %Y %r %Z"
    d_fmt="%m/%d/%Y"
    t_fmt="%r"
    t_fmt_ampm="%I:%M:%S %p"
    era=
    era_year=""
    era_d_fmt=""
    alt_digits=
    era_d_t_fmt=""
    era_t_fmt=""
    time-era-num-entries=0
    time-era-entries="S"
    week-ndays=7
    week-1stday=19971130
    week-1stweek=7
    first_weekday=1
    first_workday=2
    cal_direction=1
    timezone=""
    date_fmt="%a %b %e %H:%M:%S %Z %Y"
    time-codeset="UTF-8"
    You can see the entry for first_weekday in green. The 1 corresponds to the first day in abday (abbreviated) and day names. Clearly that information is programatically available, I just don't know how. Given all that stuff is open source, you could look up the source for the locale program to see what it does.
    Last edited by anduril462; 07-06-2012 at 11:41 AM.

  3. #3
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    @anduril462: locale -k LC_TIME always lists Sunday first. If it didn't, how would you know which day was which in other languages and locales?

    Edited: The first_weekday and first_workday fields do provide the correct information, however. In most locales they're a relatively new addition, so you might wish to let the user override it just in case. (I'm getting senile, had to edit this post a few times. Hope you didn't see the garbage versions.)

    The POSIX date-time manipulation functions like strftime have support for all three conventions:
    • %U is the week number, when first day of first week of the year is Sunday,
    • %W is the week number, when first day of first week of the year is Monday
    • %V is the ISO 8601 week number.
      In ISO 8601 standard, the first week of the year is the one that has at least four days. Each week starts on a Monday.


    Although US seems to mostly ignore the ISO 8601 standard, is is very practical: for one, the string dates sort correctly by default. See the ISO 8601 Wikipedia article for details and background. I strongly recommend defaulting to ISO 8601 formats, but allowing the user to override it if they really want to. (Most users only complain up to the first time they need to sort dates; then they're quietly grateful.)

    On POSIX systems, using C, use setlocale(LC_TIME, ""); to set the locale, and then you can use the nl_langinfo() to find out the details. Here is an example program:
    Code:
    #include <stdio.h>
    #include <locale.h>
    #include <langinfo.h>
    
    static inline int first_weekday(void)
    {
        const char *const s = nl_langinfo(_NL_TIME_FIRST_WEEKDAY);
    
        if (s && *s >= 1 && *s <= 7)
            return (int)*s;
    
        /* Default to Sunday, 1. */
        return 1;
    }
    
    static inline int first_workday(void)
    {
        const char *const s = nl_langinfo(_NL_TIME_FIRST_WORKDAY);
    
        if (s && *s >= 1 && *s <= 7)
            return (int)*s;
    
        /* Default to Sunday, 1. */
        return 1;
    }
    
    static const char *wkday(const int d)
    {
        switch (d) {
        case 1: return nl_langinfo(ABDAY_1); /* Sun */
        case 2: return nl_langinfo(ABDAY_2); /* Mon */
        case 3: return nl_langinfo(ABDAY_3); /* Tue */
        case 4: return nl_langinfo(ABDAY_4); /* Wed */
        case 5: return nl_langinfo(ABDAY_5); /* Thu */
        case 6: return nl_langinfo(ABDAY_6); /* Fri */
        case 7: return nl_langinfo(ABDAY_7); /* Sat */
        default: return "";
        }
    }
    
    static const char *weekday(const int d)
    {
        switch (d) {
        case 1: return nl_langinfo(DAY_1); /* Sunday */
        case 2: return nl_langinfo(DAY_2); /* Monday */
        case 3: return nl_langinfo(DAY_3); /* Tuesday */
        case 4: return nl_langinfo(DAY_4); /* Wednesday */
        case 5: return nl_langinfo(DAY_5); /* Thursday */
        case 6: return nl_langinfo(DAY_6); /* Friday */
        case 7: return nl_langinfo(DAY_7); /* Saturday */
        default: return "";
        }
    }
    
    int main(void)
    {
        setlocale(LC_TIME, "");
    
        printf("%s\n", wkday(first_weekday()));
        printf("%s\n", weekday(first_workday()));
    
        return 0;
    }
    The program will output two lines: the abbreviated weekday name for the first day of the week on the first line, and the full weekday name for the first workday of the week on the second line.

    The setlocale(LC_TIME,"") is needed at the start of the program to set up the locale database; using an empty string is just shorthand for "as set in the environment variables". Check the man pages for further functionality; you will need to run it for other locale features too before querying them. After thatis done, *(char *)nl_langinfo(_NL_TIME_FIRST_WEEKDAY); yields the first day of week (1 for Sunday, 2 for Monday, .., 7 for Saturday), and *(char *)nl_langinfo(_NL_TIME_FIRST_WORKDAY); the first workday of the week.

    nl_langinfo() always returns a string. For _NL_TIME_FIRST_WORKDAY and _NL_TIME_FIRST_WEEKDAY, the first character of that string is the numeric value, i.e. the string will be either empty, or contain just \001 to \007.

    These are pretty new features in locale data, so there have been errors in many locales. You might wish to let the user override it using a command-line switch.

    Finally, some example results from running LC_TIME=locale ./program :
    Code:
    $ LC_TIME=C ./program -- POSIX/C locale
    Sun
    Monday
    $ LC_TIME=fi_FI.utf8 ./program -- Finnish locale
    ma
    maanantai
    $ LC_TIME=en_DK.utf8 ./program -- English in Denmark
    Mon
    Monday
    $ LC_TIME=en_US.utf8 ./program -- US English
    Sun
    Monday
    [/COLOR]
    @anduril462: Thanks for your post. Without it, this post of mine would have been completely bogus.
    Last edited by Nominal Animal; 07-06-2012 at 03:13 PM. Reason: Senility.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,436
    mktime(3) - Linux man page

    Pick any date, then update
    foo.tm_mday += 7 - foo.tm_wday;
    then mktime() it again, to check that tm_wday is 0 (for Sunday), or whatever day of the week you want.

    When tm_wday is the right answer, then call strftime(3): format date/time - Linux man page with the appropriate locale-specific formats.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. tolower and locale
    By MK27 in forum C Programming
    Replies: 16
    Last Post: 02-03-2009, 09:05 PM
  2. System locale
    By CodeMonkey in forum C++ Programming
    Replies: 2
    Last Post: 01-03-2009, 01:06 PM
  3. locale information on windows
    By techi_talk in forum C Programming
    Replies: 5
    Last Post: 09-21-2005, 09:20 AM
  4. Changing locale for new users
    By axr0284 in forum Tech Board
    Replies: 0
    Last Post: 12-15-2004, 10:22 AM
  5. e-week, networking, and a 96 hour week...
    By doubleanti in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 02-23-2003, 05:23 PM

Tags for this Thread