GNU date and custom formats
per the man page:
The --date=STRING is a mostly free format human readable date
string such as "Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29
16:21:42" or even "next Thursday". A date string may contain items
indicating calendar date, time of day, time zone, day of week,
relative time, relative date, and numbers. An empty string indicates
the beginning of the day. The date string format is more complex than
is easily documented here but is fully described in the info
documentation.
The "T" seems to confuse it. This works:
$ date --date="2013-12-02 18:20:52" +%Y%m%dT%H%M%S
20131202T182052
The output format has nothing to do with the input format.
How to convert a custom date format to an alternate format with the gnu 'date' command?
I finally figured this out with the aid of the coreutils mailing list. However, the example they give there uses perl. They specifically rely on the POSIX::strptime module, which does not come with a standard installation of perl. Therefore, I solved this with python, which has the time
module. This module should be available in most installations of python2 and python3.
Here's how to use it programmatically:
Python solution:
$ timestamp='2013年1月8日 20時19分'
$ time_format='%Y年%m月%d日 %H時%M分'
$ gdate -u -R -d "$(python -c 'import sys; from time import strptime; t=strptime(sys.argv[-1],"'$time_format'"); print("%d-%d-%d %d:%d"%(t.tm_year,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min))' $timestamp)"
Tue, 08 Jan 2013 20:19:00 +0000
This works with both python2 and python3. You can substitute any timestamp and format as you like.
Perl solution
To document the answer given to me on coreutils, the perl solution is this (requires POSIX::strptime
)
$ gdate -u -R -d "$(perl -MPOSIX::strptime -le 'my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = POSIX::strptime("$ARGV[0]","%Y年%m月%d日 %H時%M分");$year+=1900;$mon+=1;printf("%04d-%02d-%02d %0d:%02d\n",$year,$mon,$mday,$hour,$min);' "2013年1月8日 20時19分")"
What are valid input DATE formats for the (Linux) date command?
A workaround:
x="2015_06_15"
date -d "${x//_/} 12:00 +1 day" +%Y%m%d
Output:
20150616
Parse non standard date format
Here is what the man date
page says about format for the --date
option:
The --date=STRING is a mostly free format human readable date string such as
"Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29 16:21:42" or even "next
Thursday". A date string may contain items indicating calendar date, time of day,
time zone, day of week, relative time, relative date, and numbers. An empty
string indicates the beginning of the day. The date string format is more
complex than is easily documented here but is fully described in the info
documentation.
Hence you can use, for example:
date --date "2014-06-12 09:03 UTC" --utc +%d.%m.%Y,\ %H:%M\ UTC
# Output: 12.06.2014, 09:03 UTC
to get what you desire.
You could get this second form easily from your first output with a sed
line as follows:
sed 's/\([0-9]\{2\}\)\.\([0-9]\{2\}\)\.\([0-9]\{4\}\), \(.*\)/\3-\2-\1 \4/'
<<< '12.06.2014, 09:03 UTC'
# Output: 2014-06-12 09:03 UTC
Note that it would probably be faster to output date at ISO 8601 format in the first time for reuse, e.g. with:
date --utc +%F\ %H:%M\ UTC
# Output: 2014-06-12 10:12 UTC
linux bash - Parse date in custom format
Why don't you store the time as unixtime (ie milliseconds since 1st of january 1970) Like 1388198714
?
The requested exercise in trying to parse all date formats from all around the world as a one shot bash script without reasonable dependecies is slightly ridiculous.
YYYY-MM-DD format date in shell script
In bash (>=4.2) it is preferable to use printf's built-in date formatter (part of bash) rather than the external date
(usually GNU date).
As such:
# put current date as yyyy-mm-dd in $date
# -1 -> explicit current date, bash >=4.3 defaults to current time if not provided
# -2 -> start time for shell
printf -v date '%(%Y-%m-%d)T\n' -1
# put current date as yyyy-mm-dd HH:MM:SS in $date
printf -v date '%(%Y-%m-%d %H:%M:%S)T\n' -1
# to print directly remove -v flag, as such:
printf '%(%Y-%m-%d)T\n' -1
# -> current date printed to terminal
In bash (<4.2):
# put current date as yyyy-mm-dd in $date
date=$(date '+%Y-%m-%d')
# put current date as yyyy-mm-dd HH:MM:SS in $date
date=$(date '+%Y-%m-%d %H:%M:%S')
# print current date directly
echo $(date '+%Y-%m-%d')
Other available date formats can be viewed from the date man pages (for external non-bash specific command):
man date
How can I change the format of a date from the command line?
$ date -d '2005-06-30' +'%a %F'
Thu 2005-06-30
See man date
for other format options.
This option is available on Linux, but not on Darwin. In Darwin, you can use the following syntax instead:
date -j -f "%Y-%m-%d" 2006-06-30 +"%a %F"
The -f argument specifies the input format and the + argument specifies the output format.
As pointed out by another poster below, you would be wise to use %u (numeric day of week) rather than %a to avoid localization issues.
equivalent date from GNU to solaris
Tcl has a good free-form date scanner, if you have Tcl installed (try which tclsh
). A shell function:
tcldate() {
d=${1:-now} # the date string
f=${2:-%c} # the output format
echo "puts [clock format [clock scan {$d}] -format {$f}]" | tclsh
}
In action on an ancient Solaris 8 box with bash 2.03 and tcl 8.3.3
$ tcldate
Tue Jul 23 13:27:17 2013
$ i=4
$ tcldate "$i days"
Sat Jul 27 13:27:34 2013
$ tcldate "$i days" "%Y-%m-%d"
2013-07-27
$ tcldate "20130101 + $i days" "%Y-%m-%d"
2013-01-05
This even handles daylight savings transitions:
$ tcldate "2014-03-09 00:30 + 1 hour" "%D %T %Z"
03/09/14 01:30:00 EST
$ tcldate "2014-03-09 00:30 + 2 hour" "%D %T %Z"
03/09/14 03:30:00 EDT
$ tcldate "2013-11-03 00:30 + 1 hour" "%D %T %Z"
11/03/13 01:30:00 EDT
$ tcldate "2013-11-03 00:30 + 2 hour" "%D %T %Z"
11/03/13 01:30:00 EST
Related Topics
Why Does Script Not Recognize File Extension
How to Read from Text File Line-By-Line and Split the Line by a Character
Knowing If a Remote Port Forward Was Successful
Bash/Linux Sort by 3Rd Column Using Custom Field Seperator
Compute Base64 Encoded Hash from a Given Hash
Fsync, Sync: Does It Really Do What Its Supposed To
Why Would the Elf Header of a Shared Library Specify Linux as the Osabi
G++ Always Fails with Undefined Reference to _Unwind_Getipinfo
Simple Way to Get Filesize in X86 Assembly Language
Safely Remembering Ssh Credentials in Bash Script
How to Mail Script Output in Table Format
Apache Proxypass Not Loading Resources
Libcurl Ssl Error After Fork()
Export_Symbol in Kernel Module | Undefined Symbol During Insmod
Difference Between Source and ./ Execution of Linux Scripts
Differencebetween These Two Commands Which Are Used to Run Shell Script