date '+%p' AM/PM indicator is wrong case on Fedora 20 - date

This is rather esoteric. But I have a test which tests the string of a formatted timestamp, so it's bugging me.
date's man page indicates that
%p locale's equivalent of either AM or PM; blank if not known
%P like %p, but lower case
However, on Fedora 20:
$ date
Mon 27 Oct 22:44:22 AEDT 2014
$ date '+%p %P'
pm pm
$ TZ=Europe/Madrid date '+%p %P'
pm pm
The %p is not uppercase as it should be.
On Ubuntu 14.04 the behaviour is correct:
$ date
Mon Oct 27 12:20:08 CET 2014
$ date '+%p %P'
PM pm
$ TZ=Australia/Melbourne date '+%p %P'
PM pm
They both have the same version (8.21). Any suggestions on where to look next?

My colleagues managed to track it down to the language setting:
$ LANG=en_AU.UTF-8 date '+%p %P'
AM am
$ LANG=en_GB.UTF-8 date '+%p %P'
am am
Now to figure out where to file a bug report...

Related

the rules of find -cmin 0 and -ctime 0

I was studying the command find, and I saw:
-cmin n
File's status was last changed n minutes ago.
-ctime n
File's status was last changed n*24 hours ago.
but when n is zero, comes the difference, is there a sound explanation for this behavior?
$ date
Thu 23 Jul 2020 02:16:17 PM CST
$
$ touch a
$ find -name a -cmin 0
$ find -name a -cmin 1
./a
$ find -name a -ctime 0
./a
$ find -name a -ctime 1
$
$ date
Thu 23 Jul 2020 02:16:18 PM CST
$

Why does having the time in GNU date break "- 1 day"?

This converts the given datetime to epoch time (seconds)
date -d"2015-07-24 11:29:00" +%s
// gives 1437762540
Now I want to do the same thing, but subtract a day. Normally, this is as simple as adding "- 1 day". However, instead of subtracting a day, it actually adds a day.
date -d"2015-07-24 11:29:00 - 1 day" +%s
// gives 1437848940 (notice, this value is great than the one above)
If I take away the time portion from my timestamp it works great. The time portion seems to break it however. I know I can do this in two separate steps and avoid this problem. However, I was hoping to do it in one command. Is this possible?
There is some ambiguity in the date command about how to interpret the - 1 token in your date string. It resolves it as a time zone specification
$ date -d "2015-07-24 11:29:00 -1"
Fri Jul 24 08:29:00 EDT 2015
$ date -d "2015-07-24 11:29:00 UTC-1"
Fri Jul 24 08:29:00 EDT 2015
$ date -d "2015-07-24 11:29:00 - 2"
Fri Jul 24 09:29:00 EDT 2015
$ date -d "2015-07-24 11:29:00 UTC-2"
Fri Jul 24 09:29:00 EDT 2015
$ TZ=UTC date -d "2015-07-24 11:29:00 -1"
Fri Jul 24 12:29:00 UTC 2015
(your results may vary depending on your TZ setting)
The day part is then interpreted to mean add one day
$ date -d "2015-07-24 11:29:00 - 1 day"
Sat Jul 25 12:29:00 EDT 2015
$ date -d "2015-07-24 11:29:00 UTC-1 + 1 day"
Sat Jul 25 12:29:00 EDT 2015
Add a timezone spec to your date string, as #amdixon suggests, to resolve the ambiguity and get the expected results.
For reference, the GNU coreutils info page for "Date input formats": https://www.gnu.org/software/coreutils/manual/html_node/Date-input-formats.html
I don't have a precise answer. I do know that free-form datetime parsing is hard. Playing around with date:
$ date -d"2015-07-24 11:29:00 - 1 day" "+%F %T"
2015-07-25 08:29:00
$ date -d"2015-07-24 - 1 day" "+%F %T"
2015-07-23 00:00:00
$ date -d"11:29:00 - 1 day" "+%F %T"
2015-07-25 08:29:00
$ date -d"2015-07-24 - 1 day 11:29:00" "+%F %T"
2015-07-23 11:29:00
So, subtracting a day from a date seems to work, but subtracting a day from a time is problematic.

Why piped arguments to date command are not correctly processed?

I have the problem illustrated in the following code snippet:
$ echo "2014-10-26 23:24:38.3123123" | date -d -
Sun Oct 26 00:00:00 EDT 2014
$ date -d "2014-10-26 23:24:38.3123123"
Sun Oct 26 23:24:38 EDT 2014
As you can see, the hour/min/seconds information is not picked up when I pipe in data with echo, but it is picked up when I use it as a command line argument. I am sure that there is something dumb I am not noticing, but if anyone can enlighten me on what that is it would be much appreciated!
When you write:
$ echo "2014-10-26 23:24:38.3123123" | date -d -
The space character between 2014-10-26 and 23:24:38.3123123 is treated like an argument separator and the date command takes the date string as two different arguments.
You can simply escape this space character:
$ echo "2014-10-26\ 23:24:38.3123123" | date -d -
and it works;
Sun Oct 26 23:24:38 EDT 2014

hp-ux how to get 2 hours ago bash datetime

we are using hp-ux servers
we need to get 2 hours ago datetime value in bash shell script ?
how can i do that any experiences ?
date -d -2hours; date --version
Thu Apr 14 02:38:08 CEST 2011
date (GNU coreutils) 7.4
I'm not a shell script expert, but you may want to check this site at unix.com. They provide this example for subtracting from dates:
# subtract from any date
date --date "$dte 3 days 5 hours 10 sec ago"
date --date "$dte -3 days -5 hours -10 sec"

How can I convert a file full of unix time strings to human readable dates?

I am processing a file full of unix time strings. I want to convert them all to human readable.
The file looks like so:
1153335401
1153448586
1153476729
1153494310
1153603662
1153640211
Here is the script:
#! /bin/bash
FILE="test.txt"
cat $FILE | while read line; do
perl -e 'print scalar(gmtime($line)), "\n"'
done
This is not working. The output I get is Thu Jan 1 00:00:00 1970 for every line. I think the line breaks are being picked up and that is why it is not working. Any ideas? I'm using Mac OSX is that makes any difference.
$ perl -lne 'print scalar gmtime $_' test.txt
Wed Jul 19 18:56:41 2006
Fri Jul 21 02:23:06 2006
Fri Jul 21 10:12:09 2006
Fri Jul 21 15:05:10 2006
Sat Jul 22 21:27:42 2006
Sun Jul 23 07:36:51 2006
Because $line is in single quotes, it's not being processed by bash, and so $line is treated as an (undefined) Perl variable rather than a bash variable.
You don't need a while read bash loop; Perl can do the looping itself using its -n option.
perl -nE 'say scalar(gmtime($_))' test.txt
(using -E to enable say, which automatically appends a newline)
Don't use cat.
#! /bin/bash
file="test.txt"
while read line
do
date -d #$line
done < "$file"
It's not the line breaks, it's that the $line inside the Perl script is a different variable than the $line in the bash script. You could try:
perl -e "print scalar(gmtime($line)),qq/\\n/"
Note the double-quotes, which allow bash to do variable interpolation.
No need for Perl:
awk '{ print strftime("%c", $0) }' somefile.txt
The issue is that you haven't assigned anything to the $line variable, so it defaults to a zero-value, which is why you always get Thu Jan 1 00:00:00 1970 as an output.
gbacon's answer is about as slick as it gets in Perl.
GNU date/xargs solution:
xargs -i date -d "1970-01-01 00:00:00 {} seconds" </tmp/timestamps
This simple command will do
cat time.txt | while read line; do date -ud #$line; done > string.txt
Not forgetting that localtime() can be used instead of gmtime() in Perl
So, if you're not in Greenwich in Winter, you can use localtime(), e.g.
Perl code:
my $unixtime = 1417014507;
my $humantime = localtime($unixtime);
print "\$humantime = $humantime \n";
output:
$humantime = Wed Nov 26 15:08:27 2014