25 Mart 2014 Salı

C++, Java, QT Stream sınıfları

Stream Sınıfları Hiyerarşisi
Konuyu C++ Streamleri başlıklı yazıya taşıdım.

ios_base ve locale

ios_base sınıfı template parametrelerine bağımlı olmayan ve tüm stream sınıflarının kullandığı ortak özellikleri içerir.

STL ile gelen IOStream kütüphanesinde kullanılan tüm streamlerin içinde bir locale nesnesi bulunur.
Bu durumu gösteren örnek bir şekli buradan aldım.

imbue() metodu kullanılarak stream'in kullandığı locale değiştirilebilir. Ancak When to Imbue a New Locale başlıklı yazıda yazıldığı gibi eğer stream buffer içinde veri varsa locale değiştirmemek gerekir.

Daha detaylı bilgi için Locale İşlemleri başlıklı yazıya göz atabilirsiniz.

C programlarında locale atamakC programlarında setlocale(int category,const char* locale) metodu kullanılır.

Atanmış olan locale'i almak için
setlocale(LC_ALL,NULL) yapılır.
Örnek:
printf ("C locale is : %s\n", setlocale(LC_ALL, 0)) ; //C locale is : C verir
C++ programlarında locale nesnesi yaratmak
facade vererek bir locale yaratmak
Örnek  :
std::locale fct (std::locale::classic(),boost::posix_time::time_input_facet("%d.%m.%Y %H:%M:%S"));
C++ programlarında locale atamak
C++ ile locale yazısına taşıdım.

Java'da ise locale isimleri için Locale.getISOLanguages() ve Locale.getISOCountries() metodları kullanılabilir. Örnek:


Stream'in locale'ini Almak
Örnek:
cout<<"C++ locale: "<<cout.getloc().name();//C++ locale: C

stream ve yardımcı metodlar
peek
Eğer stream'in sonuna geldiyse stream.peek () == EOF döner.

C programları

C programlarında kullanılan locale aşağıdaki şekilde görünen fonksiyonları etkiler.



QT
STL'e alternatif olabilecek bir diğer kütüphaneyi de karşılaştırma yapabilmek için eklemek istedim. QT ile gelen I/O kütüphanesinin hiyerarşisini buradan aldım ve aşağıya ekledim.

QIODevice tüm kütüphanenin başlangıç noktası. STL'den farklı olarak socketler de I/O kapsamında değerlendirilmiş.

Yine STL'den farklı olarak streamlere yazarken encode/decode işlemlerinı yapabilme imkanı sağlayan bir soyutlama katmanı daha getirilmiş ve QDataStream ile QTextStream sınıfları geliştirilmiş. Bu sınıflardan QDataStream big endian veya little endian olarak herhangi bir QIODevice sınıfına yazıp okuyabilme imkanı sağlıyor. Aşağıdaki şekli buradan aldım ve kullanım durumunu gösteriyor.
Reading the same file with several different streams in Qt sorusunda da açıklandığı gibi QDataStream veya  QTextStream sınıfları kullanılsa bile QIODevice sınıfı yazılacak pozisyonu tutuyor.
QTextStream
QTextStream sınıfı ile C'deki sscanf fonsiyonu gibi verilen string'i parçalayarak okuma mümkün. Örnek burada.

QBuffer
QBuffer sınıfı QByteArray sınıfına arayüz gibi kullanılıyor. Böylece herhangi bir şeyi byte array haline çevirmek kolaylaşıyor. Örnek için buradan aldığım koda bakabilirsiniz.

 
Java
Stream ve Karakterler Arasındaki Köprü
Java'da stream ve karakterler arasındaki köprüyü sağlayan iki sınıf var. InputStreamReader ve OutputStreamWriter.

InputStreamReader

Java da geniş bir I/O kütüphanesine sahip. C++ ile aralarındaki en büyük farklardan birisi ise Java ile gelen Reader/Writer sınıfları. istringstream sınıfı bir stream (yani ham byte'lardan) string okuyabilirken aynı işi yapan Java sınıfı ise InputStreamReader. Java InputStreamReader sınıfı sayesinde ham byte'lardan encoderlar vasıtasıyla dönüşüm yapabilme imkanı bulunuyor.

BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("infilename"), "UTF-8"));
 Soket'tten okuma yapmak içinse
Socket echoSocket = new Socket("myserver", 7);
BufferedReader in = new BufferedReader(new InputStreamReader(
                        echoSocket.getInputStream()));

OutputStreamWriter
Bu işlemin tam tersini yapan sınıf ise OutputStreamWriter.


Sadece Stream Sınıfları

FileInputStream
FileInputStream sınıfını kullanırken en çok dikkat edilmesi gereken konu stream ile işimiz bitince close() metodunun çağırılması. Böylece dosya için konulan kilit bırakılır. Eğer bu metodu çağırmazsak finalize() metodu garbage collector tarafından çağırılıncaya kadar dosya kilitli kalabilir. Force java to release all file locks/handles in Java sorusunda da benzer bir açıklama var.


Sadece Reader Sınıfları

BufferedReader

BufferedReader sınıfı okuma işlemi için tampon belleği kullanarak I/O işlemlerini kolaylaştırır.

readLine metodu

Bu metod ile tüm satırı okuma imkanı var

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in,"UTF-8"));
while (reader.ready()) {
  String line = reader.readLine();
}

Sadece Writer Sınıfları 
PrintWriter
PrintWriter sınıfı verilen OutputStream'i bir Writer haline çeviren köprü işlevini görür. Eğer encoding ile kullanılmak istenirse örnek kod kullanılabilir.


StringWriter
StringWriter sınıfı dosya yerine hafızadaki bir tamponda girdileri biriktirir. println() metodunu sağlayan PrintWriter sınıfı ile beraber kullanılması daha kolaydır. Burada beraber kullanımı gösteriyor.

Scanner

Java zengin olduğu için bir de Scanner sınıfına sahip. Bu sınıf ile Reader/Writer arayüzlerini kullanmadan stream'den okuma yapmak mümkün. Scanner aşağıdaki kurucu metod imzasına sahip.

Örnek
Scanner sc = new Scanner(System.in,"UTF-8");
while(sc.hasNext()) {
  String next = sc.nextLine();
}
Yukarıdaki kullanımda Scanner sınıfı BufferedReader sınıfı gibi kullanılmış. Buradaki soruda ikisinin arasındaki bazı farklardan bahsediliyor. Örneğin Scanner içindeki tampon BufferedReader sınıfından daha küçük ancak esas fark, Scanner sınıfının primitif veri tipleri okumak üzere tasarlanmış olması.

Scanner sınıfının hasNextInt () metodu ise buradaki gibi kullanılabilir.

Bu kullanım şekliyle C'deki scanf'i andırıyor.

scanf'in döngü içinde kullanılabilmesini sebebi ise verilen tipten kaç tane okuyabildiğini dönmesi. Örnek:

Reflection ve Streamler

ObjectOutputStream ve ObjectInputStream sınıfları bir nesneyi stream'e binary olarak yazıp okuyabilmemizi sağlarlar. ObjectOutputStream yazma işleminden önce bir header yazdığı için kaç byte okuyacağını ve her alanın büyüklüğünü bilir. Aşağıdaki örnekte bir nesneyi TCP üzerinden bu sınıfları kullanarak gönderip alma gösterilmiş.


3 Mart 2014 Pazartesi

Dosya İşlemleri - Okuma

Dosyayının Satırlarını Okuma
C++
Tam benzemese de bir örnek burada var. Döngü kurmadan tüm dosyayı okumak kolaylaşıyor.

C#
File.ReadLines metodu kullanılarak satırlar sırayla okunabilir. ReadLines bir IEnumerable döndüğü için istenirse ilk 10 satırı okumak ta çok kolay. Örnek:
var first10Lines = File.ReadLines(path).Take(10).ToList();

Java
Java ile satırları okumak için Scanner veya BufferedReader kullanılabilir.
Scanner örneği
Scanner scanner = new Scanner(new File(filename));
while (scanner.hasNextLine()) {
      String line = scanner.nextLine();
      //Process line
}
BufferedReader ve FileReader örneği
Aşağıdaki örnekte FileReader kullanılıyor ancak FileReader dosyayı okumak için encoder kullanmamıza izin vermiyor. Dolayısıyla kullanılması tavsiye edilmiyor.
BufferedReader br = new BufferedReader(new FileReader("textfile.txt"));
while (br.ready()) {
    String sCurrentLine = br.readLine(); 
    //Process line

}
BufferedReader ve InputStreamReader örneği
Aşağıdaki örnekte InputStream ile UTF8 encoding kullanan dosya okunabiliyor.
FileInputStream in = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(in,"UTF8"));
while (br.ready()) {

    String sCurrentLine = br.readLine();
    //Process line
}
Eğer istenirse her satır okunduktan sonra toCharArray() metodu ile array olarak ta işlenebilir.

Apache Commons
FileUtils.lineIterator ile başarılıyor.Örnek:

QT
QTextStream sınıfı kullanılabilir. Örneği buradan aldım.

Plot-to-Track Tracker

Aşağıdaki  cümleyi buradan aldım:
Savunma alanında sensor veri füzyonu hedeflerin konum ve kimliklerine ait en iyi kestirimi elde edebilmek, eksiksiz ve zamanında durum değerlendirmesi ve tehdit analizi yapabilmek amacı ile kısıtlı çözünürlük ve kaplama alanına sahip, farklı hata seviyelerinde çalışan sensörlerden ve bilgi kaynaklarından gelen verilerin eşleştirilmesi(correlation), birbiri ile ilişkilendirilmesi (association) ve birleştirilmesi (combining) olarak tanımlanmaktadır.

Eşleştirme (correlation) nitelik olarak aynı tip bilgilere sahip nesnelerin gruplandırılması olarak tanımlanabilir. Örneğin iki farklı radar tarafından rapor edilen iki izin aynı (gerçek) temasa ait olup olmaması “eşleştirme” işlemidir.

Birleştirme (association) ise farklı tip bilgilere sahip nesnelerin gruplandırılması olarak tanımlanabilir. Örneğin bir edt izi ile bir radar izinin aynı temasa ait olup olmadıklarının testi ise “ilişkilendirme” işlemidir.

Birleştirme (combining) ise eşleştirme / ilişkilendirme işlemleri sonucu aynı gerçek dünya nesnesine ait
olduğu belirlenerek gruplandırılan bilgilerin birleştirilme işlemidir.

İzlerin sınıflandırılması

Bir plot-to-track tracker anladığım kadarıyla izleri şu şekilde sınıflandırmalı.

  1. ConfirmedTrack : Yeterince plot hit etmiş ve iz olduğu kesin olarak bilinen nesne. Yeterince kelimesi ile belli bir sayı kast ediliyor. Örneğin buradaki yazıda 3 kere hit alan bir nesnenin iz olarak teşhis edildiği belirtilmiş.
  2. TentativeTrack   : Arka arkaya birden fazla plot almış ve gerçek iz olma olasılığı yüksek olan aday nesne. Yukarıdaki örnekten yola çıkarsak 2 kere hit almış nesne kast edilir.
  3. PotentialTrack    : Bir plot hiti almış almış nesne

Plot bilgisinin toplanması

Plot-to-track tracker bir çok sensörden bilgi toplayacağı için concurrent bir yapıda çalışmalı. Bunun için iki tane yapıdan biri seçilmeli.
  • İlk seçenek her plot bilgisi geldiğinde bunu tracker'a hemen sokmak ve iz yapısını güncellemek. 
  • İkinci seçenek ise gelen plot bilgilerini biriktirerek periyodik olarak tracker'a sokmak. 
Geleneksel olarak Plot-to-track trackerlar radar antenleri gibi periyodik olarak çalışacak şekilde tasarlanmışlardır. Bu yüzden birinci metodun kullanıldığını bu çeşit trackerlarda hiç görmedim.

Covariance Matris
Sensörden gelen bilgi belli bir oranda hatalıdır. Eğer sensörün hata oranı bilinirse gönderdiği ölçümler covariance matris ile dönüştürülerek ölçüm hatası düzeltilmeye çalışılır.

Hava Manevraları
Burada temel hava savaşı manevraları var. İyi bir tracker bu manevraların hepsini takip edebilmeli.

Algoritma

Algoritma aslında basit ve şu adımlardan oluşuyor :

Öncelikle tüm sensörlerden plotlar orijinlerine göre bir indeksleme yapabilen bir veri yapısı içinde depolanırlar.

Eğer tracker'ın platformu hareketli bir platform ise (örneğin uçak, gemi vs.) önce elimizde bulunan izler için bir pozisyon düzeltmesi yapmak gerekebilir (ownship correction).

Daha sonra yeni gelen plotlar önce ConfirmedTrack izleri ile ilişkilendirilmeye çalışılır. İlişki kurma işleminden  sonra ConfirmedTrack izleri güncellenir.

İlişki kurulamayan plotlar bu sefer TentativeTrack izleri ile ilişkilendirilmeye çalışılır. İlişki kurma işleminden  sonra TentativeTrack izleri incelenir ve eğer gerekiyorsa bazıları ConfirmedTrack olarak sistemde terfi ettirilir.

İlişki kurulamayan plotlar bu sefer PotentialTrack denenir. Eğer bir PotentialTrack belli bir süre boyunca hiç hit almazsa bu iz silinir. Belli bir süre boyunca hit almış plotlar ise TentativeTrack olarak sistemde terfi ettirilir.

Yeni gelen ve hiç bir PotentialTrack ile ilişkilendirilemeyen plotlar ise eğer Non Automatic Initiation (NAI) sahası içine düşmüyorlarsa yeni bir PotentialTrack olarak sisteme eklenir.

24 Şubat 2014 Pazartesi

Gabya Sınıfı Fırkateyn ve 3D Radar

Hangi Gemilere Takılıyor
Gabya sınıfı fırkateynlerdeki hava arama radarıın 2 boyutlu olduğunu içeren "Gabya Sınıfı Fırkateyn" yazısından sonra bazı gemilere (F494 Gökçeada, F495 Gediz, F496 Gökova, F497 Göksu) "Thales Smart-S MK2" 3 boyutlu hava arama radarı takılma projesi başlatıldı.

F246 SalihReis MEKO sınıfı bir fırkateyn olmasına rağmen bu gemilere de aynı radar takılıyor. Burada radar görülebilir.. Diğer MEKO'larda ise AWS-9 radarı bulunuyor.

Bu radar aynı zamanda Kolombiya donanmasındaki FS-1500 fırkateynlerinde de kullanılıyor. Endonezya donanması bu radarın yanında yine Thales ürünü Variant radarını da kullanıyor.

 Smart-S MK2 Radarı

Radarın tanıtım videosunu aşağıda bulabilirsiniz.

Radarın dönüşünü gösteren bir diğer video ise yine aşağıda.

Bu radar gemide bulunan Genesis-GSYS (Genesis-Gabya Savaş Yönetim Sistemi) sistemine de entegre edilecek. Radar deniz yüzeyini yalayarak gelen Mach 3+ hızındaki füzeleri ve 70 dereceden fazla açılarla yaklaşan cisimleri tesbit edebiliyor. SMART-S MK2 radarı 160 adede kadar hava hedefi ve 40 adede kadar deniz hedefini aynı anda izleyebilir.

Not : Aynı radar Milgem projesinde de kullanıldı. "Milgem ve 3D Radar"başlıklı yazıyı okuyabilirsiniz.

Proje neticesinde bazı yazılarda modernizasyona tabi tutulan bu gemilere Gökçeada sınıfı, tutulmayan diğer gemilere ise Gaziantep sınıfnı dendiğini gördüm ancak resmi olarak böyle bir ayrım henüz yok.

Bu radar S bandında çalışıyor. Geleneksel ve yeni bant isimlendirmesi için buraya bakınız. Yeni isimlendirmeye göre bu radar F bandına düşüyor ancak ben bu yazıda geleneksel bant isimlerini kullandım.

Radarın menzili 250 km ve muhtemelen L bandında çalışan AN/SPS-49 radarına göre daha fazla enerji çekiyordur.
 AN/SPS-49 Radarı

Radarın bandı
S bandında çalışan radarların L band radarlara göre idamesi biraz daha güç olmasına rağmen bu radarın üreticisi "solid state" teknolojisi kullandığını ve "high availability" sağladığını söylüyor. S bant radarların L radarlara göre dalga boyu daha küçük olduğu için daha küçük bir anten gerektiriyorlar. Buna ek olarak S band radarlar meteorolojik şartlardan daha az etkilenirler. Ayrıca bu radar kıyılarda (littoral) çalışmak üzere optimize edilmiş.

Radarın Üretimi
Cihazların üretimi konusunda Thales Türkiye ve Endonezya'da benzer bir model izliyor. İlk iki radarı kendi üretiyor kalanları ise satış yaptığı ülkede monte ediliyorlar. Endonzeya LCS gemilerinde uygulanan bu modeli burada görebilirsiniz.

ESSM
Bu modernizasyon programı kapsamında ayrıca gemilere Lockheed Martin tarafından üretilen MK 41 dikey lançerleri de takılmış. Bir çok füze çeşidini fırlatabilen bu sistemle beraber füze ve hava hedeflerine karşı koruma sağlayan ESSM (Evolved Sea Sparrow Missile) füzeleri de alınmış.ESSM radar güdümlü bir öz savunma füzesi. Hatta Roketsan ESSM füzesinin  uçuş sonlandırma biriminin tasarım, test ve üretimini gerçekleştiriyor.

ESSM ve SM-1'in amacı ve görevi farklıdır.ESSM geminin kendini koruması için tasarlanmıştır ve 4'lü gruplar halinde atılırlar. SM-1 ise daha uzun menzilli bir hava savunma füzesidir. Gemi kendini korumak için aşağıdaki sırayı izler.
  1. Daha uzun menzilli olan SM-1 füzesi.
  2. Daha kısa menzilli olan ESSM füzesi.(supersonik ve seyir füzelerini de avlayabliyor)
  3. Nokta savunması sağlayan Phalanx veya RAM 
ESSM ile SM-1 füzesinin beraber kullanılması durumu ise şu linkte açıklanmış. Böylece gemiye kademeli bir koruma sağlanıyor. ESSM'in en büyük avantajı sahip oldugu INS + X veya S band up-link ile, sadece terminal safhada aydinlatma radarina ihtiyac duymasi.
Özet olarak  "Thales Smart-S MK2" radarı yeni ESSM füzesini güdümlemek için de kullanılıyor.

SMART-L
Bu yazıyı yazdıktan sonra SMART-S Mk2 radarını müteakip SMART-L radarının çıktığını farkettim. Bu radar çok daha uzun menzilli.

Anlaşıldığına göre SMART-S radarının ilk ismi sadece SMART iken bu radarın çıkmasıyla beraber ismi SMART-S olarak değiştirilmiş.
 

SMART-L radarı

Bu radar yapılan bir yazılım güncellemesiyle ortaya çıkan Smart-L ELR (Extended Long Range) modelinin 400 km öteden ateşlenen bir balistic füzeyi tesbit edebildiği yazılıyor. 2012 yılında çıkan Royal Netherlands Navy and Thales Sign SMART-L Early Warning Capability Contract başlıklı yazıya göre balistik füze tesbit edebilme yeteneği Hollanda donanmasında kullanılmaya başlanmış.

Buradan aldığım şekilde Smart-L radarının yayın yeteneği ile ilgili bir şekil görebilirsiniz.
Yükseliş açısı (Elevation angle) hakkında bilgi almak için Radar Temelleri başlıklı yazıyı okuyabilirsiniz.

18 Şubat 2014 Salı

Groovy

Binary İndirilmesi
Groovy groovy-binary-2.1.8.zip indirildikten sonra açılır.

Bat Dosyasından Çalıştırma
Açılan dizinde groovy-2.1.8\bin\groovy.bat ile bir .groovy uzantısına sahip dosya çalıştırılabilir. Örnek:
groovy.bat test.groovy
Groovy Kabuğundan Çalıştırma
Groovysh.bat groovy kabuğudur. Bu kabukta groovy komutları çalıştırılabilir. 

Konsoldan Çalıştırma
groovyConsole.bat dosyasına çift tıklanır. Açılan konsol penceresine groovy dosyası yazılır ve çalıştırılır.

Groovy ve Java
Groovy bir şekilde Java sınıflarına yeni metodlar ekliyor. Buna metaclass deniyor.

Sınıf Tanımlama
Sınıfların static alanları olabilir. Örnek
def class MyClass {
 def property1
 def static property2
}
Dosyanın Başına Metin Ekleme
FileOutputStream kullanımını buradan aldım.
def file = new File("D:/test.txt");
def text = "new line\r\n" + file.text;

new FileOutputStream(file).withStream{ it ->
  it.channel.truncate(0);
}
file.append (text);

Listeler
Liste Tanımlama ve Ekleme
Örnek
def myList = []
def myObject = new MyObject (Name : "test")
myList.add (myObject)
Liste Üzerinde Yürüme
each metodu ile yapılabilir. Örnek
def list = ["1","2"]
list.each () {print "${it}" }

XML
Okumak
XML taglerine XPath'teki gibi path vererek kolayca erişilebilir.

def xmlFile = new File ("./config.xml")
def xml = new XmlParser (xmlFile)
xml.Domains.Server.each {
    if (it.@Name = "Server1") {}
}

Yazmak
groovy.xml.MarkupBuilder sınıfı kullanılır. Örnek'te şöyle bir xml yazılır

<MyTag>
 <MySubtag myattr ="1"/>
<MyTag>


def writer = new StringWriter
writer << '<xml version="1.0" encoding="UTF-8"?>' << '\n'

def xml = new groovy.xml.MarkupBuilder (writer)
xml.setDoubleQuotes (true)

xml.MyTag
{
  'MySubtag' ('myattr' : "${value}")
}

def xmlFile = new File ("My.xml")
xmlFile.write (writer.toString())

9 Şubat 2014 Pazar

İki Tarih Arasındaki Fark - Zaman Aralığı

Not : DateTime İşlemleri Yazısı çok uzun olduğu için içeriğin bir kısmını buraya taşımayı uygun buldum.
Giriş

İki tarih arasındaki fark ile zaman eksenindeki iki noktanın arasındaki mesafeyi ölçüyoruz. Bu mesafe bir çok birim cinsinden ifade edilebilir. Yıl, ay, hafta, gün, dakika vs. gibi.

İki tarih arasındaki farkı bulma amacımız bazen sadece mesafeyi ölçmek iken bazen de iki tarih aralığı arasına düşen kayıtları bulmak olabiliyor.

Bu yazının amacı verilen iki tarih arasındaki farkı yıl/ay/hafta vs gibi birimler cinsinden nasıl bulunacağını göstermek.

Ölçüm sonunda çıkan mesafeyi gösteren süre kavramı ile ilgili sınıfları Süre Temsili başlıklı yazıda bulabilirsiniz.

Aynı Saat Dilimindeki İki Tarih Arasındaki Farkı Ölçmek
C++
Yeni C++ ile chrono namespace'i içinde duration isimli bir sınıf var. Bu sınıf zaman aralığını temsil ediyor. Kullanım kolaylığı için diğer typedef'ler de aşağıdaki gibi tanımlanmış.

namespace std {
namespace chrono {
typedef duration<signed int-type >= 64 bits,nano>        nanoseconds;
typedef duration<signed int-type >= 55 bits,micro>       microseconds;
typedef duration<signed int-type >= 45 bits,milli>       milliseconds;
typedef duration<signed int-type >= 35 bits>             seconds;
typedef duration<signed int-type >= 29 bits,ratio<60>>   minutes;
typedef duration<signed int-type >= 23 bits,ratio<3600>> hours;
}
}
Typedef'e verilen ilk tip - örneğin signed int - birimin tutulacağı primitif tipi belirtir, ikinci parametre olan ratio ise küsüratlı durumlarda saniyeye göre oranı belirtir. Örnekte yarım dakika double tutulacağı için ilk parametre double, ikinci parametre toplam değerin 30 saniye olması için ( 60 * 0.5) 60 tanımlanmış.

std::chrono::duration<double,std::ratio<60>>halfAMinute(0.5);
Bir diğer örnekte ise aşağıda

std::chrono::duration<long,std::ratio<1,1000>> oneMillisecond(1);

Java
TimeUnit sınıfı kullanılabilir.

Calendar cal = Calendar.getInstance ();
cal.clear ();
cal.set (2013,Calendar.MARCH,1);
Date start = cal.getTime ();
cal.set (2013,Calendar.APRIL,1);
Date end = cal.getTime ();
long days = TimeUnit.MILLISECONDS.toDays (end.getTime () - start.getTime ());

C#
C# ile verilen iki tarih arasındaki farkı bulmak için TimeSpan sınıfı var. Bu sınıfta aralığın başlangıç ve bitiş değerleri yok sadece mesafe bilgisi var.  Yani bu sınıf sadece tick'ler ile ilgileniyor.

    DateTime pastTime = //değer ata
    TimeSpan timeSinceContact = DateTime.Now - pastTime;

    // 14 gün geçmişse
    if (timeSinceContact.Days > 14){
    }

TimeSpan sınıfının en işe yarayan özelliklerinden birisi ise TotalSeconds.

Örnek:
 
boost
date sınıfı
Aşağıdaki örnekte iki tarih arasındaki gün farkı bulunuyor. boost'un date sınıfı kullanıldığı için sadece gün farkı bulunur. Saat hesabı yapılmaz.

time_duration sınıfı
Bu sınıf ile iki tarih arasında fark saat ve dakika olarak bulunabilir.
is_negative() , hours() ve minutes() metodları
Örnek:
using boost::posix_time::ptime;
const boost::posix_time::ptime utcNow = boost::posix_time::second_clock::universal_time();
const ptime localTime = boost::date_time::c_local_adjustor<ptime>::utc_to_local(utcNow);
const boost::posix_time::time_duration td = localTime -
utcNow;
td.is_negative(){...}
td.hours();
td.minutes()


ticks metodu
Bir başka örnekte iki tarih arasındaki fark saniye olarak hesaplanmış. Niçin total_seconds() metodu kullanılmamış bilmiyorum.

Joda

Özet

Joda'da aynı saat dilimindeki iki tarih arasındaki farkı ölçmek için bir çok sınıf kullanılabilir. Bu sınıflar temel olarak ikiye ayrılırlar. 

  1. İlk sınıf Period ismiyle anılır. Period'un bir çok alt türevi de mevcuttur. 
  2. İkinci sınıf ise Duration sınıfıdır.

Duration Sınıfı Nedir?
Duration sınıfı tanım olarak süre anlamına geliyor. Başlangıç ve bitişi tanımlı olmak zorunda değil. Period'dan farklı olarak milisaniye cinsinden çalıştığı için genellikle daha kısa aralıklar - 10 dakika vs. - gibi kullanılıyor. Zaten sınıfın açıklamasında "specifying a length of time in milliseconds." deniliyor.

Joda Period Sınıfı Nedir ?
Periyod tanım olarak başlangıç ve bitişi belli olan zaman aralığı anlamına geliyor. Duration'dan farklı olarak daha uzun aralıklar için kullanılıyor. 3 gün 2 saat gibi.

Joda Period ve  Alt Türevleri

Eğer amacımız 2 gün 3 saat 10 dakika gibi bir sonuç elde etmekse Period sınıfını kullanmak gerekir. Yok amacımız sadece 2 gün bilgisini elde etmek saat,dakika bilgilerini dikkate almamak ise BaseSingleFieldPeriod sınıfından türeyen Months, Days,Hours, Minutes gibi sınıfları kullanabiliriz. Aşağıdaki sınıf hiyerarşisi bu durumu gösteriyor.



Joda Duration sınıfını Oluşturmak
Duration sınıfını oluşturmak için iki tane tarih kullanılabilir. Örnek:
DateTime startTime,endTime;
Duration d = new Duration (startTime,endTime);

Joda Period Sınıfını Oluşturmak
Period sınıfını oluşturmak için iki tane tarih kullanılabilir. Örnek :

Joda PeriodType Sınıfı

Bazen farkı bulurken belli birimleri görmek istemeyiz. Bu durumda PeriodType sınıfını aşağıdaki örnekteki  gibi kullanabiliriz.
Period p = new Period(startDate, endDate,PeriodType.standard().withSecondsRemoved().withMillisRemoved());
Bu durumda aradaki farkı saniye ve milisaniye olmadan buluruz. Period sınıfı string'e dönüşürken de bu birimler yazılmaz.
 
Joda Period Sınıfı ve hours() toStandardHours() metodları arasındaki fark
Period sınfı iki tane saate çeviren metod içeriyor. Aralarındaki fark ise bu soruda açıklanmış. Eğer iki tarih arasındaki fark bir günden büyükse hours() ile sadece saat farkını alırız, geri kalan gün ise getDays() ile alınıyor. toStandardHours() ise toplam saat farkını veriyor.

Joda PeriodFormat Sınıfı
PeriodFormat sınıfı Period sınıfını string'e çevirmek için kullanılıyor. Örnek:
DateTime sd = new DateTime(1973,1,1,0,0,0);
DateTime ed = new DateTime(1973,1,31,23,59,59);
Period p = new Period(sd,ed);
//Çıktı olarak 4 weeks, 2 days, 23 hours, 59 minutes and 59 seconds verir
System.out.println(PeriodFormat.getDefault().print(p));
Joda PeriodFormatterBuilder Sınıfı
Bu sınıfı PeriodFormat sınıfını yaratmak için kullanılıyor. Örnek olarak aşağıdaki kod parçasını buradan aldım.
PeriodFormat sınıfı ile verilen Period'u istenilen formatta yazdırma
Timer - How do I calculate the difference between two dates using Joda Time? örneğinde ise
DateTime dt = new DateTime();
DateTime twoHoursLater = dt.plusHours(2).plusMinutes(10).plusSeconds(5);
Period period = new Period(dt, twoHoursLater);
PeriodFormatterBuilder HHMMSSFormater =
        new PeriodFormatterBuilder().appendHours().
                                     appendSeparator("-").
                                     appendMinutes().
                                     appendSeparator("-").
                                     appendSeconds();
System.out.println(HHMMSSFormater.toFormatter().print(period));
PeriodFormat sınıfı ile verilen metini Period olarak okuma
Örnek:
Önce PeriodFormatBuilder kullanılarak bir PeriodFormat sınıfı oluşturuluyor ve  PeriodFormat sınıfının parse() metodu kullanılarak metin Period sınıfına çeviriliyor.

Joda SingleFieldPeriod Türevleri (İki tarih arasındaki fark)
Period ile iki tarih arasındaki farkı bir çok birim cinsinden alabiliyoruz.Eğer sadece tek bir birim cinsinden farkı öğrenmek istersek aşağıdaki sınıfları kullanabiliriz. 

Seconds
Seconds sınıfı saniye farkını bulur. Örnek:
int seconds = Seconds.secondsBetween(rightNow, targetDateTime)
Minutes
Minutes sınıfı dakika farkını bulur. Farkı bulurken time zone bilgisinin etkisiz olduğunu anlatan bu soru da oldukça bilgilendirici.



Hours
Hours sınıfı saat farkını bulur.
int hours =Hours.hoursBetween(new DateTime(today), new DateTime(StartTime1)).getHours();

Days
Days sınıfı daysBetween() metodu ile gün farkını bulur.
Bir başka örnek

Months
Örnekte iki tane tarih arasındaki fark ay cinsinden bulunuyor.
 
SQL
dobs tablosundan dob sütununu çekip sistem saatine bakarak ikisi arasındaki yılı bulan kod aşağıda.
select floor(months_between(sysdate,dob)/12) from dobs;
 

3 Şubat 2014 Pazartesi

Generics ve Kalıtım


Alt sınıfta Tekrar Üst Sınıfa Cast Etmek
Bu problem her hangi bir dilde de karşımıza çıkabilir. Probleme verilen genel bir isim var mı bilmiyorum. Ancka çözüm hemen hep aynı oluyor.

Alt sınıf kendisini kullanarak generic bir metodu çağırınca artık üst sınıfın bilgisi kaybedildiği için problem olabiliyor. Bu durumda üst sınıfın bilgisini de alt sınıfa geçmek gerekir. Aşağıdaki örnekte AbstractClass içinden Connection.Update (this) çağrılsaydı Connection sınıfı sadece Abstract class'ı bilecekti.

C#
Aşağıdaki örnekte üst sınıf kendi bilgisini kaybetmeden Connection.Update metoduna geçebiliyor.

abstract class AbstractClass<T>
where T: AbstractClass<T> //restrict T as a child of AbstractClass<T>
{
    bool update()
    {
        Connection.Update<T>(this as T);
    }
}

class Entity : AbstractClass<Entity>
{
}

class Connection
{
    public static void Update<T>(T obj)
    {
        someMethod<T>()
    }
}