std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
다음을위한 좋은 장소입니다 auto
.
auto now = std::chrono::system_clock::now();
millisecond
정확한 트래픽을 원하기 때문에 다음에서 은밀하게 진행하는 것이 좋습니다 time_point
.
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
now_ms
을 time_point
기반으로 system_clock
하지만 정밀도 milliseconds
대신 정밀도를 사용합니다 system_clock
.
auto epoch = now_ms.time_since_epoch();
epoch
이제 유형이 std::chrono::milliseconds
있습니다. 그리고 다음 문장은 본질적으로 no-op이됩니다 (간단히 복사하고 변환하지 않음).
auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);
여기:
long duration = value.count();
귀하와 내 코드 모두 에서 에포크 이후의 duration
수를 보유합니다.milliseconds
system_clock
.
이:
std::chrono::duration<long> dur(duration);
, 및 정밀도로 duration
표현 된을 만듭니다 . 이것은 효과적으로 은 S 에 보류를 에 . 논리 오류입니다. 올바른 코드는 다음과 같습니다.long
seconds
reinterpret_cast
milliseconds
value
seconds
std::chrono::milliseconds dur(duration);
이 줄 :
std::chrono::time_point<std::chrono::system_clock> dt(dur);
의 기본 정밀도 (일반적으로 밀리 초보다 미세함)에 정밀도를 유지하는 기능을 사용하여을 time_point
기반으로를 만듭니다 . 그러나 런타임 값은 정수 밀리 초가 유지됨을 올바르게 반영합니다 (유형에 대한 수정을 가정 ).system_clock
system_clock
dur
수정을해도이 테스트는 (거의 항상) 실패합니다.
if (dt != now)
때문에이 dt
의 정수를 보유하고 milliseconds
있지만, now
(A)보다 틱 미세한의 정수 보유 millisecond
(예 : microseconds
또는 nanoseconds
). 따라서 system_clock::now()
정수 를 반환 한 드문 경우에만 milliseconds
테스트가 통과됩니다.
그러나 대신 다음을 수행 할 수 있습니다.
if (dt != now_ms)
이제 예상 한 결과를 안정적으로 얻을 수 있습니다.
함께 모아서:
int main ()
{
auto now = std::chrono::system_clock::now();
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto value = now_ms.time_since_epoch();
long duration = value.count();
std::chrono::milliseconds dur(duration);
std::chrono::time_point<std::chrono::system_clock> dt(dur);
if (dt != now_ms)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
개인적으로 나는 모든 std::chrono
지나치게 장황한 것을 발견 하므로 다음과 같이 코딩합니다.
int main ()
{
using namespace std::chrono;
auto now = system_clock::now();
auto now_ms = time_point_cast<milliseconds>(now);
auto value = now_ms.time_since_epoch();
long duration = value.count();
milliseconds dur(duration);
time_point<system_clock> dt(dur);
if (dt != now_ms)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
안정적으로 출력됩니다.
Success.
마지막으로 임시 time_point
유형을 제거하여 및 적분 유형 간의 코드 변환을 최소화하는 것이 좋습니다 . 이러한 변환은 위험하므로 베어 정수 유형을 조작하는 코드를 적게 작성할수록 좋습니다.
int main ()
{
using namespace std::chrono;
auto now = time_point_cast<milliseconds>(system_clock::now());
using sys_milliseconds = decltype(now);
auto integral_duration = now.time_since_epoch().count();
sys_milliseconds dt{milliseconds{integral_duration}};
if (dt != now)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
위의 주요 위험이되고 있지 해석 integral_duration
으로 milliseconds
A와 방식 뒷면에 time_point
. 이러한 위험을 완화하는 한 가지 가능한 방법은 다음과 같이 작성하는 것입니다.
sys_milliseconds dt{sys_milliseconds::duration{integral_duration}};
이렇게하면 sys_milliseconds
나가는 도중과 다시 들어오는 두 곳에서 사용하는 것만으로도 위험을 줄일 수 있습니다 .
그리고 하나 더 예 : 귀하에게 어떤 기간 나타내는 정수로 변환 할하자 말 system_clock
지원 (마이크로, 10 일 마이크로 또는 나노 초)를. 그러면 위와 같이 밀리 초를 지정하는 것에 대해 걱정할 필요가 없습니다. 코드는 다음과 같이 단순화됩니다.
int main ()
{
using namespace std::chrono;
auto now = system_clock::now();
auto integral_duration = now.time_since_epoch().count();
system_clock::time_point dt{system_clock::duration{integral_duration}};
if (dt != now)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
이것은 작동하지만 한 플랫폼에서 변환의 절반 (적분으로)을 실행하고 다른 플랫폼에서 나머지 절반 (적분에서 입력)을 실행 system_clock::duration
하면 두 변환에 대해 다른 정밀도를 가질 위험 이 있습니다.
std::chrono::duration<long,std::milli> dur
하며 그 후에도 반올림 오류가 발생할 수 있습니다 (std::chrono::system_clock
아마도 밀리 초보다 높은 해상도 를 가짐 ).