Episode 023 - date

The date command will not only display or let you change the current date and time but is the go to utility for getting date and time information into scripts. Evoked by itself the date command will output the current system date based upon the rules of the LC_TIME format. The LC_TIME format defines the rules for formatting dates and times. LC_TIME is a subset of locale which defines the overall environment based upon the chosen language and cultural conventions. You can see the current LC value by issuing the locale command. You can see time specific information for your system by issueing:

locale -m LC_TIME

This will list the available locales configured for your system. Configuring of the locale values is dependent upon the distribution of Linux you are running. For instance, in Arch Linux you can set the locale by editing the /etc/locale.conf file. On a RedHat based system this value is store in /etc/sysconfig/i18n. On a Debian based system the default locale is stored in /etc/default/locale. Managing locale information is beyond the scope of this article so consult your distrobution’s documentation should you need to change your locale values or set a new default.

For the purpose of this article examples will be shown from the LC_TIME=en_US.UTF-8 value.

The date command issued by itself reports the date in the following format (Abbr stands for abbreviated):

[Abbr Day of Week] [Abr Month] [Month Day]  /
[Hour:Minute:Second] [Timezone] [Year]
Sat Feb 9 11:48:51 EST 2013
%a %b %d %H:%M:%S %Z %Y

The last row is the relates the format controls to date corresponding to the equivalent values displayed on the second line. These will be covered shortly.

The -d, or --date=, parameter takes a string format for a date and returns a value as opposed to the current date. There are many different possible strings to pass for instance:

date -d “2 days”

will return the date string like above but 2 days from the current time:

Mon Feb 11 11:48:51 EST 2013

Issuing:

date -d “2 days ago”

Will return the date string above but from 2 days ago:

Thu Feb 7 11:48:51 EST 2013

Now realize that the actual time would be the time from 2 days prior or 2 days hence from when the date command was run and would not output the exact time string as the first entry. The example was given just an example based off the first date above.

Some of the values you can pass with the -d command are:

  • days
  • months
  • years
  • hours
  • minutes
  • seconds
  • ago

The -f, or --file=, switch operates the same way as the -d but will read a file where each line is a date value in the format of -d. For instance, if there was a file called datefile.txt with the following entries:

3 days ago
1 month
2 hours 9 minutes
Sun

Then:

date -f datetime.txt

Would read each line of the file and output the corresponding values:

Wed Feb 6 12:03:49 EST 2013
Sat Mar 9 12:03:49 EST 2013
Sat Feb 9 14:12:49 EST 2013
Sun Feb 10 00:00:00 EST 2013

The date command will allow you to view the last modification date of a file with the -r, or --refrence=, switch:

date -r datetime.txt

Returns the time the file was last modified:

Sat Feb 9 12:03:45 EST 2013

Before we look at the remaining swtiches to date, let us turn to how the output of date can be formatted differently. The syntax for fomatting the date ouput is as follows:

+%?%?%?

Where ? is a placeholder for a variable. Some of the more common variables are:

  • %a = locale’s abbreviated week day - Mon, Tue, Sun
  • %A = locale’s full weekday name - Monday, Tuesday, Sunday
  • %b = locale’s abbreviated month name - Jan, Feb, Aug, Dec
  • %B = locale’s full month name - January, February, August, December
  • %c = locale’s date and time - Sat Feb 9 12:12:45 2013
  • %C = Century - 21
  • %d = day of the month with leading 0
  • %D = date in the locale format - 02/09/13
  • %e = day of the month with space padding instead of leading 0
  • %F = full date which - 2013-02-09 - equivalent to %Y-%m-%d
  • %H = 24 hour with leading 0 - 00, 08, 12, 18
  • %I = 12 hour with leading 0 - 01, 08, 10, 12
  • %j = day of the year with leading zero’s - 001, 015, 115, 350
  • %m = month with leading 0 - 01, 05, 12
  • %M = minute with leading 0 - 01, 08, 15
  • %p = locale’s equivalent of AM or PM
  • %P = locale’s equivalent of am or pm (note same as %p but lower case)
  • %s = seconds since 1970-01-01 00:00:00 UTC
  • %S = seconds with leading 0
  • %u = day number of day of the week - 1 = Monday, 7 = Sunday
  • %U = week number of the year with Sunday as the first day of the week - 00-53
  • %V = week number of the year with Monday as the first day of the week (ISO week number) - 01 - 53
  • %w = day number of day of the week with Sunday as the first day and numbering from 0 to 6 - 0 = Sunday
  • %W = week number of the year with Monday as teh first day of the week - 00-53
  • %y = last two digits of the year
  • %Y = year as four digits
  • %z = numerical timezone - -0500
  • %Z = alphabetic time zone appbreviation - EST, EDT, PST

The output of most formats is to pad numeric fields with zeros. This can be altered with the following flags:

  • - (hyphen) - do not pad the field - 09 becomes 9
  • _ (underscore) - pad with spaces - 09 becomes ” 9″ (double quotes added to identify space)
  • 0 - pads with zeros - 8 becomes 08
  • ^ - use upper case if possbile - +%^P (pm) becomes +%p (PM)
  • # - use lower case if possible - +%#p (PM) becomes +%P (pm)

Appending a number between the % and variable will specify the width of the field:

date +%Y
date +%2Y
date +%8Y

The following values are returned:

2013
2013
00002013

Note that the second entry date +%2Y did not truncate the date to two characters. Field width will not limit the output but will pad the output.

If your locale supports it there are two more flags that can be applied to some of the format options:

  • E - applied to %c, %C, %x, %X, %y, and %Y - %EY - this will use the locales alternate representation of the value. 
  • 0 - can only be applied to numeric conversions and will use the locale’s alernate numeric system.

To put some of this in perspecitve given our original date output: Sat Feb 9 11:48:51 EST 2013, the following lists the output returned by the specific formatting:

date +%Y = 2013
date +%Y%m%d = 20130209
date +%Y-%m-%d = 2013-02-09
date +%P = pm
date +%w = 6
date +%W = 05
date “+Today is %A have a good day” = Today is Saturday have a good day

Note that the third and last examples add extra content into the format. Any non-variable will be echoed back out in the string. If you want to include a “%” then issue like so: %%:

date “+%A is the 100%% best day”

There are other format tags for date:

  • -R, --rfc-2822 - Sat, 09 eb 2013 14:20:43 -0500
  • -I, --iso-8601= - 2013-02-09
  • --rfc-3339=seconds - 2013-02-09 14:20:43-0500

These three values format the date and time according to their respective specifications. The first two, -R and -I show their defaults and require no further specification. --rfc-3339 requires that you specify a TIMESPEC. You can also specify TIMESPEC for --I using --iso-8601=TIMESPEC. TIMESPEC values between the --iso-8601 and --rfc-3339 differ:

  • date, --iso-8601 and --rfc-3339, just prints date - 2013-02-09
  • hours, --iso-8601 only, prints date and hours - 2013-02-09T14-0500
  • minutes, --iso-8601 only, prints date, hours and minutes - 2013-02-09T14:40-0500
  • seconds, --iso-8601 and --rfc-3339, prints date, hours, minutes and seconds - 2013-02-09T14:40:05-0500 or 2013-02-09T14:40:05-05:00
  • ns (nano-seconds), --iso-8601 and --rfc-3339, prints date, hours, minutes and nano-seconds - 2013-02-09T14:40:05,454325891-0500 or 2013-02-09T14:40:05,454325891-05:00

The -u, or --utc or --universal, flag will output the date in Coordinated Universal Time

date
date -u

Shows the comparison:

Sat Feb 9 14:46:17 EST 2013
Sat Feb 9 19:46:19 UTC 2013

The date command can not only display the date or time but can also set the date and time with the -s, or --set, flag. This of course requires elevated priveleges:

date -s 2013-01-15

This would set the system date and time to:

2013-01-15 00:00:00 EST 2013

But:

date -s “2013-01-15 08:15:44″

Would set the date to:

2013-01-15 08:15:44 EST 2013″

The date command is a fantastic tool available for providing date stamps in your scripts. For example:

#!/bin/bash
if [ -n "$1" ] && [ -e "$1" ]
then
cp $1 $1.`date +%Y%m%d-%H%M%S`
fi

If you save this script as makebkup, make it executable, when called this script will take a file as input using the cp command make a backup using date to create a file name with a time stamp:

makebkup mypoem.txt

This would effectively run:

cp mypoem.txt mypoem.txt.20130209-150823

The date command is a powerful tool to have at your disposal. Check out the man or info pages for the full list of formatting variables.

 


If the video is not clear enough view it off the YouTube website and select size 2 or full screen.  Or download the video in Ogg Theora format:

Thank you very much!

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>