Custom locale with 12-hour time but Monday as the first day of the week

Hello everyone! I use mainly the en_US.UTF-8 locale, however I like to have Monday as the first day of the week. I’ve been having a lot of trouble trying to somehow declare this configuration in Nix. I’ve tried writing something to create a new locale that copies en_US but changes first_weekday to 2, but if I overwrite en_US.UTF-8, it doesn’t seem to register, and if I create a new locale, glibclocale complains that it doesn’t support it. I’m also not sure if there’s a good way to do this in Nix.

The main problem is that I could, in theory, just change LC_TIME to en_GB.UTF-8 or something, but that changes my default time format to 24-hour time, and I like 12-hour time. As far as I know, there’s no locale that uses 12-hour time but has the first weekday as Monday (correct me if I’m wrong). I could also just turn on imperativeLocale, or just use e.g. en_US and change the first weekday in my applications, but I’d like Nix to manage this, if possible.

Does anyone have any ideas on what I can do? I apologize also that I don’t have the deepest understanding of locale definitions on Linux, so maybe there’s some syntax or something I’m missing. Thanks in advance!

I don’t know if there’s an easier way, but I found one person who made a custom locale:

Specifically, once you make the locale file (they called it en_EU here), you’ll then want to set i18n.glibcLocales to support this new locale.

Also, if you’re thinking more about a specific desktop environment, please share if so; there might be simpler customization you can do that we can inform you about.

Thank you so much for the helpful and really quick response! This looks like a great example; I’ll see if I can adapt it tomorrow.

I’m using Hyprland right now, so I doubt there’s a simpler configuration (though let me know if that’s not the case). Probably the simplest would be to just configure all my applications to use the time I like, but I’d rather invest time to set it globally (and maybe I’ll learn a bit more about my system).

That en_EU locale looks quite cool actually. I think we are many Europeans that want our computers to be using English but use European conventions otherwise. It seems to tick all boxes for me. I wonder why it was archived. I haven’t studied UK or IE locales for comparison though

I managed to achieve what I was wanting, using the en_EU as an example! I wanted to have my locale as a standalone file, so if anyone finds it useful, here is my solution:

{ config, pkgs, ... }:
let
  en_us_mon_definition = ''
    comment_char %
    escape_char /

    LC_IDENTIFICATION
    title      "English locale for the USA, but with Monday as the first day."
    source     ""
    address    ""
    contact    ""
    email      ""
    tel        ""
    fax        ""
    language   "American English"
    territory  "United States"
    revision   "1.1"
    date       "2026-06-27"

    category "i18n:2012";LC_IDENTIFICATION
    category "i18n:2012";LC_CTYPE
    category "i18n:2012";LC_COLLATE
    category "i18n:2012";LC_TIME
    category "i18n:2012";LC_NUMERIC
    category "i18n:2012";LC_MONETARY
    category "i18n:2012";LC_MESSAGES
    category "i18n:2012";LC_PAPER
    category "i18n:2012";LC_NAME
    category "i18n:2012";LC_ADDRESS
    category "i18n:2012";LC_TELEPHONE
    category "i18n:2012";LC_MEASUREMENT
    END LC_IDENTIFICATION

    LC_CTYPE
    copy "en_US"
    END LC_CTYPE

    LC_COLLATE
    copy "en_US"
    END LC_COLLATE

    LC_MONETARY
    copy "en_US"
    END LC_MONETARY

    LC_NUMERIC
    copy "en_US"
    END LC_NUMERIC

    % copied from: https://github.com/lattera/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/localedata/locales/en_US#L4
    LC_TIME
    abday	"Sun";"Mon";"Tue";"Wed";"Thu";"Fri";"Sat"
    day	"Sunday";/
      "Monday";/
      "Tuesday";/
      "Wednesday";/
      "Thursday";/
      "Friday";/
      "Saturday"

    week 7;19971130;1
    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"
    % Appropriate date and time representation (%c)
    d_t_fmt "%a %d %b %Y %r %Z"
    %
    % Appropriate date representation (%x)
    d_fmt   "%m//%d//%Y"
    %
    % Appropriate time representation (%X)
    t_fmt   "%r"
    %
    % Appropriate AM/PM time representation (%r)
    t_fmt_ampm "%I:%M:%S %p"
    %
    % Strings for AM/PM
    %
    am_pm	"AM";"PM"
    first_weekday 2
    END LC_TIME

    LC_MESSAGES
    copy "en_US"
    END LC_MESSAGES

    LC_PAPER
    copy "en_US"
    END LC_PAPER

    LC_NAME
    copy "en_US"
    END LC_NAME

    LC_ADDRESS
    copy "en_US"
    END LC_ADDRESS

    LC_TELEPHONE
    copy "en_US"
    END LC_TELEPHONE

    LC_MEASUREMENT
    copy "en_US"
    END LC_MEASUREMENT
  '';
  # Function to patch glibclocales borrowed from: https://github.com/illdefined/en_EU/blob/483ed0fa469f87c8ea4d1b834f56c6d209bf45d3/flake.nix
  patchLocales = args:
    let glibcLocales =
        if pkgs.glibcLocales == null
        then pkgs.callPackage
          (pkgs.path + "/pkgs/development/libraries/glibc/locales.nix") args
        else pkgs.glibcLocales.override args;
    in glibcLocales.overrideAttrs (base: {
      postPatch = base.postPatch + ''
        echo '${en_us_mon_definition}' > localedata/locales/en_US_MON
        echo 'en_US_MON.UTF-8/UTF-8 \' >>localedata/SUPPORTED
      '';
    });
in
{
  i18n.glibcLocales = patchLocales {
    allLocales = builtins.any (x: x == "all")
      config.i18n.supportedLocales;

    locales = config.i18n.supportedLocales;
  };

  i18n.defaultLocale = "en_US.UTF-8";
  i18n.extraLocaleSettings = {
    LC_TIME = "en_US_MON.UTF-8";
  };
}

Thanks for the help!

1 Like

While I was looking for solutions, I remember seeing somewhere someone mentioned an en_DK locale, which may achieve what you want. Perhaps Europeans who want an English locale are using something like that?

I did some research, and indeed the en_DK locale exist and is part of upstream officially, and appearently kind of popular also outside Denmark. But I will try to create a custom locale now, just like you.

It has some small annoyances, and far too many applications conflate region with locale, so you get danish text from time to time.

Personally, I set it specifically for LC_TIME, which mostly works with occasional surprises.

A proper en_EU would still be awesome, but writing custom locales is a pain and standards bodies don’t care much for non-nationalist self-expression.