linux date 명령으로 ISO8601 날짜를 구문 분석하는 방법 date -d “20140103T1422” Thu

date 명령을 사용하여 date 명령 자체가 해석 할 수있는 파일 타임 스탬프를 생성하려고합니다. 그러나 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

날짜가 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
>>> 

유닉스 타임 스탬프로 표시 될 때 여전히 15 시간까지 꺼져 있습니다.

편집 # 1

어쩌면 나는이 질문을 조금 다르게 바꿔야 할 수도 있습니다. 다음 형식의 ISO8601 기본 타임 스탬프 목록이 있다고 가정합니다.

  • YYYYMMDDThhmm
  • YYYYMMDDThhmmss

해당 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 정보 문서는 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

질문의 두 번째 부분에 대답하려면 …

날짜 형식에는 숫자와 기호 만 포함되므로 각 기호를 고유 문자로 바꿀 수 있습니다 (예 : 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과를 -+예를 들어 분리기로 쉘 사용 ${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.13 이후 (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.

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.

결정적이지는 않지만 T[ISO 8601]에 대해 시도한대로 시간 형식 문자열을 명시 적으로 표시하지는 않습니다 . @Gilles의 답변에서 알 수 있듯이 GNU CoreUtils에서 ISO 8601 의 지원 은 비교적 새로운 것입니다.

문자열 재 포맷

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입력으로 예상되는 형식과 다릅니다 . 다음은 매뉴얼 페이지의 내용입니다.

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입력으로 예상되는 것과 동일하기 때문입니다.


답변