BSDのdateコマンドを使用してUnix時間午後11時と今夜11時CSTを取得するには?

BSDのdateコマンドを使用してUnix時間午後11時と今夜11時CSTを取得するには?

BSDはまだ時間形式にdate -j -f対応しながら、現在の時間の秒と分を混ぜているようです。'%H%p'私が望むのは、入力形式を正しいUNIX時間に変換することだけです。また、%Z値をシステムタイムゾーン以外の値に変更するとエラーが発生します。

❯ /bin/date -j -f '%H%p %Z' '11PM PDT' '+%s'; gdate -d '11PM' '+%s'
1653546964
1653544800
# Run again
❯ /bin/date -j -f '%H%p %Z' '11PM PDT' '+%s'; gdate -d '11PM' '+%s'
1653546965
1653544800

私が望むもの?

  1. コマンドを実行する時間の分/秒が結果に影響を与えないようにします。
  2. どの時間帯でも動作するようにしてください%Z

日付に不要な問題がある場合は、これを行うために他のPOSIX準拠の方法を使用できます。

私はzshを使用しているので、可能であればzshソリューションも動作します。 strftime -rは有望に見えますが、負の値を生成します。

答え1

フォーマット文字列の一部として:%M:%Sを指定し、時間として:00:00を指定できる必要があります。

% /bin/date -j -f '%H:%M:%S%p %Z' '11:00:00PM GMT'
Wed May 25 19:00:00 EDT 2022

FreeBSDコマンドのマンページdate表示解析を完了するには、strptime(3)を使用してください。マンページには次の内容があります。

 The %Z format specifier only accepts time zone abbreviations of the local
 time zone, or the value "GMT".  This limitation is because of ambiguity
 due to of the over loading of time zone abbreviations.  One such example
 is EST which is both Eastern Standard Time and Eastern Australia Summer
 Time.

したがって、dateこれらのタイムゾーン変換を実行するために使用することはできません。

代わりに、GMTオフセットを計算して一緒に使用できます%z

例えば

% /bin/date -j -f '%H:%M:%S%p %z' "11:00:00PM $(TZ=America/Los_Angeles date +%z)"
Thu May 26 02:00:00 EDT 2022

そして正確に言えば、今夜11時(現在PDT)ロサンゼルスはニューヨークの翌日午前2時です。

答え2

次のようにタグを付けているzshのでzshstrftimezsh/datetimestrftime()(+ localtime())とstrptime() (+ mktime())標準機能(秒未満をサポートする拡張を含む)。

したがって、ここで移植することができます(BSD、GNU、またはGNUまたはBSDを持たないすべてのシステムでdate):

zmodload zsh/datetime
TZ=America/Los_Angeles strftime -s today %Y-%m-%d
TZ=America/Los_Angeles strftime -r "%Y-%m-%d %I%p" "$today 11PM"

今日は2022-05-26私の時間ですが、まだ2022-05-25ロサンゼルスの時間は1653544800(2022-05-26T06:00:00+00:00)です。

これは%H1日を24時間形式で表した時間です。%I12時間形式を使用する場合は必須です%p

また、日付を指定する必要があります。それ以外の場合、デフォルトは1900-01-01(および返される他の日付関連フィールドの値は0 tm_year)なので、数値は負です。struct tmstrptime()

また、%pロケールによって異なります。常に認識されるようにCロケールを設定する必要があるかもしれません。PM

CSTが米国中部標準時(または夏?)時間(中国時間またはオーストラリア中部標準時とは反対)を意味すると仮定すると、たとえば自分に関連する他の時間帯America/Los_Angelesに置き換えるか、常にUTC 6時間西に表示されている時間帯をハードコーディングすることができます。あります。 、この時間は季節(冬/夏)に関係なく使用されます。America/ReginaTZ=CST6CST

関連情報