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.

Not the answer you're looking for? Browse other questions tagged .