Can I get UTC offset from Unix command line? - unix

I'm writing an autoconf script that needs the current UTC offset. There's no obvious way to get this out of the date program. Is there any straightforward way to get this from a command-line utility, or should I write a test that gets the information and somehow captures it?

Try this, and see whether it works for you:
date +%z

For others doing ISO8601, you might pick some variant of:
date +%Y%m%dT%H%M%S%z # 20140809T092143-0700
date -u +%Y%m%dT%H%M%S%z # 20140809T162143+0000
date -u +%Y%m%dT%H%M%SZ # 20140809T162143Z
I like those because the lack of punctuation supports universal use. Note that the capital Z is 'hard-coded' for UTC - using %Z will put UTC or the other named timezone. If you prefer punctuation:
date +%Y-%m-%dT%H:%M:%S%z # 2014-08-09T09:21:43-0700
date +%Y-%m-%dT%H:%M:%S%:z # 2014-08-09T09:21:43-07:00 - NOT ALL SYSTEMS
date -u +%Y-%m-%dT%H:%M:%S%z # 2014-08-09T16:21:43+0000
date -u +%Y-%m-%dT%H:%M:%S%:z # 2014-08-09T16:21:43+00:00 - NOT ALL SYSTEMS
date -u +%Y-%m-%dT%H:%M:%SZ # 2014-08-09T16:21:43Z
Consult man strftime as supported formats vary. For instance, some systems support inserting colons into the offset using %:z, %::z, or %:::z - only two of my five systems do (Debian, Ubuntu do, but Mac, BusyBox, QNX do not).
And I often go back to https://en.wikipedia.org/wiki/ISO_8601 for reference.

Yes, date can do this:
[tomalak#lolphin:~] date -R
Mon, 02 May 2011 17:37:45 +0100
Or, more specifically:
[tomalak#lolphin:~] date -R | awk '{print $6}'
+0100
[tomalak#lolphin:~] date +%z
+0100
Reading date --help is very useful.

Related

Solaris get minus 5 min logs from trace file with specific timestamp

I have the following CHECK that works fine in Linux (and Unix) to grep for a specific error "java.lang.OutOfMemoryError" the logs of up to -5 min from current date and time:
CHECK=$(awk -v d1="$(date --date="-5 min" "+[%-m/%-d/%y %H:%M:%S:%3N EEST]")" '$0 > d1' trace.log | grep "java.lang.OutOfMemoryError")
The logs have always the following timestamp format at each line (example):
[4/18/16 12:23:57:998 EEST]
I am trying to do the same at Solaris, but I get the following error response:
date: illegal option -- date=-5 min
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
I have been looking for a solution but I cannot find a convenient one yet. I have found some info for date and time manipulation with perl and python, but they are not easy to use and transform to do the same as I need above (especially perl appears to quite tricky, I am not familiar). So, maybe perl and python are not the answer here.
Can you please help me to do the job ?
Thank you.

Last Month Date in Solaris CSH script

As pre requirement, I need to fetch last month date in Unix (solaris) csh.
set Lmit_Date=`date --date='1 month ago' +%Y%m%d`
above command will fetch last month date and working fine in Linux server. But our server is Solaris and mentioned command is not working.
Please can anyone suggest how I can fetch the last month date
The issue is due to the fact you are using a GNU date extension. --date is non standard.
Moreover, due to the fact month lengths are variable, the date displayed by GNU date might be unexpected, to say the least...
For example today is March 31 but "last month" date was March the 2nd according to GNU date:
$ date +%Y%m%d
20160331
$ date --date='1 month ago' +%Y%m%d
20160302
If you still want to either use GNU date on Solaris or find some workarounds, have a look to these replies:
https://stackoverflow.com/a/23507108/211665 and https://stackoverflow.com/a/17817087/211665
You should be able to compile coreutils for your solaris platform, which will provide you with the right date utility. But as coreutils overwrites core utilities as the name says, you may want to install this into a custom path and select the right date command through your special path, say "/opt/coreutils/bin/date".
The other method would be to calculate last month with a symbolic date output split
eval `date +"set YEAR=%Y; set MONTH=%m ;set DAY=%d"`
Now you can operate on "$YEAR", "$MONTH" and "$DAY". For example
let 'MONTH--'
if [ "$MONTH" -eq 0 ]; then MONTH=12; let 'YEAR--'; fi
set Lmit_Date=`date --date "$MONTH$DAY0000$YEAR" +"%Y%m%d"`
kind of. (I'm used to bash so I don't know if let is available here. But there are some other methods to shell calculations. There might be another keyword for csh).
Also you need to take care for number of days per month with the $DAY parameter.
function last_day {
y=`echo $1 | cut -f1 -d "-"`
m=`echo $1 | cut -f2 -d "-"`
d=`cal ${m} ${y} | nawk 'NF{A=$NF}END{print A}'`
echo "$y $m $d" | nawk '{printf("%s-%02d-%02d",$1,$2,$3);}'
} # last_day
last_day 2023-01-01
Will give you: 2023-01-31 in non-GNU Solaris.

Convert date string to unix timestamp without "date -d" in a shell script

I've been bashing my head into the wall for some time on this one.
I have a date string in my (ksh) script. It's not the current time, it's some arbitrary time.
How can I convert that date string into a Unix timestamp? I'm working on SunOS 5.10 and AIX, which don't have the date -d option, nor the MacOS date -j -f options.
I only need to do this conversion in one place in my code, so ideally I'd like to do it in one line, but if I have to create a function then so be it
I've messed around with Python and Perl to achieve this in one line. Python came the closest, but I couldn't get it to account for time zone, which I would really like. Any help would be much appreciated.
I lost whatever I had been trying to do with Python earlier, but looking back at it I've found a solution:
python -c 'import datetime, time;print time.mktime(datetime.datetime.strptime("08/22/2014/16", "%m/%d/%Y/%H").timetuple())'
This particular command outputs 1408737600, which is 4pm on August 22 2014 on the east coast.

Why does it seem completely random if ls -lrt returns last modifed year or not?

Here are the results of a ls -lrt command in unix:
-rw-r--r-- 1 blah blah 846 Apr 18 2013 filetype1.log
-rw-r--r-- 1 blah blah 290338533 Jan 3 00:59 filetype2.log
Why does one conveniently return the year while the other just has month, day, and time stamp? How can I always get the year?
EDIT:
Here's an example where the last edit time was NOT within the current year and still no year:
-rw-r--r-- 1 blah blah 689466 Dec 31 23:59 filetype2.log
-rw-r--r-- 1 blah blah 689591 Jan 1 00:59 filetype2.log
From the GNU Coreutils manual:
10.1.6 Formatting file timestamps
By default, file timestamps are listed in abbreviated form, using a date
like 'Mar 30 2002' for non-recent timestamps, and a date-without-year
and time like 'Mar 30 23:45' for recent timestamps. This format can
change depending on the current locale as detailed below.
A timestamp is considered to be "recent" if it is less than six
months old, and is not dated in the future. If a timestamp dated today
is not listed in recent form, the timestamp is in the future, which
means you probably have clock skew problems which may break programs
like 'make' that rely on file timestamps.
Based on discussion in comments and chat, you're trying to get the modification time of a file on a remote system in a C# program, and you're not able to install any software on the remote system (which is running HP-UX).
(You also mentioned file creation time, but Unix doesn't store that information, just modification time, access time, and time of most recent inode change).
Since the system doesn't have GNU Coreutils installed, you can't use either ls --time-style=... or the stat command.
But since it does have Perl, you can obtain a file's modification time with a very simple Perl script, using the built-in stat function.
The simplest way to display a timestamp from Perl is as the number of seconds since the Unix epoch, 1970-01-01 00:00:00 GMT; that's also likely to be the simplest format to parse from a C# program.
Create this script on the remote system:
#!/usr/bin/perl
use strict;
use warnings;
foreach my $file (#ARGV) {
my #stat = stat $file;
if (defined $stat[9]) {
print "$stat[9] $file\n";
}
else {
die "$file: $!\n";
}
}
and make it executable (chmod +x script-file-name). You can then invoke it with one or more file names as command-line arguments; for each file, it will print its modification time and its name.
Parsing the output from your C# program is left as an exercise.
If you had the GNU Coreutils stat command, you could do this instead:
stat -c '%Z %n' filename
You can do something similar with ls:
ls --time-style=+%s filename
but that prints additional information and is harder to parse. ls output is intended to be human-readable, not necessarily machine-parsable -- which is probably part of the reason the stat command exists.

Specify input date format for /bin/date

I'm creating Unix bash script that parses web-server log file and inserts this data into database. So I need to convert timestamp which has format "05/Oct/2010:07:38:40 +0400" into "YYYY-mm-dd".
I've tried to use /bin/date -d, but it does not accept given format. I could not find a way to specify input date format for this tool. Is is possible or i should consider alternative solution?
input_date="05/Oct/2010:07:38:40 +0400"
better_date=`echo $input_date | sed -E 's|(..)/(...)/(.{4}).*|\1 \2 \3|'`
date -I -d "$better_date"
You need:
date +%F
Also, this seems to work:
date -d "05 Oct 2010 07:38:40 +0400" +%F
You need to use spaces as separators rather than / or :.

Resources