Guide to setting custom date format in (recent versions of) KDE
So I was looking for a way to customize the date format displayed in Dolphin in KDE on my Kali system but it doesn't seem the setting is easily changed. This is managed by locales but none of the preinstalled ones seemed to affect the setting I was trying to change in the way that I wanted it. (That's not to say I didn't overlook it) So! If there is already an easy way to do this, please, call me an idiot and say "Click here next time".
But until then, there doesn't seem to be a very straightforward guide on how to do it. So for a future reference for myself, and anyone else trying to do the same or similar, just follow along. I may add more information about settings that weren't important for me to change, but you may be interested in them.
So far, I have tried this and it has worked on
Kali Linux 2016.2 rolling
KDE Plamsa Version: 5.8.2
KDE Frameworks Version: 5.27.0
QT Version: 5.7.1
Kernel Version: 4.8.0-kali2-amd64
OS Type: 64 bit
Kubuntu 16.10
KDE Plamsa Version: 5.7.5
KDE Frameworks Version: 5.26.0
QT Version: 5.6.1
Kernel Version: 4.8.0-30-generic
OS Type: 64 bit
Specifically, what I am trying to change is the Date format to display DAY(number)/SHORTMONTH(text)/YEAR(number) e.g. 31/JAN/2016 rather than the default (at least, on my installation) MONTH(number)/DAY(number)/YEAR(number) e.g. 31/1/2016
I was going to upload a picture but it seems I can't.
Here is a link
The process is not that long or difficult, but because we are editing files that aren't very human-readable, please be careful of the commands you enter into your terminal
The files we will be dealing with are located in (currently):
* /usr/share/i18n/locales/ (For CentOS/Rhel etc. I believe it is located in /usr/sysconfig/i18n/locales/)
* /etc/locale.gen
Let's go ahead and view our current locale settings
Code:
locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME=en_US.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT=en_US.UTF-8
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
The first thing you'll want to do is cd to the proper directory for your system
Code:
cd /usr/share/i18n/locales
Then we are going to copy one of the existing files to use as a template. I'm just going to copy the one that I'm currently using: en_US
*Note: custom can be any name you'd like.
Next, we will be editing this file, however, as I mentioned before, it's not particularly human-readable. So we will need to know a few things before hand. To get an idea of what I mean, go ahead and
to see what I mean.
You'll notice the code at the end of the file is rather difficult to decipher.
The particular part I'll be editing is in the section LC_TIME, though the process is (relatively) the same for any other changes you'd like to make. Specfically, the line I'll be editing starts with d_fmt and is responsible for the date format.
Let's go ahead and
Code:
cat custom | grep -B2 d_fmt
% Appropriate date representation (%x)
% "%m/%d/%Y"
d_fmt "<U0025><U0062><U002F><U0025><U0064><U002F><U0025><U0059>"
*Note: if you're not familiar with the command line, cat just means to print the contents of the file to screen and we pipe | that to grep and tell it to print any lines containing the string d_fmt, the -B2 tells it to print the 2 lines before it as well.
Here, in the middle line, is the human-readable(er) format of our date. The arguments here %m/%d/%Y are just to help us out. Note that in this file, lines beginning with % indicate a comment and the rest of the line is ignored when the file is read.
But let's do the first of a couple steps to deciphering exactly what the d_fmt line means, so that we know what we're editing.
We can find the meaning of the arguments that are more human-readable in the date manual. Look for FORMAT and you should a list of characters and their meanings.
Code:
man date
FORMAT controls the output. Interpreted sequences are:
%% a literal %
%a locale's abbreviated weekday name (e.g., Sun)
%A locale's full weekday name (e.g., Sunday)
%b locale's abbreviated month name (e.g., Jan)
%B locale's full month name (e.g., January)
%c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
%C century; like %Y, except omit last two digits (e.g., 20)
%d day of month (e.g., 01)
%D date; same as %m/%d/%y
%e day of month, space padded; same as %_d
%F full date; same as %Y-%m-%d
%g last two digits of year of ISO week number (see %G)
%G year of ISO week number (see %V); normally useful only with %V
%h same as %b
%H hour (00..23)
%I hour (01..12)
%j day of year (001..366)
%k hour, space padded ( 0..23); same as %_H
%l hour, space padded ( 1..12); same as %_I
%m month (01..12)
%M minute (00..59)
%n a newline
%N nanoseconds (000000000..999999999)
%p locale's equivalent of either AM or PM; blank if not known
%P like %p, but lower case
%r locale's 12-hour clock time (e.g., 11:11:04 PM)
%R 24-hour hour and minute; same as %H:%M
%s seconds since 1970-01-01 00:00:00 UTC
%S second (00..60)
%t a tab
%T time; same as %H:%M:%S
%u day of week (1..7); 1 is Monday
%U week number of year, with Sunday as first day of week (00..53)
%V ISO week number, with Monday as first day of week (01..53)
%w day of week (0..6); 0 is Sunday
%W week number of year, with Monday as first day of week (00..53)
%x locale's date representation (e.g., 12/31/99)
%X locale's time representation (e.g., 23:13:48)
%y last two digits of year (00..99)
%Y year
%z +hhmm numeric time zone (e.g., -0400)
%:z +hh:mm numeric time zone (e.g., -04:00)
%::z +hh:mm:ss numeric time zone (e.g., -04:00:00)
%:::z numeric time zone with : to necessary precision (e.g., -04,
+05:30)
%Z alphabetic time zone abbreviation (e.g., EDT)
*Note that I cut to only the FORMAT section for brevity
From here we find (well, you probably could've guessed what these stood for, but other options aren't as easily guessed
) that
%m/%d/%Y translates to
month(1...12)
day of month (e.g., 01)
year
and I want it to be
day of month (e.g., 01)
shortmonth (e.g. Jan, Feb, Mar, etc)
year
or, %d/%b/%Y
where %b gives us our abbreviated month name.
Now we have one more step before this is useable for us, the d_fmt line that we are actually editing is really just our %m/%d/%Y but written in hexadecimal unicode.
A conversion table can be found
here.
Now I know I want to change my %m to %b, and rearrange so that DAY comes before SHORTMONTH.
After a little bit of effort, the "%d/%b/%Y" format that I want turns into <U0025><U0064><U002F><U0025><U0062><U002F><U0025><U0059>
*Note: you may want to edit the %m/%d/%Y as well to reflect the changes you made, just for yourself in the future
You'll quickly see that this can be a time consuming and involved process when done by hand, depending on how many changes you want to make.
Luckily, we can save ourselves a bit of time if you have uni2ascii installed.
This can be done character by character or all at once. Just determine the format that you'd like in the more human-readable format, in my case, that's %d/%b/%Y. The conversion command is uni2ascii -a A -p. This gives us our string in exactly the format we want.
This will give us a blinking cursor on the line below to enter our string. Note that any spaces will be converted literally!
Code:
uni2ascii -a A -p
%d/%b/%Y
<U0025><U0064><U002F><U0025><U0062><U002F><U0025><U0059>
That was faster wasn't it?
So I'm going to
Code:
vim /usr/share/i18n/locales/custom
Hit Esc then type
and hit enter, this will take us to the relevant line starting with d_fmt
(use h and l (lowercase L) to move the cursor left or right, and j or k to move down or up)
Go ahead and higlight the first angle bracket with your cursor and press
. This will delete everything up to the next " in the line. Then just go ahead and enter in the line generated from the ascii2uni command, save, and exit.
If you want to make any other changes, the process is the same, go ahead and make them now, edit commands as necessary for your particular situation.
*Note that the only change I tested is the one mentioned above! The information below is just information I gathered throughout the process and writing this guide! If any changes you make don't seem to work properly, I will do my best to help you out. Also, note that other options are available apart from the ones I explicitly mention, study the man date FORMAT section to figure out your options.
Other notable sections in LC_TIME include:
Code:
cat custom | grep -B2 d_t_fmt
% Appropriate date and time representation (%c)
% "%a %d %b %Y %r %Z"
d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0072><U0020><U0025><U005A>"
U0025=%
U0061=a (abbreviated weekday name (e.g., Sun))
U0020=" "
U0025=%
U0064=d (day of month (e.g., 01))
U0020=" "
U0025=%
U0062=b (abbreviated month name (e.g., Jan))
U0020=" "
U0025=%
U0059=Y (year
U0020=" "
U0025=%
U0072=r (12-hour clock time (e.g., 11:11:04 PM))
U0020=" "
U0025=%
U005A=Z (alphabetic time zone abbreviation (e.g., EDT))
Code:
cat custom | grep -B2 am_pm
% Strings for AM/PM
%
am_pm "<U0041><U004D>";"<U0050><U004D>"
*If you want lower-case am/pm, change the values to 0062, 006D, 0070, 006D, respectively
Code:
cat /usr/share/i18n/locales/custom | grep -B2 -A1 t_fmt_ampm
% Appropriate AM/PM time representation (%r)
% "%I:%M:%S %p"
t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
<U0025><U0070>"
U0025=%
U0049=I (uppercase i) (hour 1...12)
U003A=:
U0025=%
U004D=M (minute 0..59)
U003A=:
U0025=%
U0053=S (second 00..59)
U0020=" " (a literal space)
U0025=%
U0070=p
*If you want a 24 hour clock format, change the "I" (0049) here to "H" (0048), if you want lowercase am/pm change the "p" (0070) here to "P" (0050)
Code:
cat /usr/share/i18n/locales/custom | grep -B2 t_fmt
% Appropriate time representation (%X)
% "%r"
t_fmt "<U0025><U0072>"
*If you want a 24 hour clock format, (e.g. 23:13:4, rather than 11:11:04 PM) change the "r" (0072) here to "X" (0058)
There are many other sections but for the sake of keeping this a (relatively) short guide, I'm only going to mention the rest and their basic functions and leave it to you to do for more granular control.
abday Defines the abbreviated weekday names corresponding to the %a field descriptor
day Defines the full spelling of the weekday names corresponding to the %A field descriptor
abmon Defines the abbreviated month names corresponding to the %b field descriptor
mon Defines the full spelling of the month names corresponding to the %B field descriptor
That's it for LC_TIME. Changes in other locale arguments (e.g. LC_CTYPE, LC_NUMERIC, LC_ADDRESS, etc) can be made similarly. A brief summary of some of them and their purpose can be found at the end.
Code:
vim /etc/locale.gen
and add our new custom locale to the file in the same format as we borrowed our template from, in my case, that ends up being
then in your terminal type
Now locale-gen should have made that a valid locale and you can define each of the lines seen from locale individually. Since I only edited the LC_TIME section, I can
Code:
export LC_TIME=custom.UTF-8
Do this for any other sections you might have changed as well.
On the other hand, I can also use my custom as the system default
Code:
dpkg-reconfigure locales
Ensure your newly created locale definition is selected to be generated here if it isn't already, but that should have been taken care of by our locale-gen command. The next screen is where we set the system default.
You may have to logout and login for the changes to take affect.
Now lets open Dolphin and take a look at the date
And
here we see the change!
and just for good measure, let's check out locale
Code:
locale
LANG=custom.UTF-8
LANGUAGE=custom
LC_CTYPE="custom.UTF-8"
LC_NUMERIC="custom.UTF-8" This category applies to formatting numeric values that are not monetary
LC_TIME=custom.UTF-8
LC_COLLATE="custom.UTF-8"
LC_MONETARY="custom.UTF-8" This category applies to formatting monetary values
LC_MESSAGES="custom.UTF-8" This category applies to selecting the language used in the user interface for message translation
LC_PAPER="custom.UTF-8"
LC_NAME="custom.UTF-8"
LC_ADDRESS="custom.UTF-8"
LC_TELEPHONE="custom.UTF-8"
LC_MEASUREMENT=custom.UTF-8 This category applies to measurement units (e.g. imperial or metric)
LC_IDENTIFICATION="custom.UTF-8"
LC_ALL=
to verify our changes have been made.
That's it! Enjoy your new date format