This question already has answers here:
Convert date time string to epoch in Bash
(6 answers)
Closed 4 years ago.
I know the command is date +%s -d "xxx"
But how do I convert 11/03/2018 02:44:58 to epoch ?
root#AngelBeats:~# date +%s -d "11/03/2018 02:44:58"
date: invalid date '11/03/2018 02:44:58'
Edit: For Linux
date --date="11/03/2018 8:15:00" +"%s"
1520736300
This should do it.(For OSX Systems)
date -j -f "%d/%m/%Y %H:%M:%S" "11/03/2018 8:15:00" +"%s"
1520736300
The "-f" specifier can be used to set the format.
-j is for BSD systems. On Linux, use this:
date -d "11/03/2018 8:15:00" +"%s"
Related
This question already has answers here:
Date arithmetic in Unix shell scripts
(14 answers)
How do I do date math in a bash script on OS X Leopard?
(8 answers)
Calculating time (adding minutes) bash
(1 answer)
Subtract days from a date in Bash
(7 answers)
Closed 4 years ago.
I have a file that contains date values. I want to be able to pull the last line of the file, formatted like "'2018-09-18 16:42:57'" add 1 day to it and store that into a variable. The code I have right now looks like the following, but it does not work:
start_date=$(tail -n 1 run_dates.txt)
start_date=$(start_date -d "+1 day")
What is the correct syntax to do this?
You can use this one-liner gnu date command to extract last line of the file, add one day and store output in a variable:
start_date=$(date -d "$(tail -n 1 run_dates.txt) +1 day" '+%Y-%m-%d %T')
To check variable content use:
declare -p start_date
declare -- s="2018-09-19 11:42:57"
I have the following time format
"2014-06-02T16:23:13+02:00"
I want to convert it to the unix timestamp (since 1/1/1970). For the above example, The command should return:
1401725705
Are there a linux command for that?
date -d"2014-06-02T16:23:13+02:00" +%s
should work if you have a newer GNU coreutil. I tested with v8.22 latest.
if you are on a elder coreutil box like 8.4. it won't work, you could try replace the T with space. use string "2014-06-02 16:23:13+02:00" in date -d"2014-06-02 16:23:13+02:00" +%s
this is tested on Red Hat Enterprise Linux Server release 6.5 (Santiago) with coreutil 8.4
$>date -d"2014-06-02 16:23:13+02:00" +%s
1401718993
date -d"2014-06-02T16:23:13+02:00" +%s
As pacholik indicates, %s is the way to convert date to seconds since 1970-01-01 00:00:00 UTC.
You can try either of these (note the usage of -d or --date=, as well as %s with + in or outside the quotes:
$ date --date="2014-06-02T16:23:13+02:00" "+%s"
1401718993
$ date --date="2014-06-02T16:23:13+02:00" +"%s"
1401718993
$ date -d"2014-06-02T16:23:13+02:00" +"%s"
1401718993
As a side note, you can do the opposite with -d#TIME:
$ date -d#1401718993
Mon Jun 2 14:23:13 UTC 2014
I see you were having problems with the T - time designator:
$ date -d"$(sed 's/\(.*\)T\(.*\).*/\1 \2/' <<< "2014-06-02T16:23:13+02:00")" +"%s"
1401718993
This sed gets the string and removes the T in the middle.
$ sed 's/\(.*\)T\(.*\).*/\1 \2/' <<< "2014-06-02T16:23:13+02:00"
2014-06-02 16:23:13+02:00
I have a shell script that runs on Linux and uses this call to get yesterday's date in YYYY-MM-DD format:
date -d "1 day ago" '+%Y-%m-%d'
It works most of the time, but when the script ran yesterday morning at 2013-03-11 0:35 CDT it returned "2013-03-09" instead of "2013-03-10".
Presumably daylight saving time (which started yesterday) is to blame. I'm guessing the way "1 day ago" is implemented it subtracted 24 hours, and 24 hours before 2013-03-11 0:35 CDT was 2013-03-09 23:35 CST, which led to the result of "2013-03-09".
So what's a good DST-safe way to get yesterday's date in bash on Linux?
I think this should work, irrespective of how often and when you run it ...
date -d "yesterday 13:00" '+%Y-%m-%d'
Under Mac OSX date works slightly different:
For yesterday
date -v-1d +%F
For Last week
date -v-1w +%F
This should also work, but perhaps it is too much:
date -d #$(( $(date +"%s") - 86400)) +"%Y-%m-%d"
If you are certain that the script runs in the first hours of the day, you can simply do
date -d "12 hours ago" '+%Y-%m-%d'
BTW, if the script runs daily at 00:35 (via crontab?) you should ask yourself what will happen if a DST change falls in that hour; the script could not run, or run twice in some cases. Modern implementations of cron are quite clever in this regard, though.
Here a solution that will work with Solaris and AIX as well.
Manipulating the Timezone is possible for changing the clock some hours.
Due to the daylight saving time, 24 hours ago can be today or the day before yesterday.
You are sure that yesterday is 20 or 30 hours ago. Which one? Well, the most recent one that is not today.
echo -e "$(TZ=GMT+30 date +%Y-%m-%d)\n$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1
The -e parameter used in the echo command is needed with bash, but will not work with ksh.
In ksh you can use the same command without the -e flag.
When your script will be used in different environments, you can start the script with #!/bin/ksh or #!/bin/bash. You could also replace the \n by a newline:
echo "$(TZ=GMT+30 date +%Y-%m-%d)
$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1
date -d "yesterday" '+%Y-%m-%d'
To use this later:
date=$(date -d "yesterday" '+%Y-%m-%d')
you can use
date -d "30 days ago" +"%d/%m/%Y"
to get the date from 30 days ago, similarly you can replace 30 with x amount of days
Just use date and trusty seconds:
As you rightly point out, a lot of the details about the underlying computation are hidden if you rely on English time arithmetic. E.g. -d yesterday, and -d 1 day ago will have different behaviour.
Instead, you can reliably depend on the (precisely documented) seconds since the unix epoch UTC, and bash arithmetic to obtain the moment you want:
date -d #$(( $(date +"%s") - 24*3600)) +"%Y-%m-%d"
This was pointed out in another answer. This form is more portable across platforms with different date command line flags, is language-independent (e.g. "yesterday" vs "hier" in French locale), and frankly (in the long-term) will be easier to remember, because well, you know it already. You might otherwise keep asking yourself: "Was it -d 2 hours ago or -d 2 hour ago again?" or "Is it -d yesterday or -d 1 day ago that I want?"). The only tricky bit here is the #.
Armed with bash and nothing else:
Bash solely on bash, you can also get yesterday's time, via the printf builtin:
%(datefmt)T
causes printf to output the date-time string resulting from using
datefmt as a format string for strftime(3). The corresponding argu‐
ment is an integer representing the number of seconds since the
epoch. Two special argument values may be used: -1 represents the
current time, and -2 represents the time the shell was invoked.
If no argument is specified, conversion behaves as if -1 had
been given.
This is an exception to the usual printf behavior.
So,
# inner printf gets you the current unix time in seconds
# outer printf spits it out according to the format
printf "%(%Y-%m-%d)T\n" $(( $(printf "%(%s)T" -1) - 24*3600 ))
or, equivalently with a temp variable (outer subshell optional, but keeps environment vars clean).
(
now=$(printf "%(%s)T" -1);
printf "%(%Y-%m-%d)T\n" $((now - 24*3600));
)
Note: despite the manpage stating that no argument to the %()T formatter will assume a default -1, i seem to get a 0 instead (thank you, bash manual version 4.3.48)
You can use:
date -d "yesterday 13:55" '+%Y-%m-%d'
Or whatever time you want to retrieve will retrieved by bash.
For month:
date -d "30 days ago" '+%Y-%m-%d'
As this question is tagged bash "DST safe":
And using fork to date command implie delay, there is a simple and more efficient way using pure bash built-in:
printf -v tznow '%(%z %s)T' -1
TZ=${tznow% *} printf -v yesterday '%(%Y-%m-%d)T' $(( ${tznow#* } - 86400 ))
echo $yesterday
This is a lot quicker on more system friendly than having to fork to date.
From bash version 5.0, there is a new variable $EPOCHSECONDS
printf -v tz '%(%z)T' -1
TZ=$tz printf -v yesterday '%(%Y-%m-%d)T' $(( EPOCHSECONDS - 86400 ))
echo $yesterday
I read the date from a file to a variable. The date has the format ddmmyyyy. It has to be converted to yyyy-mm-dd
I already searched this forum and got this far :
date -d '$DATE' +%F
The problem is the input format is not recognised. Is there any way I can specify the input date format?
On an other forum I found : date -d "${OLD_DATE}" -D "%d%m%Y" +%F
where -D should specify the input format but this doesn't work. But -D is unknown.
thanks for the help and sorry for my English.
You could to it like this:
echo "DDMMYYYY" | awk 'BEGIN {OFS="-"} {print substr($1,5,4), substr($1,3,2), substr($1,1,2)}'
Output:
YYYY-MM-DD
Yes, date understands a lot of formats for -d, but when it's just 8 digits in a row, it interprets it as YYYYmmdd. I'm not sure if you can force it to read it differently, but in this case you can use a simple editor such as awk or sed instead:
$ OLD_DATE='08032011'
$ echo $OLD_DATE | sed -r 's/(.{2})(.{2})(.{4})/\3-\2-\1/'
2011-03-08
This will work on GNU sed. Note that it doesn't check the input (for brevity).
On Linux you can convert a date like "2010-10-02" to a unix timestamp in shell script by
date -d "2010-10-02" "+%s"
Since Mac OS does not have the equivalent -d for date. How do you go about converting a date to a unix timestamp in a shell script.
date +%s
This works fine for me on OS X Lion.
man date on OSX has this example
date -j -f "%a %b %d %T %Z %Y" "`date`" "+%s"
Which I think does what you want.
You can use this for a specific date
date -j -f "%a %b %d %T %Z %Y" "Tue Sep 28 19:35:15 EDT 2010" "+%s"
Or use whatever format you want.
date -j -f "%Y-%m-%d" "2010-10-02" "+%s"
I used the following on Mac OSX.
currDate=`date +%Y%m%d`
epochDate=$(date -j -f "%Y%m%d" "${currDate}" "+%s")
Alternatively you can install GNU date like so:
install Homebrew: https://brew.sh/
brew install coreutils
add to your bash_profile: alias date="/usr/local/bin/gdate"
date +%s
1547838127
Comments saying Mac has to be "different" simply reveal the commenter is ignorant of the history of UNIX. macOS is based on BSD UNIX, which is way older than Linux. Linux essentially was a copy of other UNIX systems, and Linux decided to be "different" by adopting GNU tools instead of BSD tools. GNU tools are more user friendly, but they're not usually found on any *BSD system (just the way it is).
Really, if you spend most of your time in Linux, but have a Mac desktop, you probably want to make the Mac work like Linux. There's no sense in trying to remember two different sets of options, or scripting for the mac's BSD version of Bash, unless you are writing a utility that you want to run on both BSD and GNU/Linux shells.
date -j -f "%Y-%m-%d %H:%M:%S" "2020-04-07 00:00:00" "+%s"
It will print the dynamic seconds when without %H:%M:%S and 00:00:00.
I wrote a set of scripts that provides a uniform interface for both BSD and GNU version of date.
Follow command will output the Epoch seconds for the date 2010-10-02, and it works with both BSD and GNU version of date.
$ xsh /date/convert "2010-10-02" "+%s"
1286020263
It's an equivalent of the command with GNU version of date:
date -d "2010-10-02" "+%s"
and also the command with BSD version of date:
date -j -f "%F" 2010-10-02 "+%s"
The scripts can be found at:
https://github.com/xsh-lib/core/tree/master/functions/date
It's a part of a library called xsh-lib/core. To use them you need both repos xsh and xsh-lib/core, I list them below:
https://github.com/alexzhangs/xsh
https://github.com/xsh-lib/core
To convert a date in UTC to a Unix timestamp:
date -ju -f "%F %T" "2021-03-08 14:56:21" "+%s"