Tz date format to human readable format - linux

I have a log file containing date and time in the format below
2016-11-03T00:00:18.976926847Z
I would like to change this to more human readable formate, like 2016-11-03 00:00:18

If you have GNU date just do
$ date -d "2016-11-03T00:00:18.976926847Z"
Thu Nov 3 05:30:18 IST 2016
where the -d flag as per the man page
-d, --date=STRING
display time described by STRING, not 'now'
and to format it as you need add the custom format '%Y-%m-%d %H:%M:%S'
$ date -d "2016-11-03T00:00:18.976926847Z" +'%Y-%m-%d %H:%M:%S'
2016-11-03 05:30:18

$ echo 2016-11-03T00:00:18.976926847Z|sed 's/T/ /;s/\..*$//'
2016-11-03 00:00:18

Related

Comparing last modified date of a file and current date in shell script

I am trying to create a new file if the last modified date of the previously created file is less then the current date. Below is the code i tried but not sure getting what value as difference between last modified date and current date.
Code
LAST_MODIFIED_DATE=$(stat -c %y ${APPDIR}/data/XYZ.csv)
echo "LAST_MODIFIED_DATE ${LAST_MODIFIED_DATE}"
NOW=$(date +%s)
echo "NOW ${NOW}"
let diff=${NOW}-${LAST_MODIFIED_DATE}
echo "Diff ${diff}"
Result
LAST_MODIFIED_DATE 2021-08-03 10:30:56.627022878 -0500
NOW 1629354883
Diff 1629354883-2021-08-03 10:30:56.627022878 -0500
You should convert LAST_MODIFIED_DATE in seconds since 1970-01-01 first:
NOW="$(date +%s)"
LAST_MODIFIED_DATE="$(stat -c %y ${APPDIR}/data/XYZ.csv)"
LAST_MODIFIED_DATE_EPOCH="$(date +%s --date="$LAST_MODIFIED_DATE")"
diff=$(($NOW - $LAST_MODIFIED_DATE_EPOCH))
echo "Diff ${diff}"
But diff will be all the time positive unless the file ${APPDIR}/data/XYZ.csv was created with a date in the future.
If you want to test against a different date (for instance to check whether the file has been created in the last hour or not) you can modify the definition of NOW:
NOW="$(date +%s --date '1 hour ago')"

Strange date behaviour in bash

I am trying to add hours to a given datetime in bash and its giving weird results
This is just to check if its parsing the date time correctly
$ date -d "2020-01-21 12:00:00"
Tue 21 Jan 12:00:00 UTC 2020
Now when I try to do date math
$ date -d "2020-01-21 12:00:00 +2 hour"
Tue 21 Jan 11:00:00 UTC 2020
I tried few other operations but similar behaviour.
If I change my format then it behaves correctly for eg.
date -d "12:00:00 2020-01-21 +2 hour"
Tue 21 Jan 14:00:00 UTC 2020
not sure whats going on here.
The +2 is being interpreted as an explicit timezone specifier (equivalent to EET), so date -d "2020-01-21 12:00:00 +2 hour" is interpreted the same as date -d "2020-01-21 12:00:00 EET hour", which adds one hour to the timezone-adjusted time specified.
You can either provide an explicit timezone (as suggested by Maaz) so that +2 hour is syntactically an additional offset, or you can move it to the beginning of the expression, where it can't be parsed as a timezone.
date -d "+ 2 hour 2020-01-21 12:00:00"
Basically you need to pass the timezone in command as well like UTC/CT/IST, so that date command can understand the point of reference to add extra hours.
For example if you are in UTC timezone, then following will produce correct output for you.
date -d "2020-01-21 12:00:00 UTC + 2 hour"

Get last 30 minutes from log file

I have a log file that contain logs as follows
1486307866.155 240207 68.146.231.80 TCP_MISS/200 790 CONNECT clients1.google.com:443 - DIRECT/172.217.6.238 -
1486307866.155 is the time in unix format with corresponds to 2017-02-05 07:17:46 (Format : Y-m-d H:i:s)
I need a unix command that give me the logs within last 30 minutes in the following format and discarding any details that i don't need.
2017-02-05 07:17:46|68.146.231.80|clients1.google.com:443
Using GNU date and GNU awk you can achieve what you want:
awk -v bt=$(date "+%s" -d "30 minutes ago") '$1 > bt {printf("%s|%s|%s\n", strftime("%F %T",$1), $3, $7)} ' yourfile
Explanation:
the date command date "+%s" -d "30 minutes ago" gets the timestamp from 30 minutes ago
the date command is replaced with its output via the command substitution feature $( ... )
the awk option -v passes that timestamp as variable named bt into the awk script
the script prints only those lines from the file having a value in column one ($1) larger than bt in your desired format

Converting time to unix timestamp

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

give the input format when converting a date

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).

Resources