Extract day from non standard Unix date - date

I can see that UNIX easily handles a standard date format 'yyyy-mm-dd'. Date function can easily extract day form standard date format like this
date -d '2016-12-9 00:00:00' '+%d'
output: 09
But I can't figure out a way to get the same result using a non-standard date format. My date format is 'mm-dd-yyyy'.

GNU date which you are most likely using because of the -d switch, doesn't allow custom formatting of dates, unlike the FreeBSD version which supports with the -f input_fmt for converting custom date formats.
With GNU date and bit of manipulation with sed, you can achieve what you are trying to do.
Using sed converting your input date in mm-dd-yyyy to a format GNU date can understand.
customDate=$(echo "12-09-2016 00:00:00" | sed 's/\([0-9]\{2\}\)\-\([0-9]\{2\}\)\-\([0-9]\{4\}\) \(.*\)/\3-\1-\2 \4/')
Now customDate will have the date in the format 2016-12-09 00:00:00 format which you can pass to -d flag to get the required date. i.e.
date -d "$customDate" '+%d'
09
Or as a fancy "one-liner" they call it these days, without the use of the temporary variable.
date -d "$(echo "12-09-2016 00:00:00" | sed 's/\([0-9]\{2\}\)\-\([0-9]\{2\}\)\-\([0-9]\{4\}\) \(.*\)/\3-\1-\2 \4/')" '+%d'
09

Related

Unix string to date conversion, what is wrong

I know the topic has already emerged and some of the posts give a good summary like the one here: Convert string to date in bash . Nevertheless, I encounter a problem presented below with an example I should solve:
date +'%d.%m.%y' works as desired and returns 05.12.20 but the inverse operation I should use to convert strings to date fails:
date -d "05.12.20" +'%d.%m.%y'
date: invalid date ‘05.12.20’
and this is exactly what I need. The Unix date formatting I have also checked on https://www.cyberciti.biz/faq/linux-unix-formatting-dates-for-display/ but it seems to be in line with that. What is the problem? I also tried to supply time zone indicators like CEST but they did not solve the problem.
Try
date -d "05-12-20" +'%d.%m.%y'
UNIX date expects either - or / as a date separator.
However, if your input really must be in the format "05.12.20" (i.e. using .), then you can convert it to the format expected by UNIX date:
date -d `echo "05.12.20" | sed 's/\./-/g'` +'%d.%m.%y'

How to print date in MM/DD/YYYY formate in unix?

I'm new to unix and I'm trying to run print the date using:
echo "Purchase date: `date`"
but I keep getting the date in the format
Purchase date: Fri Oct 2 12:21:26 EDT 2020
but I'm trying to get it in the format of MM/DD/YYYY
A quick google search will show you lots of options but I believe you want something like: ~$ date +%m/%d/%Y
~$ 10/02/2020
%[a-z] represents formatting options.
%m - month (01..12)
%d - day of month
%Y - Full Year
'/' - Delimiter
You can see all of the date formatting options by using the help command:
~$ date --help

How to get ISO8601 seconds format from “date” in busybox?

[DISCLAIMER: This question is intended to be in question and answer format. The solution has already been determined and is provided with the question.]
Without adequate examples from the busybox help section, I was unable to determine the how to get date to print out the 'seconds' version of iso8601. The help does not provide examples to help understand the syntax required. Here are different ways that were tried to get the desired format without much luck. How does one get ISO8901 seconds format from the "date" in busybox?
Here is what was tried:
➤ date -I=seconds
➤ date -I SPEC='seconds'
➤ date -I seconds
➤ date -I='seconds'
➤ date -I 'seconds'
➤ date -I['seconds']
➤ date -I TIMESPEC='seconds'
➤ date -I TIMESPEC=seconds
Note I have tried to use the Ubuntu version of date and was able to figure out how to get the iso8601=seconds format of date, but not in busybox...
Here is what the help of date shows for Busybox 1.22.1:
BusyBox v1.22.1 (2014-09-26 07:33:17 CEST) multi-call binary.
Usage: date [OPTIONS] [+FMT] [TIME]
Display time (using +FMT), or set time
[-s,--set] TIME Set time to TIME
-u,--utc Work in UTC (don't convert to local time)
-R,--rfc-2822 Output RFC-2822 compliant date string
-I[SPEC] Output ISO-8601 compliant date string
SPEC='date' (default) for date only,
'hours', 'minutes', or 'seconds' for date and
time to the indicated precision
-r,--reference FILE Display last modification time of FILE
-d,--date TIME Display TIME, not 'now'
-D FMT Use FMT for -d TIME conversion
The documentation (i.e., date --help) is confusing. Example usages in the documentation can help reduce this confusion and at least help socialize the syntax.
The main difference from the above examples is a "space" that messes up the command. See below:
➤ date -I 'seconds'
date: invalid date 'seconds'
Was off by a hair. It needed a space removed:
➤ date -I'seconds'
2017-07-09T17:29:54-0400
Now busybox date is happy.

How to get ISO8601 seconds format from "date" in busybox?

Without adequate examples I keep going around in circles to get the 'seconds' version of iso8601 printed out by 'date'. Please look at the help that is provided with date with busybox 1.22.1. I can't seem to understand the syntax required. Examples speaks louder than words in my experience and I haven't found anything that could be useful online.
Here is what I tried:
➤ date -I=seconds
➤ date -I SPEC='seconds'
➤ date -I seconds
➤ date -I='seconds'
➤ date -I 'seconds'
➤ date -I['seconds']
➤ date -I TIMESPEC='seconds'
➤ date -I TIMESPEC=seconds
Note I have tried to use the Ubuntu version of date and was able to figure out how to get the iso8601=seconds format of date, but not in busybox...
Here is what the help of date shows for Busybox 1.22.1:
BusyBox v1.22.1 (2014-09-26 07:33:17 CEST) multi-call binary.
Usage: date [OPTIONS] [+FMT] [TIME]
Display time (using +FMT), or set time
[-s,--set] TIME Set time to TIME
-u,--utc Work in UTC (don't convert to local time)
-R,--rfc-2822 Output RFC-2822 compliant date string
-I[SPEC] Output ISO-8601 compliant date string
SPEC='date' (default) for date only,
'hours', 'minutes', or 'seconds' for date and
time to the indicated precision
-r,--reference FILE Display last modification time of FILE
-d,--date TIME Display TIME, not 'now'
-D FMT Use FMT for -d TIME conversion
The documentation (i.e., the help) is confusing and doesn't lead to a pleasant experience for a simple functionality. Instead the documentation needs to be re-written such that example command line inputs are also a part of help (at least to get the syntax down). In any case, I answered my own question.
The main and very subtle difference in one of my tries that I happened to miss:
➤ date -I 'seconds'
date: invalid date 'seconds'
Was off by a hair. It needed to remove the space:
➤ date -I'seconds'
2017-07-09T17:29:54-0400
Now busybox date is happy.

How can I change the format of a date from the command line?

What's the quickest way to convert a date in one format, say
2008-06-01
to a date in another format, say
Sun 1st June 2008
The important bit is actually the 'Sun' because depending on the dayname, I may need to fiddle other things around - in a non-deterministic fashion. I'm running GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0).
[Background: The reason that I want to do it from the command line, is that what I really want is to write it into a TextMate command... It's an annoying task I have to do all the time in textMate.]
$ date -d '2005-06-30' +'%a %F'
Thu 2005-06-30
See man date for other format options.
This option is available on Linux, but not on Darwin. In Darwin, you can use the following syntax instead:
date -j -f "%Y-%m-%d" 2006-06-30 +"%a %F"
The -f argument specifies the input format and the + argument specifies the output format.
As pointed out by another poster below, you would be wise to use %u (numeric day of week) rather than %a to avoid localization issues.
Reading the date(1) manpage would have revealed:
-j Do not try to set the date. This allows you to use the -f flag
in addition to the + option to convert one date format to another.
Thanks for that sgm. So just so I can come back to refer to it -
date -j -f "%Y-%m-%d" "2008-01-03" +"%a%e %b %Y"
^ ^ ^
parse using | output using
this format | this format
|
date expressed in
parsing format
Thu 3 Jan 2008
Thanks.
date -d yyyy-mm-dd
If you want more control over formatting, you can also add it like this:
date -d yyyy-mm-dd +%a
to just get the Sun part that you say you want.
date -d ...
doesn't seem to cut it, as I get a usage error:
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
I'm running GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0), and as far as the man goes, date -d is just for
-d dst Set the kernel's value for daylight saving time. If dst is non-
zero, future calls to gettimeofday(2) will return a non-zero for
tz_dsttime.
If you're just looking to get the day of the week, don't try to match strings. That breaks when the locale changes. The %u format give you the day number:
$ date -j -f "%Y-%m-%d" "2008-01-03" +"%u"
4
And indeed, that was a Thursday. You might use that number to index into an array you have in your program, or just use the number itself.
See the date and strftime man pages for more details. The date manpage on OS X is the wrong one, though, since it doesn't list these options that work.