localized output for `date` command - macos

How can I localize output of date command in MacOSX bash environment?
for example, I want to localize following in ru_RU locale:
$ date +"%d %B %Y"
07 April 2011

Could you try this?
LC_ALL=ru_RU date +"%d %B %Y"

I don't have ru_RU installed, so I show it with de/us:
env LC_ALL=en_US.utf8 date +"%d %B %Y" -d +2months
> 07 June 2011
env LC_ALL=de_DE.utf8 date +"%d %B %Y" -d +2months
> 07 Juni 2011

Related

bash command to get current time in given time zone accounting for daylight savings

Is there a bash command that will tell me the current time in a given time zone while accounting for daylight savings? For example, I'm thinking of something like this:
$ getDateTime --region Seattle
2021-01-01-13-30-00
Importantly, I would like it to give me the standard time during the winter and daylight time during the summer, and switch over on the correct days of the year in accordance with the region. Does something like this exist in bash? If not, what about another language?
Set the TZ environment variable to the desired time zone and use the date command.
TZ=US/Pacific date
There are some city names in the timezone database, such as America/New_York and America/Los_Angeles, but it's not very complete and doesn't include Seattle. See https://data.iana.org/time-zones/tzdb-2019c/zone.tab for the master list.
Building on Barmar's answer, here's a bash function you can use:
getDateTime() {
TZ="$1" date '+%Y-%m-%d-%H-%M-%S %Z %z'
}
Sample usage:
getDateTime America/Los_Angeles
getDateTime America/New_York
getDateTime Pacific/Honolulu
getDateTime Asia/Hong_Kong
2022-07-08-18-06-50 PDT -0700
2022-07-08-21-06-50 EDT -0400
2022-07-08-15-06-50 HST -1000
2022-07-09-09-06-50 HKT +0800
Daylight savings times are handled automatically by the system, since the timezone names are timezone-aware.
Your system most likely uses the most up-to-date timezone information from IANA:
https://data.iana.org/time-zones/tzdb/zone.tab
https://ftp.iana.org/tz/tzdb/zone.tab
You can find your system's file of timezone names in:
/usr/share/zoneinfo/zoneinfo.tab
It seems like a really nice idea to map individual country/state/city names or latitude/longitude pairs to IANA timezone TZ names, there are probably third-party software out there that can do this.
Only with bash >= version 4.2:
TZ=US/Pacific printf -v unixtime "%(%Y-%m-%d-%H-%M-%S)T\n" -1
echo "$unixtime"
Output (e.g.)
2022-07-08-15-18-51
To demonstrate how the other answers work with DST:
"spring forward"
date:
$ TZ=America/Los_Angeles date -d '2022-03-13 01:59:59'
Sun Mar 13 01:59:59 PST 2022
$ TZ=America/Los_Angeles date -d '2022-03-13 + 1 second 01:59:59'
Sun Mar 13 03:00:00 PDT 2022
bash builtin printf
$ epoch=$(TZ=America/Los_Angeles date -d '2022-03-13 01:59:59' +%s)
$ TZ=America/Los_Angeles printf '%(%F %T %Z)T\n' $epoch
2022-03-13 01:59:59 PST
$ TZ=America/Los_Angeles printf '%(%F %T %Z)T\n' $((epoch + 1))
2022-03-13 03:00:00 PDT
"fall behind"
$ TZ=America/Los_Angeles date -d '2022-11-06 01:59:59'
Sun Nov 6 01:59:59 PDT 2022
$ TZ=America/Los_Angeles date -d '2022-11-06 + 1 second 01:59:59'
Sun Nov 6 01:00:00 PST 2022
$ epoch=$(TZ=America/Los_Angeles date -d '2022-11-06 01:59:59' +%s)
$ TZ=America/Los_Angeles printf '%(%F %T %Z)T\n' $epoch
2022-11-06 01:59:59 PDT
$ TZ=America/Los_Angeles printf '%(%F %T %Z)T\n' $((epoch + 1))
2022-11-06 01:00:00 PST

how to use shell convert from 01/Mar/2011 to 2011-03-01 on OS X

I want to know how to use shell convert from 01/Mar/2011 to 2011-03-01 on OS X?
in my bash:
bash-3.2$ date -d "03 Mar 2011" +%F
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
Thank #ghoti, on OS X should use like:
date -j -f '%d %b %Y' "02 JUN 2011" '+%F'
Failed conversion of ``02 JUN 2011'' using format ``%d %b %Y''
date: illegal time format
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
but, my system show me > date +%b 7, %b is a number, not an abbreviated month name.
Thanks.
Using BSD date, you can convert one format to another by using the -f option.
For example, putting your input into a variable so you can see how to re-use this date command:
$ d="27 JUN 2011"
$ date -j -f '%d %b %Y' "$d" '+%F'
2011-06-27
You can man date to see how everything works, but the basics are this;
-j tells the command just to process input and not try to set your system clock.
-f this that uses this as an input format to interpret that.
+yadda uses the specified output format to print the interpreted date.
For details on the input format, on OS X or most BSDs, you can man strftime.
The idea is to convert date STRING to epoch time, then output it as the format you desire.
I tested it on Cygwin and CentOS.
convert date STRING to epoch time
use command 'date -d STRING +%s', STRING can be 01 Mar 2011 or 01-Mar-2011 or 01/03/2011
date -d '01 Mar 2011' +%s
1298908800
output epoch time to date format
use command 'date -d #EPOCH_TIME '+%Y-%m-%d'
date -d #1298908800 '+%Y-%m-%d'
2011-03-01
Because your date STRING 01/Mar/2011 is not a valid format for date -d, so you have to use 'sed' to convert it.
echo "01/Mar/2011"|sed -e 's/\// /g'
01 Mar 2011
So your solution can be
old_date="01/Mar/2011"
date_string=`echo "$old_date"|sed -e 's/\// /g'`
echo $date_string
01 Mar 2011
epoch_time=`date -d "$date_string" +%s`
echo $epoch_time
1298908800
date -d #$epoch_time '+%Y-%m-%d'
2011-03-01

Bash How to format a date

I want to grep a file with the following date format:
Thu Apr 24
At the moment I only have date +"%d %m %Y" and that's returning 24 04 2014.
How do I format to get "Thu Apr 24"?
So I need the day month and date?
man date would suggest date +"%a %b %d"
You can try
date +"%a %b %d"
where
%a locale's abbreviated weekday name (e.g., Sun)
%b locale's abbreviated month name (e.g., Jan)
%d day of month (e.g., 01)

Is there Shell script date Format (dd month year time) (29 Oct 2013 05:26:30)

I want the date format in shell script as (dd month year time)
Example:
29 Oct 2013 05:26:30
Please can anyone help me in solving this.
Like this:
$ date "+%d %b %Y %T"
29 Oct 2013 10:45:08
From man date:
%d day of month (e.g., 01)
%b locale's abbreviated month name (e.g., Jan)
%Y year
%T time; same as %H:%M:%S

Parse Date in Bash

How would you parse a date in bash, with separate fields (years, months, days, hours, minutes, seconds) into different variables?
The date format is: YYYY-MM-DD hh:mm:ss
Does it have to be bash? You can use the GNU coreutils /bin/date binary for many transformations:
$ date --date="2009-01-02 03:04:05" "+%d %B of %Y at %H:%M and %S seconds"
02 January of 2009 at 03:04 and 05 seconds
This parses the given date and displays it in the chosen format. You can adapt that at will to your needs.
I had a different input time format, so here is a more flexible solution.
Convert dates in BSD/macOS
date -jf in_format [+out_format] in_date
where the formats use strftime (see man strftime).
For the given input format YYYY-MM-DD hh:mm:ss:
$ date -jf '%Y-%m-%d %H:%M:%S' '2017-05-10 13:40:01'
Wed May 10 13:40:01 PDT 2017
To read them into separate variables, I'm taking NVRAM's idea, but allowing you to use any strftime format:
$ date_in='2017-05-10 13:40:01'
$ format='%Y-%m-%d %H:%M:%S'
$ read -r y m d H M S <<< "$(date -jf "$format" '+%Y %m %d %H %M %S' "$date_in")"
$ for var in y m d H M S; do echo "$var=${!var}"; done
y=2017
m=05
d=10
H=13
M=40
S=01
In scripts, always use read -r.
In my case, I wanted to convert between timezones (see your /usr/share/zoneinfo directory for zone names):
$ format=%Y-%m-%dT%H:%M:%S%z
$ TZ=UTC date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-10T00:40:01+0000
$ TZ=America/Los_Angeles date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-09T17:40:01-0700
Convert dates in GNU/Linux
On a Mac, you can install the GNU version of date as gdate with brew install coreutils.
date [+out_format] -d in_date
where the out_format uses strftime (see man strftime).
In GNU coreutils' date command, there is no way to explicitly set an input format, since it tries to figure out the input format by itself, and stuff usually just works. (For detail, you can read the manual at coreutils: Date input formats.)
For example:
$ date '+%Y %m %d %H %M %S' -d '2017-05-10 13:40:01'
2017 05 10 13 40 01
To read them into separate variables:
$ read -r y m d H M S <<< "$(date '+%Y %m %d %H %M %S' -d "$date_in")"
To convert between timezones (see your /usr/share/zoneinfo directory for zone names), you can specify TZ="America/Los_Angeles" right in your input string. Note the literal " chars around the zone name, and the space character before in_date:
TZ=out_tz date [+out_format] 'TZ="in_tz" in_date'
For example:
$ format='%Y-%m-%d %H:%M:%S%z'
$ TZ=America/Los_Angeles date +"$format" -d 'TZ="UTC" 2017-05-10 02:40:01'
2017-05-09 19:40:01-0700
$ TZ=UTC date +"$format" -d 'TZ="America/Los_Angeles" 2017-05-09 19:40:01'
2017-05-10 02:40:01+0000
GNU date also understands hour offsets for the time zone:
$ TZ=UTC date +"$format" -d '2017-05-09 19:40:01-0700'
2017-05-10 02:40:01+0000
This is simple, just convert your dashes and colons to a space (no need to change IFS) and use 'read' all on one line:
read Y M D h m s <<< ${date//[-:]/ }
For example:
$ date=$(date +'%Y-%m-%d %H:%M:%S')
$ read Y M D h m s <<< ${date//[-: ]/ }
$ echo "Y=$Y, m=$m"
Y=2009, m=57
$ t='2009-12-03 12:38:15'
$ a=(`echo $t | sed -e 's/[:-]/ /g'`)
$ echo ${a[*]}
2009 12 03 12 38 15
$ echo ${a[3]}
12
The array method is perhaps better, but this is what you were specifically asking for:
IFS=" :-"
read year month day hour minute second < <(echo "YYYY-MM-DD hh:mm:ss")
Pure Bash:
date="2009-12-03 15:35:11"
saveIFS="$IFS"
IFS="- :"
date=($date)
IFS="$saveIFS"
for field in "${date[#]}"
do
echo $field
done
2009
12
03
15
35
11
instead of using the shell scripting,incorporate in your scripting itself like below wheever you need:
a=date +%Y
b=date +%S
c=date +%H
a will be year
b will be seconds
c will be hours. and so on.
Another solution to the OP's problem:
IFS=' -:' read y m d h m s<<<'2014-03-26 16:36:41'
Converting a date to another format with BSD date and GNU date:
$ LC_ALL=C date -jf '%a %b %e %H:%M:%S %Z %Y' 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
$ gdate -d 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
GNU date recognizes Wed and Mar even in non-English locales but BSD date doesn't.
Converting seconds since epoch to a date and time with GNU date and BSD date:
$ gdate -d #1234567890 '+%F %T'
2009-02-14 01:31:30
$ date -r 1234567890 '+%F %T'
2009-02-14 01:31:30
Converting seconds to hours, minutes, and seconds with a POSIX shell, POSIX awk, GNU date, and BSD date:
$ s=12345;printf '%02d:%02d:%02d\n' $((s/3600)) $((s%3600/60)) $((s%60))
05:25:45
$ echo 12345|awk '{printf "%02d:%02d:%02d\n",$0/3600,$0%3600/60,$0%60}'
05:25:45
$ gdate -d #12345 +%T
05:25:45
$ date -r 12345 +%T
05:25:45
Converting seconds to days, hours, minutes, and seconds:
$ t=12345678
$ printf '%d:%02d:%02d:%02d\n' $((t/86400)) $((t/3600%24)) $((t/60%60)) $((t%60))
142:21:21:18
another pure bash
$ d="2009-12-03 15:35:11"
$ d=${d//[- :]/|}
$ IFS="|"
$ set -- $d
$ echo $1
2009
$ echo $2
12
$ echo $#
2009 12 03 15 35 11
have you tried using cut?
something like this:
dayofweek=date|cut -d" " -f1

Resources