12

Let me explain you the problem

$ date +%c -d "$d"
Tue 31 Dec 2013 01:13:06 PM CET
$ date +'Today is %F' -d "$d"
Today is 2013-12-31

This solution corresponds to current date.

But I have one variable which stores date other than current date

$Prev_date="Wed Dec 25 06:35:02 EST 2013" 

I am looking for solution to read this date as 2013-12-25 and store it in a variable.

I have tried this:

a=`date --date=$Prev_date '+%y/%m/d'`
echo $a

It's giving this error:

date: illegal option -- date=Wed
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
2
  • Is it possible to call date with a different format string to reach the goal?
    – frlan
    Commented Dec 31, 2013 at 11:31
  • Looks like your version of date does not recognize the --date option. Why don't you use -d "$Prev_date" like your working example? Anyway, please remember to always include your OS. Are you actually on Unix? If so, date is very different to the GNU date that GNU/Linux uses.
    – terdon
    Commented Dec 31, 2013 at 15:47

7 Answers 7

10

I assume you are talking about Bash. If so, then you are missing the " around the arguments of the --date parameter.

Instead of

a=`date --date=$Prev_date '+%y/%m/d'`

try this

a=`date --date="$Prev_date" '+%y/%m/d'`

and I'm guessing the d is supposed to have a %. So then it would be like that:

a=`date --date="$Prev_date" '+%y/%m/%d'`

The reasons why your error showed you the usage of the date command is following:

Without the " around $Prev_date, the variable will be substituted and the command looks like this:

a=`date --date=Wed Dec 25 06:35:02 EST 2013 '+%y/%m/d'`

So only the Wed is taken as argument to --date, while all the other parts of the $Prev_date string are considered separate parameters to the date command. So date says it doesn't know a parameter called Dec and shows you it's help output.

5
  • I am working on ksh and still getting the same error date: illegal option -- date=Mon Dec 30 06:35:02 EST 2013 usage: date [-u] mmddHHMM[[cc]yy][.SS] date [-u] [+format] date -a [-]sss[.fff]
    – Prabhat
    Commented Dec 31, 2013 at 15:30
  • Which operating system are you using? It seems your date command take different parameter than mine (Gentoo Linux)
    – replay
    Commented Dec 31, 2013 at 15:32
  • @user3149144 try to replace date with gdate
    – janos
    Commented Dec 31, 2013 at 16:00
  • gdate is not working for me. I am using SunOS 5.10
    – Prabhat
    Commented Dec 31, 2013 at 16:55
  • 1
    One minor change, you should try and avoid using the back ticks, use $(cmd) now.
    – slm
    Commented Dec 31, 2013 at 16:59
6

The -d option is GNU specific.

Here, you don't need to do date calculation, just rewrite the string which already contains all the information:

a=$(printf '%s\n' "$Prev_date" | awk '{
  printf "%04d-%02d-%02d\n", $6, \
  (index("JanFebMarAprMayJunJulAugSepOctNovDec",$2)+2)/3,$3}')
0
5

If I understand right, you want to save the date, so that you can reuse it later to print the same date in different formats. For this, I propose to save the date in a format that can be easily parsed by the date -d command, and let the date command do the formatting.

As far as I know, the format +%Y%m%d %H:%M:%S is the most platform independent. So let's save the date in this format:

d=$(date '+%Y%m%d %H:%M:%S')

Then later you can print this date in different formats, for example:

$ date +%c -d "$d"
Tue 31 Dec 2013 01:13:06 PM CET
$ date +'Today is %A' -d "$d"
Today is Tuesday
$ date +'Today is %F' -d "$d"
Today is 2013-12-31

UPDATE

If you are given a date string like Wed Dec 25 06:35:02 EST 2013, then you can try to parse it with date -d and change its format, for example:

$ date +%F -d 'Wed Dec 25 06:35:02 EST 2013'
2013-12-25

This works with GNU date. If it doesn't work in your system, you can try the gdate command instead, usually it exists in modern systems.

5
  • Thanks for the above answer. But it doesn't solve my issue. Let me explain you the problem $ date +%c -d "$d" Tue 31 Dec 2013 01:13:06 PM CET $ date +'Today is %F' -d "$d" Today is 2013-12-31 This solution corresponds to correct date. But I have one variable which stores date other than correct date $Prev_date="Wed Dec 25 06:35:02 EST 2013" I am looking for solution as 2013-12-25 and store it in a variable
    – Prabhat
    Commented Dec 31, 2013 at 14:25
  • I see. To be honest you didn't explain yourself very well. Now I understand better what you need and updated my answer. Let me know if you still have problems.
    – janos
    Commented Dec 31, 2013 at 15:01
  • I tried the updated code. Output coming is 2013-12-31. I am using SunOS 5.10
    – Prabhat
    Commented Dec 31, 2013 at 16:54
  • 1
    @user3149144 since you are in Solaris try gdate instead of date. Let me know if that doesn't work.
    – janos
    Commented Dec 31, 2013 at 16:56
  • gdate is not working for me
    – Prabhat
    Commented Dec 31, 2013 at 17:10
2

As others have pointed out, the problem is that the date stored in $C above is being evaluated before being passed into your subshell (by the use of ``), so the subshell is trying to find a literal command named 'Tue' (i.e. the start of your date string).

To fix this, you'll need to pass your date command back into a GNU version of date using the -d option, which will take an existing date as input.

I've illustrated this using your example code above:

C=$(date)
G=$(gdate '+%Y%m%d' -d "$C")

echo "C = $C"
echo "G = $G"

Which outputs

C = Tue Dec 31 10:33:29 EST 2013
G = 20131231

Note: I had to use gdate to get this to work on my system (OS X).

If you don't have a GNU compatible date command, and can't install it for whatever reason, the best you could do would be to manipulate the date string directly, using something like this:

C=$(date)
D=$(echo "$C" | awk -F' ' '{ printf "%s-%s-%s", $6, $2, $3 }')

echo "C = $C"
echo "D = $D"

which produces the following output:

C = Tue Dec 31 12:03:27 EST 2013
D = 2013-Dec-31
2
  • gdate is not working for me, my system is SunOS 5.10
    – Prabhat
    Commented Dec 31, 2013 at 16:52
  • Are you able to you install it? Otherwise, I'm afraid SunOS does not have a compatible date command for what you're trying to accomplish. In which case, you'll need to modify the original date format stored in $C either by producing it with another +format, or by manipulating the string itself.
    – Donovan
    Commented Dec 31, 2013 at 16:54
2

On Mac OS X using the FreeBSD date command you could do the transformation via epoch time:

epoch_time="$(LANG=C TZ='EST' date -j -f "%a %b %d %T %Z %Y" "Wed Dec 25 06:35:02 EST 2013" "+%s")"
a="$(date -r $epoch_time '+%F')
echo "$a"  #  2013-12-25
1

It seems that the first output is G. C already contains the first word of the actual date (Tue), so when you try to execute

`tue …format… `

your shell answers that tue is not a valid command.

$ A=date
$ echo $($A)
Mar 31 déc 2013 12:21:48 CET
$ B=$($A)   
$ echo $B
Mar 31 déc 2013 12:22:12 CET

Try just storing date in your C variable, as I did with A.

And by the way, can't you find better names for them?

1

Assuming you want to store the exact time, using GNU date, I have found the following options can output in a format that date is happy to parse again:

date -R
date --iso-8601=ns         # <-- JavaScript's new Date() does not parse this one
date --iso-8601=seconds
date --rfc-3339=ns
date --rfc-3339=seconds

Note that only the ns options record nanoseconds (although most filesystems only store seconds anyway).

(Out of interest, I also tested them in Node.JS and in Firefox, and only the one indicated failed to parse.)

For example, to read the date of a file into a variable, and then parse and display it:

# Record when bash was compiled into a variable
prev_date="$(date --rfc-3339=ns -r /bin/bash)"

# Parse the variable and display in desired format
echo "Date is: $(date -d "$prev_date" '+%y/%m/%d')"

What I would like to know now: How to do the same with BSD date?

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.