GNU date output specific time - date

I have a date command that outputs the last day of the previous month:
date -d"-1 day 1 $(date +%b)"
Outputs:
Sun Sep 30 00:00:00 BST 2018
How can I change the time part to be 23:59:59 on the same date?

Here is one solutions:
date -d "$(date +%b) -1.0 sec"
Notice the usage of a float and not an integer for the subtraction. This is to avoid timezone problems.

Thanks for the replies, sadly it gave me an error.
I got things working with:
EPOCH=$(date -d "-1 day 1 $(date +%b)" +%s)
END=`echo $EPOCH +86399 | bc -q`
Which gives me the EPOCH at 23:59:59 on the last day of the previous month.

Related

How to print date in MM/DD/YYYY formate in unix?

I'm new to unix and I'm trying to run print the date using:
echo "Purchase date: `date`"
but I keep getting the date in the format
Purchase date: Fri Oct 2 12:21:26 EDT 2020
but I'm trying to get it in the format of MM/DD/YYYY
A quick google search will show you lots of options but I believe you want something like: ~$ date +%m/%d/%Y
~$ 10/02/2020
%[a-z] represents formatting options.
%m - month (01..12)
%d - day of month
%Y - Full Year
'/' - Delimiter
You can see all of the date formatting options by using the help command:
~$ date --help

Perl POSIX returning wrong year

I have the code:
use POSIX qw( strftime );
print POSIX::strftime("%a, %d %b %G %T-0000",localtime(1325427034));
which should output
Sun, 01 Jan 2012 09:10:34-0000
but instead it outputs
Sun, 01 Jan 2011 09:10:34-0000
In a few tests I did, it seems to happen whenever the time is in the first few days of 2010, 2011, or 2012. It works correctly in every other case including the first few days of 2013 and 2014. Is there something I should be doing differently?
%G is subject to ISO_8601 standard,
From perldoc
Consult your system's strftime() manpage for details about these and the other arguments.
man strftime
%G The ISO 8601 week-based year (see NOTES) with century as a decimal number. The 4-digit year corresponding to the ISO week number (see %V). This has the
same format and value as %Y, except that if the ISO week number belongs to the previous or next year, that year is used instead. (TZ)
print POSIX::strftime("%a, %d %b %Y %T-0000",localtime(1325427034));
^__ gives 2012
You want %Y, not %G. %G is intended to be used with %V to show ISO 8601 week numbers, which may start before the beginning of the year or end after it ends.
Example:
use POSIX 'strftime';
print strftime("%Y-%m-%d week %G-%V\n",0,0,0,$_,11,111) for 25..31;
print strftime("%Y-%m-%d week %G-%V\n",0,0,0,$_,0,112) for 1..9;
output:
2011-12-25 week 2011-51
2011-12-26 week 2011-52
2011-12-27 week 2011-52
2011-12-28 week 2011-52
2011-12-29 week 2011-52
2011-12-30 week 2011-52
2011-12-31 week 2011-52
2012-01-01 week 2011-52
2012-01-02 week 2012-01
2012-01-03 week 2012-01
2012-01-04 week 2012-01
2012-01-05 week 2012-01
2012-01-06 week 2012-01
2012-01-07 week 2012-01
2012-01-08 week 2012-01
2012-01-09 week 2012-02

Month ago from a date given a date in bash or perl

I will be reading random dates from a files, I want to substract 4 months from that date. I am programming in Perl but I can use a bash command.
If i have the 10/14/2013 i will get 06/14/2013.
Thanks a lot!
Karem
use DateTime::Format::Strptime qw( );
my $format = DateTime::Format::Strptime->new(
pattern => '%m/%d/%Y',
on_error => 'croak',
);
my $dt = $format->parse_datetime('10/14/2013');
$dt->subtract( months => 4 );
say $format->format_datetime($dt);
$ date '+%m/%d/%Y' --date='02/14/2013 4 month ago'
10/14/2012
The CPAN module Date::Manip is perfect for this sort of thing. Date::Manip is quite powerful in that it understands business days and holidays... and can parse arbitrary date strings like "next Tuesday" or "3rd Thursday in August".
You should give it a shot; I bet you'll find it quite useful.
Here's a short example the solves your current problem:
#!/usr/bin/perl
use Date::Manip;
my $d = new Date::Manip::Date("10/18/2013");
print $d->printf("%c"), "\n";
my $delta = new Date::Manip::Delta("4 months ago");
my $od = $d->calc($delta);
print $od->printf("%c"), "\n";
...and this generates the following output:
Fri Oct 18 00:00:00 2013
Tue Jun 18 00:00:00 2013
Beware of months that have more days in them than others!
Here's an example where subtracting one month gives you an answer that you are probably not expecting
endOfMarch=$(date -d "2017-03-31")
today=$endOfMarch
echo $(date -d "$today -1 month" "+%Y-%m-%d")
2017-03-02
Because February only has 28 days, subtracting one month has effectively created the date 2017-02-31 which obviously doesn't exist and so has spilled over the extra days into March given you 2017-03-02
Depending on what you are trying to solve you can reliably calculate n months ago, by creating a date variable set to the first day of the current month, then subtracting the months.
endOfMarch=$(date -d "2017-03-31")
today=$endOfMarch
firstDayOfMonth=$(date -d "$today" "+%Y-%m-01")
echo $(date -d "$firstDayOfMonth -1 month" "+%Y-%m-%d")
2017-02-01
So now you have the correct Month (i.e. February when subtracting 1 month) and you then have to figure out what Day to set the new date to based on your use case.
So adding/subtracting Months is not as straight forward as one might think

Server strtotime incorrect

Both strtotime and mktime are outputting an incorrect timestamp and it's driving me mad.
If I add the following strtotime('2012-10-09');
I get 1349701200
Which is actually
Mon, 08 Oct 2012 13:00:00 GMT
I'm using my localhost, running MAMP. I'm assuming it's a server timezone issue, or something, but I don't understand why, or how to fix it.
Any help?
strtotime uses default timezone to interpret the string. If you want different timezone you could specify it explicitly or change it for all calls:
<?php
if (date_default_timezone_get()) {
echo 'date_default_timezone: ' . date_default_timezone_get()."\n";
}
echo strtotime('2012-10-09')."\n"; # default timezone
echo strtotime('2012-10-09 UTC')."\n";
date_default_timezone_set('UTC');
echo strtotime('2012-10-09')."\n";
?>
Output
date_default_timezone: Europe/London
1349737200
1349740800
1349740800
POSIX timestamp counts number of seconds since 1970-01-01 00:00:00 UTC. For example, midnight (00:00) in New York may be 20:00 in UTC at this time of year (the same POSIX timestamp). But 00:00 in UTC and 00:00 in New York correspond to different moments in time (different POSIX timestamps). Local clocks follow the Sun usually (roughly speaking) and even if it is night where you are; the Sun shines somewhere on Earth.

Convert seconds to date from Jan 01 1901 in unix/linux

im trying to convert a time stamp in seconds from Jan 01 1901 to the current date.
for example,
time stamp 3465468225 translate to a date in 2010. does anyone know of a way to do this in unix/linux? thanks.
In R, it is as simple as this:
> as.POSIXct(3465468225, origin="1901-01-01")
[1] "2010-10-25 15:03:45 CDT"
>
This uses appropriate wrappers around C-level calls gmtime() / localtime() plus time formatting via strftime().
On GNU and POSIX systems you can obtain the date string using seconds since Epoch (1970-01-01 00:00:00 UTC) as:
$ date --date=#1289495920
Thu Nov 11 12:18:40 EST 2010
You should handle the offset since Jan 01 1901 yourself.