나는 Unix 시간에 관한 수많은 게시물을 읽었으며 많은 사람들이 하루가 86,400초라고 말합니다.
하지만 페이지는 다음과 같습니다이것윤초에 대해 이야기해 보세요. 이것은 나를 혼란스럽게 한다. 나는 Unix 시간이 UTC를 기반으로 한다는 것을 읽었으며 내가 이해하는 것은 UTC와 TAI의 차이가 윤초이므로 Unix는 윤초를 지원해야 한다는 것입니다. 그렇지 않으면 UTC 대신 TAI 기반으로 말하지 않을 이유가 무엇입니까?
더 헷갈리게 하기 위해 Windows가 어떤 기능을 하는지 확인해 보았는데, 찾아낸 답은 윤초를 계산하지 않는다는 것이었지만,그것은 말한다UTC를 기반으로 하고 혼란스럽습니다. 윤초가 계산되지 않는데 왜 UTC라고 말합니까?
어쨌든 Unix에서 정수 초를 정확한 날짜로 변환하는 방법을 묻고 싶습니다.
답변1
나는 Unix 시간에 관한 수많은 게시물을 읽었으며 많은 사람들이 하루가 86,400초라고 말합니다.
네, 그게 정의입니다.
그러나 이와 같은 페이지에서는 윤초에 대해 설명합니다. 이것은 나를 혼란스럽게 한다.
당신은 유일한 사람이 아닙니다. 정말 우스꽝스러운 혼란입니다.
유닉스 시간은 UTC를 기반으로 한다는 것을 읽었습니다.
예, 아래를 참조하세요.
내가 이해할 수 있는 것은 UTC와 TAI의 차이가 윤초라는 것입니다.
예.
그렇다면 유닉스는 도약을 지원해야 한다
그러나 실제로는 그렇지 않습니다. 눈을 감고 이 어색하고 비실용적인 기술 문제에 대한 논의를 듣기를 거부합니다.
이것POSIX는 "에포크 이후 초"를 정의합니다.세분화된 UTC 시간을 기준으로 모든 날짜의 길이가 86400초라고 명시적으로 가정합니다.
에포크 이후 4.15초
에포크 이후 경과된 시간(초)에 가까운 값입니다. 협정 세계시[UTC]이름(초 단위로 지정(tm_seconds), 분(최소 시간), 시간(tm_시간), 올해 1월 1일 이후의 일수(tm_yday), 해당 연도의 경우 마이너스 1900(tm_년))는 다음 표현식에 따라 에포크 이후의 시간(초)과 관련됩니다.
연도가 1970년 미만이거나 값이 음수이면 관계가 정의되지 않습니다. 연도가 1970보다 크고 값이 음수가 아닌 경우 값은 C 언어 표현식에 따라 UTC 이름과 연결됩니다.tm_seconds,최소 시간,tm_시간,tm_yday, 그리고 tm_년모두 정수 유형입니다.
tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 + (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 - ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400
실제 시간과 신기원 이후의 현재 시간(초) 사이의 관계는 지정되지 않습니다.
현재 실시간과 원하는 관계를 유지하기 위해 epoch 값 이후의 초 단위 변경 방법은 구현에 따라 정의됩니다. 에포크 이후의 초 단위로 표현하면 하루는 정확히 86400초로 계산되어야 합니다.
(홀수 처리 tm_year
는 윤일을 고려하기 위한 것입니다. 나누기는 잘린 정수 나누기입니다.)
이것기본원리부분윤초가 무시된다는 점을 직접 인정합니다.
협정 세계시(UTC)에는 윤초가 포함됩니다. 하지만,POSIX 시간(에포크 이후 초)에서는 윤초가 무시됩니다.(적용되지 않음) 시차를 계산하는 간단하고 호환 가능한 방법을 제공합니다. 따라서 겉모습에도 불구하고 분해된 POSIX 시간이 반드시 UTC일 필요는 없습니다.
위의 표현식은 윤초가 삽입되면 "에포크 이후 초"가 1초 동안 반복된다는 의미입니다.
UTC 1972-06-30 23:59:59 = 78796799 seconds since epoch
UTC 1972-06-30 23:59:60 = 78796800 seconds since epoch
UTC 1972-07-01 00:00:00 = 78796800 seconds since epoch
UTC 1972-07-01 00:00:01 = 78796801 seconds since epoch
이는 에포크 이후의 "초"가 (물리적으로) 동일한 길이가 아니거나 에포크 자체가 실제로 "이동"한다는 것을 의미합니다. 골라보세요.
위에서 언급했듯이 1초는 2(물리적, SI/UTC)초이므로 분명히 같은 길이는 아닙니다.
"모든 날은 86400초"라는 정의를 취하면 SI 초의 길이가 일정하다고 가정하고 이를 계산하면 에포크는 다음과 같이 "이동"합니다. (즉, UTC 1972-07-01 00:00:00은 UTC 1970-00-01 00:00:01 이후 78796800 SI초이므로 그 당시 유효한 에포크여야 합니다.)
글쎄, 그들은 "대략"으로 헤지합니다.
게다가 이는 간단하지만 정확한 해결책이 존재하지 않는 상황 중 하나입니다. 당신은 도착할 수 있습니다좋은 점 3가지 중 2가지를 선택하세요.그리고 견뎌야 한다
- a) 가변 길이 일수(초)
- b) 그 자체로 길이가 다른 초
- c) 결국 태양과 동기화되지 않게 된 날짜 체계.
날짜 계산을 단순화하기 위해 POSIX는 (a)를 거부하지만 그렇지 않으면 상용시와 일치하도록 UTC를 일치시키므로 (c)를 거부하고 단점(b)을 허용하기로 선택합니다. 계산의 단순성은 이론적 근거에서 명시적으로 언급됩니다.
윤초를 몇 초 단위로 고려해야 하는지에 대한 주제는 매번 합의를 통해(각각 의견 차이를 인정하면서) 여러 차례 논의된 적이 있습니다. 대부분의 사용자에게는 모든 날짜를 동일한 거래로 처리하는 것이 좋습니다. . (즉, 대부분의 적용은 모든 날이 단일 길이(에포크 이후 초 단위로 측정됨)를 갖는다고 가정하는 것으로 판단됩니다. 따라서 윤초는 에포크 이후 초에 적용되지 않습니다.)
("실제 시간과 신기원 이후의 현재 초 수 사이의 관계는 지정되지 않았습니다." 거의 모든 실제 목적에서 UTC가 "실제 시간"이고 위의 정의에 의존하기 때문에 문장 자체가 이상합니다. UTC가 무엇을 의미하는지 잘 모르겠지만 시스템 시계가 정확할 필요는 없으며 외부 동기화가 없으면 대부분의 컴퓨터 시계는 정확하지 않다는 의미일 뿐입니다.
마찬가지로 "그러므로 POSIX 시간이 나타나더라도 반드시 UTC는 아닙니다." 근거 부분이 이상해 보이지만 윤초에 적용됩니다. 그렇지 않으면 주어진 동등성은 POSIX 시간을 고려한 것으로 보입니다.예UTC. )
하지만 똑똑한 사람들이 그것에 대해 충분히 썼기 때문에 내가 제대로 할 것이라고 기대하지 마십시오.
간략한 소개유닉스 시간에 대한 프로그래머의 오해알렉스 첸 지음.
SE 게시물유닉스 시간과 윤초설득력 있는 일부 토론 및 게시물에 대한 링크가 포함되어 있습니다."유닉스 윤초 카오스"저자: 데이빗 마도르(David Madore)
그 사람은 NTP에서 이 문제를 처리한다고 언급했습니다.NTP를 사용하여 윤초를 처리하는 5가지 방법Red Hat 개발자 블로그에서.
물론 그 방법 중 하나는 Google이 사용하기 시작한 것입니다."점프 스머지"2008년. 즉, 단일 두 배 길이의 초를 약간 벗어난 더 많은 초로 바꾸는 것입니다. (필수XKCD)
그리고Unix 시간용 Wikipedia 페이지TAI 및 UTC를 포함한 중복 값을 표시하는 위와 유사한 테이블이 있습니다.
어쨌든 Unix에서 정수 초를 정확한 날짜로 변환하는 방법을 묻고 싶습니다.
몇초냐에 따라..
Unix 시간에서는 86400으로 나누어 일 수를 얻은 다음 가변 길이 월, 윤일 및 시간대에 대한 일반적인 규칙을 따릅니다.
아니면 오히려 전화 localtime()
하거나 gmtime()
대신 해주세요.
다른 시간이라면 현재 가지고 있는 것을 처리할 수 있는 라이브러리를 사용하십시오.
답변2
여러 개념을 혼동하고 계십니다. UNIX 시간(충분히 높은 관점에서)은 단지 로컬 개념인 초 카운터입니다. 마침내 누군가가 당신에게 시계를 주면서 "이 아름다운 시계에 따르면 1970년 1월 1일 이후로 몇 초가 지났습니까?"라고 말하면 "그래, 1970년 1월 1일 이후로 몇 초가 지났습니까?"라고 말합니다. 몇 초"를 입력하고 초를 계속 계산합니다. 이는 저널 문서를 마지막으로 변경한 시간을 저장하는 등 많은 "홈" 타이밍 목적에 적합합니다. TAI는 또한 단지 초 카운터이지만 조정된 카운터입니다. 단지 현지 시간 수일 뿐이지만 많은 원자 시계의 평균입니다.
UTC는 완전히 다른 것입니다.언제이는 단지 일반적인 사건이 발생한 후 몇 초가 걸리는 시간이 아닙니다.
예를 들어, 많은 경우 "시대 이후 1400만226초가 지났습니다"는 "지금은 오전 9시 12분이고 오늘은 6월 6일입니다"라고 말하는 것보다 덜 유용합니다.
명확하게 말하면 "UNIX 시간"은 단순히 특정 이벤트(에포크) 이후 경과된 초 수입니다. 초당 한 번씩 똑딱거리는 완벽한 메트로놈이 있고 해당 날짜 이후의 틱을 계산하면 그것이 UNIX 시간입니다. (이 카운터가 실제로 UTC에서 파생되었다는 사실이 아니었다면,효과적으로UTC가 윤초를 삽입할 때마다 에포크는 1초씩 앞으로 이동합니다. )
이제 여러분의 혼란은 예를 들어 1697300527(몇 초 전 UNIX 시간)이 인간에게 그다지 유용한 시간이 아니라는 사실에서 비롯됩니다. 두 번째 개수를 사람이 읽을 수 있는 날짜/시간으로 변환해야 합니다(예: 2023년 10월 14일 토요일 18:22:01).
물론 시간 변환에서는 윤년, 윤초, 시간대 및 기타 수정 사항을 고려해야 합니다. 이는 UNIX 시간에서 UTC 시간 또는 기타 시간 표현으로의 변환이 반드시 매끄럽거나 연속적이거나 모호하지 않다는 것을 의미합니다. (예: 해당 시간대에서 일광 절약 시간이 끝나는 날 오전 3시 15분에 해당하는 여러 UNIX 타임스탬프가 있을 수 있습니다.)
그게 다야. 언제나 "쉽고 명확하게"라고 말할 수 있지만그 시대로부터 너무나 많은 초가 흘렀다”, 인간의 목적을 위한 현지 시간(또는 조정 시간) 표현으로의 변환은 단순히 해당 시간(UNIX 시간) 이후의 초 수를 계산하는 것만으로도 단조롭지 않을 수 있습니다.
어쨌든 Unix에서 정수 초를 정확한 날짜로 변환하는 방법을 묻고 싶습니다.
플랫폼에 있는 시간대 정보를 사용합니다. Chris Davies가 제안했고 date
저도 동의합니다. 합리적인 프로그래밍 언어라면 누구나 tzinfo 데이터베이스에 액세스할 수 있습니다.
1 C: ctime(…)
, C++: , std::chrono
Python: python -c 'import datetime;print(datetime.datetime.now())'
, Perl, Haskell,...)
답변3
적합한 버전이 있으면 date
내장된 기능을 사용할 수 있습니다.
date
Sat Oct 14 17:17:59 BST 2023
date +'%s'
1697300279
date --date '@1697300279'
Sat Oct 14 17:17:59 BST 2023
date --date '@1697300279' +'%Y-%m-%d %H:%M:%S'
2023-10-14 17:17:59