私は日付コマンドを使用して、日付コマンド自体が解釈できるファイルのタイムスタンプを生成しようとしています。ただし、dateコマンドは独自の出力を好まないようで、これを回避する方法がわかりません。適例:
sh-4.2$ date
Fri Jan 3 14:22:19 PST 2014
sh-4.2$ date +%Y%m%dT%H%M
20140103T1422
sh-4.2$ date -d "20140103T1422"
Thu Jan 2 23:22:00 PST 2014
dateは、15時間のオフセットで文字列を解釈しているようです。これに対する既知の回避策はありますか?
編集:これは表示の問題ではありません:
sh-4.2$ date +%s
1388791096
sh-4.2$ date +%Y%m%dT%H%M
20140103T1518
sh-4.2$ date -d 20140103T1518 +%s
1388737080
sh-4.2$ python
Python 3.3.3 (default, Nov 26 2013, 13:33:18)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1388737080 - 1388791096
-54016
>>> 54016/3600
15.004444444444445
>>>
UNIXタイムスタンプとして表示した場合、15時間ずれています。
たぶん私はこの質問を少し違った方法で提起するべきです。次の形式のISO8601基本タイムスタンプのリストがあるとします。
それらを対応するUnixタイムスタンプに変換する最も簡単な方法は何ですか?
例えば:
- 20140103T1422 = 1388787720
- 20140103T142233 = 1388787753
「既知の回避策」を要求します。ここに簡単なものがあります:
$ date -d "$(echo 20140103T1422 | sed 's/T/ /')"
Fri Jan 3 14:22:00 PST 2014
これは、sed
を使用して、「T」をスペースに置き換えます。結果はdate
が理解できる形式です。
ISO8601の日付に秒を追加すると、date
にはさらに変更が必要になります。
$ date -d "$(echo 20140103T142211 | sed -r 's/(.*)T(..)(..)(..)/\1 \2:\3:\4/')"
Fri Jan 3 14:22:11 PST 2014
上記では、sed
は「T」をスペースに置き換え、HHMMSSをHH:MM:SSに区切ります。
coreutils info docs は、ISO 8601「拡張フォーマット」がサポートされていることを示しています。
機能させるには、ハイフン、コロン、+%z
を追加する必要があります。
$ date +"%Y-%m-%dT%H:%M:%S%z"
2014-01-03T16:08:23-0800
$ date -d 2014-01-03T16:08:23-0800
Fri Jan 3 16:08:23 PST 2014
質問の2番目の部分に答えるには...
日付形式には数値と記号しか含まれていないため、各記号を一意の文字に置き換えることができます。 tr
を使用
$ ts="$(date +"%Y-%m-%dT%H:%M:%S%z" | tr -- '-:+' 'hcp')"; echo "$ts"
2014h01h03T16c18c04h0800
$ date -d "$(echo "$ts" | tr -- 'hcp' '-:+')"
Fri Jan 3 16:18:04 PST 2014
または、T
と-
または+
を区切り文字として使用して解析することもできます。 Shell ${var%Word}
および${var#Word}
拡張を使用
$ ts="$(date +"%Y%m%dT%H%M%S%z")"; echo "$ts"
20140103T162228-0800
$ date=${ts%T*}; time=${ts#*T}
etc.
またはbash
正規表現マッチングを使用
$ ts="$(date +"%Y%m%dT%H%M%S%z")"; echo "$ts"
20140103T165611-0800
$ [[ "$ts" =~ (.*)(..)(..)T(..)(..)(..)(.....) ]]
$ match=("${BASH_REMATCH[@]}")
$ Y=${match[1]}; m=${match[2]}; d=${match[3]}; H=${match[4]}; M=${match[5]}; S=${match[6]}; z=${match[7]}
$ date -d "$Y-$m-$d"T"$H:$M:$S$z"
Fri Jan 3 16:56:11 PST 2014
またはPerl、Pythonなど.
GNU coreutilsは バージョン8.1 (2011-09-08にリリース)以降、入力として ISO 8601日付 のみをサポートしています。古いバージョンを使用している必要があります。
古いバージョンでは、T
をスペースに置き換える必要があります。それ以外の場合は 米軍のタイムゾーン と解釈されます。
最近のバージョンでも、完全に句読点の付いた形式のみが認識され、数字と中央にT
のみを含む基本形式は認識されません。
# Given a possibly abbreviated ISO date $iso_date...
date_part=${iso_date%%T*}
if [ "$date_part" != "$iso_date" ]; then
time_part=${abbreviated_iso_date#*T}
case ${iso_date#*T} in
[!0-9]*) :;;
[0-9]|[0-9][0-9]) time_part=${time_part}:00;;
*)
hour=${time_part%${time_part#??}}
minute=${time_part%${time_part#????}}; minute=${minute#??}
time_part=${hour}:${minute}:${time_part#????};;
esac
else
time_part=
fi
date -d "$date_part $time_part"
date
のmanページでこのメモに気付きました。
DATE STRING
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.
これは決定的なものではありませんが、[ISO 8601]の場合、試みているようにT
を含む時刻形式文字列を明示的に示していません。 @ Gilles回答 が示すように、 ISO 8601 in GNU CoreUtils のサポートは比較的新しいものです。
Perlを使用して文字列を再構成できます。
例:
$ date -d "$(Perl -pe 's/(.*)T(\d{2})(\d{2})(\d{2})/$1 $2:$3:$4/' \
<<<"20140103T142233")"
Fri Jan 3 14:22:33 EST 2014
これに秒を含む文字列と含まない文字列の両方を処理させることができます。
20140103T1422:
$ date -d "$(Perl -pe 's/^(.*)T(\d{2})(\d{2})(\d{2})$/$1 $2:$3:$4/ || \
s/^(.*)T(\d{2})(\d{2})$/$1 $2:$3:00/' <<<"20140103T1422")"
Fri Jan 3 14:22:00 EST 2014
20140103T142233:
$ date -d "$(Perl -pe 's/^(.*)T(\d{2})(\d{2})(\d{2})$/$1 $2:$3:$4/ || \
s/^(.*)T(\d{2})(\d{2})$/$1 $2:$3:00/' <<<"20140103T142233")"
Fri Jan 3 14:22:33 EST 2014
日付のマニュアルページによると、出力する形式は、date
が入力として期待する形式とは異なります。これはmanページが言うことです:
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
したがって、次のようにすることができます。
# date +%m%d%H%M%Y
010402052014
# date 010402052014
Sat Jan 4 02:05:00 EAT 2014
出力文字列の定義に使用される変数では、+%m%d%H%M%Y
は、入力として期待するものと等しくなります。