Get hex time stamp from bash script - bash

I would like to convert the current date and time into a hex time stamp, something like:
Tue Feb 2 10:27:46 GMT 2010 converted into 0x6d054a874449e
I would like to do this from a bash script, any idea how I might do that?
Thanks
J

printf '0x%x' $(date +%s)

Without knowing the unit or epoch for your hex timestamp, it's hard to say for sure (and I was slightly confused by your example of "Feb 2" which is not even close to the current date!).
date +%s will convert the current date into a time_t, the number of seconds since the usual Unix epoch (which is midnight on 1st Jan 1970).
printf "0x%x" some_number will convert a value from decimal to hex.
If you need to convert to a different epoch / unit, you will need to do some calculation. You can do arithmetic in bash using $(( expression )):
$ time_t=$(date +%s)
$ echo $(($time_t * 1000))
1284505668000
If you want to convert an arbitrary date (like your "Feb 2 ..." example), rather than the current one, and are happy to assume that you have the GNU version of date, then you can use the -d option along with the +%s output format to do the conversion:
$ date -d 'Tue Feb 2 10:27:46 GMT 2010' +%s
1265106466
An example of putting this all together:
$ time_t=$(date -d 'Tue Feb 2 10:27:46 GMT 2010' +%s)
$ time_t_ms=$(($time_t * 1000))
$ hexstamp=$(printf "0x%x" $time_t_ms)
$ echo $hexstamp
0x1268e38b4d0

Seconds since unix epoch, in hex:
echo "$(date +%s)"|xargs printf "0x%x"
0x59a8de5b
Milliseconds since the epoch:
echo "$(date +%s%N)/1000000"|bc|xargs printf "0x%x"
0x15e3ba702bb
Microseconds:
echo "$(date +%s%N)/1000"|bc|xargs printf "0x%x"
0x55818f6eea775
Nanoseconds:
echo "$(date +%s%N)"|xargs printf "0x%x"
0x14e0219022e3745c

Related

bash: substract a day from a date stored in a variable [duplicate]

I have the following in a shell script. How can I subtract one hour while retaining the formatting?
DATE=`date "+%m/%d/%Y -%H:%M:%S"`
The following command works on recent versions of GNU date:
date -d '1 hour ago' "+%m/%d/%Y -%H:%M:%S"
date -v-60M "+%m/%d/%Y -%H:%M:%S"
DATE=`date -v-60M "+%m/%d/%Y -%H:%M:%S"`
If you have bash version 4.4+ you can use bash's internal date printing and arithmetics:
printf "current date: %(%m/%d/%Y -%H:%M:%S)T\n"
printf "date - 60min: %(%m/%d/%Y -%H:%M:%S)T\n" $(( $(printf "%(%s)T") - 60 * 60 ))
The $(printf "%(%s)T") prints the epoch seconds, the $(( epoch - 60*60 )) is bash-aritmetics - subtracting 1hour in seconds. Prints:
current date: 04/20/2017 -18:14:31
date - 60min: 04/20/2017 -17:14:31
if you need substract with timestamp :
timestamp=$(date +%s -d '1 hour ago');
This work on my Ubuntu 16.04 date:
date --date="#$(($(date +%s) - 3600))" "+%m/%d/%Y -%H:%M:%S"
And the date version is date (GNU coreutils) 8.25
$ date +%Y-%m-%d-%H
2019-04-09-20
$ date -v-1H +%Y-%m-%d-%H
2019-04-09-19
But in shell use as like date +%Y-%m-%d-%H, date -v-1H +%Y-%m-%d-%H
Convert to timestamp (a long integer), subtract the right number of milliseconds, reformat to the format you need.
Hard to give more details since you don't specify a programming language...
If you need change timezone before subtraction with new format too:
$(TZ=US/Eastern date -d '1 hour ago' '+%Y-%m-%d %H:%M')
Here another way to subtract 1 hour.
yesterdayDate=`date -d '2018-11-24 00:09 -1 hour' +'%Y-%m-%d %H:%M'`
echo $yesterdayDate
Output:
2018-11-23 23:09
I hope that it can help someone.
DATE=date -1H "+%m/%d/%Y -%H:%M:%S"

How to subtract two different date formats to get days in bash?

I am working on bash. I have to subtract current date from a given date to get number of days as a difference. The given date is in format m/d/yyyy so instead of 09/26/2015 it is 9/26/2015. So even if I try to convert both dates into same format and subtract it says invalid date format.
date1=$(date +"%F")
date2=$(date -d 11/2/2015 +"%F")
diff=$(date "--date=${date2} -${date1}" +%F)
echo $diff days remaining
This is what I had tried with some variations, but doesn't work. What am I doing wrong? Thanks in advance.
Try this:
let diff=(`date +%s -d 11/2/2015` - `date +%s`)/86400
echo $diff days remaining
there are two problems: converting the user-provided date into a normalized form and calculcating the difference in days.
normalizing date
how date interprets a date-string depends on the current locale.
Try to find a locale that uses your special formatting (%m/%d/%Y):
$ LC_TIME=en_US.UTF-8 date -d 1/2/2015
Fri Jan 2 00:00:00 CET 2015
calculating the difference
bash only can only do integer arithmetic, so convert your date first to some integer representation, do the subtraction and convert the representation to days (if needed).
$ LC_TIME=en_US.UTF-8 \
echo $(( ( $(date -d 11/2/2015 +%s) - $(date +%s)) / (3600*24) ))
32
This uses $(...) instead of ... to function substitution.
It also uses $(( ... )) for evalution of math expression instead of the bashism let x=(), so you can use it in POSIX-conformant shell-scripts (e.g. interpreted by /bin/dash)

Subtract 1 hour from date in UNIX shell script

I have the following in a shell script. How can I subtract one hour while retaining the formatting?
DATE=`date "+%m/%d/%Y -%H:%M:%S"`
The following command works on recent versions of GNU date:
date -d '1 hour ago' "+%m/%d/%Y -%H:%M:%S"
date -v-60M "+%m/%d/%Y -%H:%M:%S"
DATE=`date -v-60M "+%m/%d/%Y -%H:%M:%S"`
If you have bash version 4.4+ you can use bash's internal date printing and arithmetics:
printf "current date: %(%m/%d/%Y -%H:%M:%S)T\n"
printf "date - 60min: %(%m/%d/%Y -%H:%M:%S)T\n" $(( $(printf "%(%s)T") - 60 * 60 ))
The $(printf "%(%s)T") prints the epoch seconds, the $(( epoch - 60*60 )) is bash-aritmetics - subtracting 1hour in seconds. Prints:
current date: 04/20/2017 -18:14:31
date - 60min: 04/20/2017 -17:14:31
if you need substract with timestamp :
timestamp=$(date +%s -d '1 hour ago');
This work on my Ubuntu 16.04 date:
date --date="#$(($(date +%s) - 3600))" "+%m/%d/%Y -%H:%M:%S"
And the date version is date (GNU coreutils) 8.25
$ date +%Y-%m-%d-%H
2019-04-09-20
$ date -v-1H +%Y-%m-%d-%H
2019-04-09-19
But in shell use as like date +%Y-%m-%d-%H, date -v-1H +%Y-%m-%d-%H
Convert to timestamp (a long integer), subtract the right number of milliseconds, reformat to the format you need.
Hard to give more details since you don't specify a programming language...
If you need change timezone before subtraction with new format too:
$(TZ=US/Eastern date -d '1 hour ago' '+%Y-%m-%d %H:%M')
Here another way to subtract 1 hour.
yesterdayDate=`date -d '2018-11-24 00:09 -1 hour' +'%Y-%m-%d %H:%M'`
echo $yesterdayDate
Output:
2018-11-23 23:09
I hope that it can help someone.
DATE=date -1H "+%m/%d/%Y -%H:%M:%S"

Bash: subtracting 10 mins from a given time

In a bash script, if I have a number that represents a time, in the form hhmmss (or hmmss), what is the best way of subtracting 10 minutes?
ie, 90000 -> 85000
This is a bit tricky. Date can do general manipulations, i.e. you can do:
date --date '-10 min'
Specifying hour-min-seconds (using UTC because otherwise it seems to assume PM):
date --date '11:45:30 UTC -10 min'
To split your date string, the only way I can think of is substring expansion:
a=114530
date --date "${a:0:2}:${a:2:2}:${a:4:2} UTC -10 min"
And if you want to just get back hhmmss:
date +%H%M%S --date "${a:0:2}:${a:2:2}:${a:4:2} UTC -10 min"
why not just use epoch time and then take 600 off of it?
$ echo "`date +%s` - 600"| bc; date
1284050588
Thu Sep 9 11:53:08 CDT 2010
$ date -d '1970-01-01 UTC 1284050588 seconds' +"%Y-%m-%d %T %z"
2010-09-09 11:43:08 -0500
Since you have a 5 or 6 digit number, you have to pad it before doing string manipulation:
$ t=90100
$ while [ ${#t} -lt 6 ]; do t=0$t; done
$ echo $t
090100
$ date +%H%M%S --utc -d"today ${t:0:2}:${t:2:2}:${t:4:2} UTC - 10 minutes"
085100
Note both --utc and UTC are required to make sure the system's timezone doesn't affect the results.
For math within bash (i.e. $(( and ((), leading zeros will cause the number to be interpreted as octal. However, your data is more string-like (with a special format) than number-like, anyway. I've used a while loop above because it sounds like you're treating it as a number and thus might get 100 for 12:01 am.
My version of bash doesn't support -d or --date as used above. However, assuming a correctly 0-padded input, this does work
$ input_time=130503 # meaning "1:05:03 PM"
# next line calculates epoch seconds for today's date at stated time
$ epoch_seconds=$(date -jf '%H%M%S' $input_time '+%s')
# the 600 matches the OP's "subtract 10 minutes" spec. Note: Still relative to "today"
$ calculated_seconds=$(( epoch_seconds - 600 )) # bc would work here but $((...)) is builtin
# +%H%M%S formats the result same as input, but you can do what you like here
$ echo $(date -r $calculated_seconds '+%H%M%S')
# output is 125503: Note that the hour rolled back as expected.
For MacOS users you can do the following:
$(date -v -10M +"%H:%M:%S")
Date time without a specific format:
$(date -v -10M)
For non-macOS users:
Date time without a specific format:
date --date '-10 min'

Parse Date in Bash

How would you parse a date in bash, with separate fields (years, months, days, hours, minutes, seconds) into different variables?
The date format is: YYYY-MM-DD hh:mm:ss
Does it have to be bash? You can use the GNU coreutils /bin/date binary for many transformations:
$ date --date="2009-01-02 03:04:05" "+%d %B of %Y at %H:%M and %S seconds"
02 January of 2009 at 03:04 and 05 seconds
This parses the given date and displays it in the chosen format. You can adapt that at will to your needs.
I had a different input time format, so here is a more flexible solution.
Convert dates in BSD/macOS
date -jf in_format [+out_format] in_date
where the formats use strftime (see man strftime).
For the given input format YYYY-MM-DD hh:mm:ss:
$ date -jf '%Y-%m-%d %H:%M:%S' '2017-05-10 13:40:01'
Wed May 10 13:40:01 PDT 2017
To read them into separate variables, I'm taking NVRAM's idea, but allowing you to use any strftime format:
$ date_in='2017-05-10 13:40:01'
$ format='%Y-%m-%d %H:%M:%S'
$ read -r y m d H M S <<< "$(date -jf "$format" '+%Y %m %d %H %M %S' "$date_in")"
$ for var in y m d H M S; do echo "$var=${!var}"; done
y=2017
m=05
d=10
H=13
M=40
S=01
In scripts, always use read -r.
In my case, I wanted to convert between timezones (see your /usr/share/zoneinfo directory for zone names):
$ format=%Y-%m-%dT%H:%M:%S%z
$ TZ=UTC date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-10T00:40:01+0000
$ TZ=America/Los_Angeles date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-09T17:40:01-0700
Convert dates in GNU/Linux
On a Mac, you can install the GNU version of date as gdate with brew install coreutils.
date [+out_format] -d in_date
where the out_format uses strftime (see man strftime).
In GNU coreutils' date command, there is no way to explicitly set an input format, since it tries to figure out the input format by itself, and stuff usually just works. (For detail, you can read the manual at coreutils: Date input formats.)
For example:
$ date '+%Y %m %d %H %M %S' -d '2017-05-10 13:40:01'
2017 05 10 13 40 01
To read them into separate variables:
$ read -r y m d H M S <<< "$(date '+%Y %m %d %H %M %S' -d "$date_in")"
To convert between timezones (see your /usr/share/zoneinfo directory for zone names), you can specify TZ="America/Los_Angeles" right in your input string. Note the literal " chars around the zone name, and the space character before in_date:
TZ=out_tz date [+out_format] 'TZ="in_tz" in_date'
For example:
$ format='%Y-%m-%d %H:%M:%S%z'
$ TZ=America/Los_Angeles date +"$format" -d 'TZ="UTC" 2017-05-10 02:40:01'
2017-05-09 19:40:01-0700
$ TZ=UTC date +"$format" -d 'TZ="America/Los_Angeles" 2017-05-09 19:40:01'
2017-05-10 02:40:01+0000
GNU date also understands hour offsets for the time zone:
$ TZ=UTC date +"$format" -d '2017-05-09 19:40:01-0700'
2017-05-10 02:40:01+0000
This is simple, just convert your dashes and colons to a space (no need to change IFS) and use 'read' all on one line:
read Y M D h m s <<< ${date//[-:]/ }
For example:
$ date=$(date +'%Y-%m-%d %H:%M:%S')
$ read Y M D h m s <<< ${date//[-: ]/ }
$ echo "Y=$Y, m=$m"
Y=2009, m=57
$ t='2009-12-03 12:38:15'
$ a=(`echo $t | sed -e 's/[:-]/ /g'`)
$ echo ${a[*]}
2009 12 03 12 38 15
$ echo ${a[3]}
12
The array method is perhaps better, but this is what you were specifically asking for:
IFS=" :-"
read year month day hour minute second < <(echo "YYYY-MM-DD hh:mm:ss")
Pure Bash:
date="2009-12-03 15:35:11"
saveIFS="$IFS"
IFS="- :"
date=($date)
IFS="$saveIFS"
for field in "${date[#]}"
do
echo $field
done
2009
12
03
15
35
11
instead of using the shell scripting,incorporate in your scripting itself like below wheever you need:
a=date +%Y
b=date +%S
c=date +%H
a will be year
b will be seconds
c will be hours. and so on.
Another solution to the OP's problem:
IFS=' -:' read y m d h m s<<<'2014-03-26 16:36:41'
Converting a date to another format with BSD date and GNU date:
$ LC_ALL=C date -jf '%a %b %e %H:%M:%S %Z %Y' 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
$ gdate -d 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
GNU date recognizes Wed and Mar even in non-English locales but BSD date doesn't.
Converting seconds since epoch to a date and time with GNU date and BSD date:
$ gdate -d #1234567890 '+%F %T'
2009-02-14 01:31:30
$ date -r 1234567890 '+%F %T'
2009-02-14 01:31:30
Converting seconds to hours, minutes, and seconds with a POSIX shell, POSIX awk, GNU date, and BSD date:
$ s=12345;printf '%02d:%02d:%02d\n' $((s/3600)) $((s%3600/60)) $((s%60))
05:25:45
$ echo 12345|awk '{printf "%02d:%02d:%02d\n",$0/3600,$0%3600/60,$0%60}'
05:25:45
$ gdate -d #12345 +%T
05:25:45
$ date -r 12345 +%T
05:25:45
Converting seconds to days, hours, minutes, and seconds:
$ t=12345678
$ printf '%d:%02d:%02d:%02d\n' $((t/86400)) $((t/3600%24)) $((t/60%60)) $((t%60))
142:21:21:18
another pure bash
$ d="2009-12-03 15:35:11"
$ d=${d//[- :]/|}
$ IFS="|"
$ set -- $d
$ echo $1
2009
$ echo $2
12
$ echo $#
2009 12 03 15 35 11
have you tried using cut?
something like this:
dayofweek=date|cut -d" " -f1

Resources