clock_gettime clock_gettime yazısına taşıdım
clock_gettime ve clock_getres ilişkisi
Yazının başında da belirttiğim gibi Epoch'tan beri geçen süre belli bir çözünürlükte artırılır. Bu çözünürlüğü öğrenmek için clock_getres kullanılır.
Örnek:
void pr(int clock,const char *n)
{
struct timespec tv = {1,2};
struct timespec res = {3,4};
int rc;
rc=clock_getres(clock,&res);
if (rc) {
printf("getres return code on %s=%d errno=%d\n",n,rc,errno);
}
rc=clock_gettime(clock,&tv);
if (rc) {
printf("gettime return code on %s=%d errno=%d\n",n,rc, errno);
}
else {
printf("%25s=% 11d.%09d resolution=% 2d.%09d\n",n,tv.tv_sec,tv.tv_nsec,res.tv_sec,res.tv_nsec);
}
}
Bu metod aşağıdaki gibi çağırılırsa
pr(CLOCK_REALTIME,"CLOCK_REALTIME");
şu sonucu alırız.
CLOCK_REALTIME= 1097084999.490116229 resolution= 0.000000040
Yani Epoch'tan beri geçen süre saniye + nanosaniye , resolution ise 40 nanosaniyedir.
WINDOWS
GetSystemTime
GetSystemTime yazısına taşıdım.
GetSystemTimeAsFileTime
GetSystemTimeAsFileTime yazısına taşıdım.
NtQuerySystemTime
NtQuerySystemTime yazısına taşıdım.
_ftime
_ftime ile 1 Ocak 1970 (UTC) gece yarısından (00:00:00) itibaren geçen süreyi saniye +
milisaniye çözünürlüğünde almamızı sağlar. Posix ile gelen ftime metodunun eşleniğidir.
QueryPerformanceCounter
Bu metodu sonra yazacağım.
C Dili
C dilinde time() metodu kullanılır. Epoch'tan beri geçen süreyi
saniye çözünürlüğünde almamızı sağlar. Konu uzun olduğu için
C'de Time API'leri başlıklı yazıya taşıdım.
C++ Dili
Boost
get_system_time
Bu metod boost derlenirken
microsec_clock tanımlı ise onu kullanır, değilse
second_clock'ı kullanır. thread_time.hpp dosyasında kod
görülebilir.
Thread veya condition bekleme kodlarında da aşağıdakine benzer satırlar
görülebilir.
boost::system_time timeout =
boost::get_system_time( ) +
boost::posix_time::milliseconds(1000);
second_clock
boost ile gelen date_time kütüphanesinde second_clock sınıfı ile
saniye çözünürlüğünde zaman ölçümü yapabilmek mümkün.
microsec_clock
boost ile gelen date_time kütüphanesindeki microsec_clock sınıfı ile
mikrosaniye çözünürlüğünde zaman ölçümü yapabilmek mümkün. Hatta bu kütüphane ile linux/windows arasında portable kod yazabilmek te mümkün. Bu kütüphane Linux üzerinde çalışırken yukarıda bahsedilen gettimeofday() metodunu çağırıyor.
Ancak Windows üzerinde çalışırken ftime() metodunu çağırıyor. ftime() Windows için yeterince iyi aralıkta güncellenmediği için microsec_clock'ın Windows üzerinde mikrosaniye çözünürlüğünde zaman ölçümü için kullanılması bence doğru değil. Buradaki soruda da konuyla ilgili açıklama var.
using namespace boost::posix_time;
ptime now = microsec_clock::local_time();
Bir diğer örnekte ise UTC saat alınmış.
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;
ptime now = microsec_clock::universal_time();
Eğer istenirse boost::posix_time daha az hassasiyetle de kullanılabilir. Örneğin from_time metodu ile yeni bir nesne yaratmak mümkün.
Ancak bu nesne sadece saniye hassasiyetinde olacaktır.
Boost chrono high resolution clock
Bu kütüphane ile
nanosaniye çözünürlüğünde zaman ölçümü yapabilmek mümkün.
#include <boost/chrono.hpp>
int main() {
boost::chrono::high_resolution_clock::time_point t1 = boost::chrono::high_resolution_clock::now();
boost::chrono::high_resolution_clock::time_point t2 = boost::chrono::high_resolution_clock::now();
std::cout << boost::chrono::duration_cast<boost::chrono::nanoseconds>(t2-t1) << "\n";
// boost chrono has more advanced output, .count() isn't needed, nor is manually writing out the units
}
C++11 high resolution clock
chrono sınıfları yazısına taşıdım.
QT
QDateTime::currentDateTime() ile milisaniye çözünürlüğünde zaman ölçümü yapabilmek mümkün. Aşağıdaki şekil QDateTime nesnesinin nasıl çalıştığını gösteriyor.
Java Dili
System.currentTimeMillis :
Bu API 1 Ocak 1970 (UTC) gece yarısından (00:00:00) beri geçen süreyi milisaniye çözünürlüğünde alabilmemizi sağlar. Bu metodun hassasiyeti her zaman çok iyi olmayabilir. Örneğin System.currentTimeMillis() metodunu bir döngü içinde çağırırsak gelen sonuçlarda 10-20-30 milisaniyelik atlamalar görebiliriz. Bu durumu teyit eden bir yazıyı
burada görebilirsiniz.
Benim yaptığım küçük bir deneyde de
Epoch Converter sitesindeki saniye ile System.currentTimeMillis(); hemen hemen (
1374955419 saniye ve
1374955418858 milisaniye) aynı değerleri verdiler.
Java'da Epoch zamanını yerel saat olarak nasıl gösteriyor?
Akış aşağıdaki gibi
DateFormat df = DateFormat.getDateTimeInstance (..) şeklinde formatlama sınıfı çağırılınca
DateFormat arayüzünü gerçekleştiren SimpleDateFormat sınıfı döndürülür. Bu sınıf içinde bir Calendar nesnesi barındırır. Calendar arayüzünü gerçekleştiren GregorianCalendar sınıfı'nın setTime() metodu çağırılınca, bu sınıf kendi içindeki computeFields() metodunu çağırır ve saat dilimin hesaba katarak yerel saati
bulur.
Yani her formatlama işleminde UTC saatini yerel saate çeviren hesaplama
yapılır.
Javada'ki Date ve etrafındaki sınıfların hiyerarşisini gösteren bir şekli
buradan aldım ve aşağıya ekledim.
Aşağıda ise bir başka şekil bulunmakta.
Joda
ReadableInstant sınıfı saat diliminden bağımsız olarak epoch'tan beri geçen süreyi milisaniye olarak alabilmemizi sağlar. Aşağıda bu arayüzün hiyerarşisi
var.
Bu sınıf ta altta System.currentTimeMillis(); metodunu kullanır. Örnek:
new DateTime ().getMillis();
C# dili
C# ile 1 Ocak 1970 (UTC) gece yarısından (00:00:00) beri geçen süreyi milisaniye çözünürlüğünde alabilmemizi sağlayan bir metod bulunmamaktadır ancak kolayca da yazılabilir.
TimeSpan timeSpan = DateTime.UtcNow-new DateTime(1970, 1, 1,0,0,0,DateTimeKind.Utc);
long milliSeconds = timeSpan.TotalMilliseconds;
EPOCH'tan Geriye Dönüş
Epoch'tan beri geçen süreyi bazen tekrar bir nesneye çevirmek gerekir. Bunun için aşağıda bazı notlar aldım.
C++ Dili
Boost
ptime someUTC_Time(date(2008, Jan, 1), time_duration(0, 0, 0, 0));
QT
QDateTime::fromTime_t(uint seconds) : Bu metod ile Epoch'tan beri geçen
saniyeler tekrar nesneye çevirilebilir.
Java Dili
public Date(long date) : Bu metod ile ile Epoch'tan beri geçen
milisaniyeler tekrar nesneye çevirilebilir.
Calendar.setTimeInMillis (long) : Bu metod ile Epoch'tan beri geçen
milisaniyeler tekrar nesneye çevirilebilir.
UTC ve Leap Second (Artık Saniye) UTC ve Leap Second yazısına taşıdım