Convert "Thu Sep 22 3:50 2016" to "2016-09-22" in Solaris, without GNU date - date

Could someone please suggest a simple and short approach to convert "Thu Sep 22 3:50 2016" to "2016-09-22" in Solaris, through a shell script?
I do not have GNU date available on Solaris as discussed in below post:
Convert date String to number on Solaris shell script gives No such file or directory
I need to query an sql server db, where date is saved in the format, "2016-09-06", hence I need to convert it

Actually, you do have GNU date available but here is anyway one way to achieve this by scripting:
#!/bin/ksh
a="Thu Sep 22 3:50 2016"
echo $a | nawk '
BEGIN {
m=1
m2m["Jan"]=m++;
m2m["Feb"]=m++;
m2m["Mar"]=m++;
m2m["Apr"]=m++;
m2m["May"]=m++;
m2m["Jun"]=m++;
m2m["Jul"]=m++;
m2m["Aug"]=m++;
m2m["Sep"]=m++;
m2m["Oct"]=m++;
m2m["Nov"]=m++;
m2m["Dec"]=m++;
}
{
printf("%s-%02d-%02d\n",$5,m2m[$2],$3)
}'
output:
2016-09-22

Why not use Oracle's sysdate?
select * from your_table where saved_date >= to_char(sysdate,'yyyy-MM-dd')

Related

Is there an issue with Central Africa Time (CAT) PostgreSQL TIMESTAMPTZ conversion?

One of our PostgreSQL 11.4 deployments in Congo uses the CAT timezone (Africa/Kigali +02) and one of our function chokes when trying to convert human-input timestamps to actual TIMESTAMPTZ data.
For example:
SELECT '2019-10-17 00:00:00 CAT'::TIMESTAMPTZ;
ERROR: invalid input syntax for type timestamp with time zone: "2019-10-17 00:00:00 CAT"
LINE 2: SELECT '2019-10-17 00:00:00 CAT'::TIMESTAMPTZ
^
SQL state: 22007
Character: 9
But when I try with CEST (Central European, also +02) it works.
SELECT '2019-10-17 00:00:00 CEST'::TIMESTAMPTZ;
"2019-10-17 00:00:00+02"
Incidentally, converting from epoch to CAT also works
select to_timestamp(1571263200);
"2019-10-17 00:00:00+02"
Version:
"PostgreSQL 11.4 (Ubuntu 11.4-1.pgdg18.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0, 64-bit" on Ubuntu 18.04.2 LTS
For whatever reason, 'CAT' is not valid for input by default, presumably someone felt it was ambiguous or something. You could append the line
CAT 7200 # Central Africa Time
to the file "$SHAREDIR/timezonesets/Default" to make this work.
Or you could create a file "$SHAREDIR/timezonesets/Africa" with the contents:
#INCLUDE Default
#OVERRIDE
CAT 7200 # Central Africa Time
And then set the parameter timezone_abbreviations to 'Africa'.
I am not horologist, you might want to research why CAT is missing before blindly adding it. Also, if you go either of the above routes, you should document it clearly someplace. You will need to repeat the steps you took when you upgrade PostgreSQL, or restore or move your database.
Or, you could preprocess your user input to replace 'CAT' with 'Africa/Kigali'.
Incidentally, converting from epoch to CAT also works
select to_timestamp(1571263200);
"2019-10-17 00:00:00+02"
'CAT' does not appear in your example. So it is not clear what this is an example of.

In Conky, how do I convert from Unix time to hours and minutes? (HH:MM)

Given a Unixtime such as 1551996855 (Thu, 07 Mar 2019 22:14:15 +0000), how can convert and extract just HH:MM, (22:14)?
you could use date for the conversion and specify +%H:%M as the format:
date -d #$"1551996855" +%H:%M
note: the option to use with date will be different than -d if you are not on a Linux system (which uses date from GNU coreutils).. so YMMV

Read and interpret crontab with Perl

I'm writing a Perl program to check if and make sure that some system backup tasks were executed from crontab.
I need to read the crontab and interpret when it was supposed to run, in order to check if that backup was done. Here is an example.
00 03 * * 6 system_backup.sh
Let's suppose this task will generate a file called system_backup_20180510.iso
Then my idea was to store a "desirable date" into a var then compare with that date in the filename. The biggest issue is how to build that desirable date with crontab's day of month field filled up.
What you guys can suggest? Thanks
Note the 5th field: this only runs on Saturday.
Here's something you can do with GNU date:
$ date -d "-1 week saturday 03:00" "+%Y%m%d %H:%M:%S"
20180505 03:00:00
$ date -d "-w week saturday 03:00" "+%Y%m%d %H:%M:%S"
20180518 13:00:00
$ date -d "-2 week saturday 03:00" "+%Y%m%d %H:%M:%S"
20180428 03:00:00
the Schedule::Cron::Events suggestion implemented:
crontab -l | perl -MPOSIX=strftime -MSchedule::Cron::Events -lne '
$cron = Schedule::Cron::Events->new($_);
$prev = strftime("%F %T", $cron->previousEvent());
print "$prev => ", $cron->commandLine();
'

perl DateTime incorrect timezone offset

I have several servers running under centos 6.3 and I faced issue that perl module DateTime treats Europe/Moscow timezone as UTC+3
[ulan#rt-virtual ~]$ perl -MDateTime -e 'print DateTime->now()->set_time_zone("Europe/Moscow"), "\n";'
2013-12-19T11:11:38
but in fact it is UTC+4 and system tools like zdump or date work correctly
[ulan#rt-virtual ~]$ zdump Europe/Moscow
Europe/Moscow Thu Dec 19 12:11:47 2013 MSK
I updated tzdata and DateTime module but it didn't help.
How can I amend this?
Thanks.
Well, DateTime module is doing its magic by following the rules specified in the TimeZone modules specific for each timezone. For Europe/Moscow, the module's is DateTime::TimeZone::Europe::Moscow. The problem is all the files are generated automatically corresponding to the rules existing when a specific version of DateTime module is released.
In this case one very important change - Russia's stopping following DST routines in 2011 - wasn't obviously reflected in that file. So updating - either the whole module or only the relevant TimeZone part - should have fixed the issue.
You can use your systems tzfile(5), using DateTime::TimeZone::Tzfile. Not only does it perform better than DateTime::TimeZone it also removes the need to have redundant data that needs to be in sync.
$tz = DateTime::TimeZone::Tzfile->new('/etc/localtime');
$dt = DateTime->now(time_zone => $tz);

Windows batch file - calculating filename from current date

I would like to create an environment variable to hold a filename something like:
PREFIX-2010-AUG-09.zip
I can get close if I use something like this:
SET filename=PREFIX-%date:~-4,4%-%date:~-7,2%-%date:~0,2%.zip
Result:
PREFIX-2010-08-09.zip
but in this case, I get the month as two digits (08).
Is there any easy trick in Windows batch files to get the three-letter month abbreviation from the numeric month (e.g. 08 for "AUG" = August) ??
Update: this needs to be run on a Windows 2008 R2 Server, and yes, if someone can show me a PowerShell solution, that would work, too :-) Thanks!
This is something like a look up table:
set month_01=JAN
set month_02=FEB
set month_03=MAR
#rem ...
set number=02
for %%a in (month_%number%) do call set month_as_text=%%%%a%%
echo %month_as_text%
The value in %number% in the for loop is used to dereference the matching variable name.
Or even shorter:
set number=02
for /f "tokens=%number%" %%m in ("JAN FEB MAR APR ...") do set month_as_text=%m
echo %month_as_text%
EDIT:
Johannes suggests a shorthand for the 1st version:
set month_01=JAN
set month_02=FEB
set month_03=MAR
#rem ...
set number=02
setlocal enabledelayedexpansion
set month_as_text=!month_%number%!
echo %month_as_text%
You could always do the number-to-text translation by hand, like:
if %MM%==01 set MM=Jan
if %MM%==02 set MM=Feb
if %MM%==03 set MM=Mar
if %MM%==04 set MM=Apr
etc.
The first answer is incorrect for August and September. The reason is that the shell interprets a leading zero as octal, and 08 and 09 are not valid octal numbers. You can see this easily for yourself by running this command:
for /f "tokens=08" %a in ("A B C D E F G H I J") do echo %a
If you replace the 08 above with 09 it will also fail. It will work if you use 07 or 10. A working implementation is as follows:
months=JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
:: get the month as a 2-digit number
set number=%date:~4,2%
:: remove leading zero
for /f "tokens=* delims=0" %%a in ("%number%") do set number=%%a
:: index into array to get month name
for /f "tokens=%number%" %%m in ("%months%") do set month_as_text=%%m
:: print month name
echo %month_as_text%