18 Kasım 2013 Pazartesi

DateTime'ı String Olarak Okuma ve Yazma İşlemleri

Not : DateTime İşlemleri başlıklı yazıya göz atabilirsiniz.

ISO 8601 formatında yazma

Joda
Joda zaten ISO 8601 formatında çalışmak üzere tasarlandığı için bu işlem çok kolay.
DateTimeFormatter sınıfını yaratan 3 tane factory sınıftan birisi olan ISODateTimeFormat sınıfını kullanmak yeterli.


//Çıktı olarak : bugünün tarihi olan 2012-05-08T08:48:02.332+03:00 alırız

DateTime dt = new DateTime();
DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
String str = fmt.print(dt);
Eğer istenirse DateTimeFormatter DateTime sınıfının toString() metoduna da geçilebiliyor. Örnek:
DateTimeFormatter formatter = DateTimeFormat.forPattern("MM/dd/yyyy");
DateTime dateTime = new DateTime();
dateTime.toString(formatter);
Boost
to_iso_extended_string veya to_iso_string() metodları ile verilen nesne stringe çevirilebilir.
//Çıktı olarak 2011-08-02 alırız.


Belirsiz bir formatta yazma

Joda
String dateFormat = ("MM/dd/yyyy");
DateTime date;
String formattedDate = DateTimeFormat.forPattern(dateFormat).print(date);
Aşağıda DateTimeFormat sınıfının kullanım ile ilgili daha detaylı bilgi var.

SQL
Oracle Date veri tipini kendi bildiği bir yapıda saklıyor.
 Bu yapıyı istediğimiz bir şekle çevirmek için TO_CHAR metodunu kullanırız. Örnek:


-------------------------------------OKUMA İŞLEMLERİ-----------------------------------------------
ISO 8601 formatında okuma
ISO8601 tarihleri standartlaştırıyor. Aşağıdaki şekilde görülebilir.

ISO8601 basic ve extended format olarak kullanılabiliyor. Basic formatta arada hiç ayraç yokken, extended formatta tarih alanları arasında "-" , zaman alanları arasında ise ":" işareti kullanılıyor. Saniyeden ile milisaniye arasında ise "." ayracı var. Tarih ve zaman alanları arasındaki T işareti ise opsiyonel.

Bu standart ile 3 türlü gösterim şekli var. Bildiğimiz takvim gösterimi, Yılın kaçıncı günü gösterimi (Ordinal), Yılın kaçıncı haftası gösterimi (Week). Aşağıdaki şekildeki tarihlerin hepsi aynı zamanı gösteriyor.

Boost
date
Date sınıfının from_simple_string metodu ISO8601 formatında günleri okuyabiliyor. Örnek:

ptime
Boost ile gelen from_iso_string() metodu ile delimeter kullanmayan stringleri okuyup tekrar zamana çevirebilme imkanı var.
//Çıktı olarak 2012-Sep-27 06:23:39 verir 
std::cout << boost::posix_time::from_iso_string("20120927T062339");
time_from_string metodu ile de delimeter kullanan stringi okuma imkanı var. Örnek:


iso_extended_string formatında okuma işlemini ise buradan aldım. boost'un time_input_facet sınıfının set_iso_extended_format metodu ile belirtilen formatta okuma yapılabiliyor.

Joda

Eğer timezone UTC ise aşağıdaki gibi parse edebiliriz.

DateTimeFormatter formatter = ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC);
DateTime datetime = formatter.parseDateTime(dateAsString); 


Bir başka örnekte ise 
DateTime.parse("2012-08-16T07:22:05Z") //UTC saat dilimindeki ISO8601 saat örneği

yukarıdaki ile aynı işlemi yapar.


Yalnız yukarıdaki örneklerde verilen saat kendi saat dilimimize göre çevirilir.
Eğer çevirilme yapılmasın isteniyorsa aşağıdaki gibi yapılabilir.
val date1 = formatter.withOffsetParsed().parseDateTime("2012-01-03T00:00:00Z");
veya
val formatter = ISODateTimeFormat.dateTimeNoMillis
val date1 = formatter.withZone(DateTimeZone.UTC).parseDateTime("2012-01-03T00:00:00Z")
Eğer parse işlemi başarısız olursa IllegalArgumentException atılır.

ISO 8601'in başka formatları da vardır. Örneğin ISO week date (xxxx-'W'ww-e yani  2006-W52-7) veya sadece date (yyyy-MM-dd yani 1981-04-05) gibi. Bu tür stringleri parse etmek için aşağıdaki örnek kullanılabilir.


Belirsiz bir formatta okuma
boost
boost ile gelen boost::gregorian::date_input_facet ve boost::posix_time::time_input_facet sınıflarını kullanarak  date veya datetime okuma imkanı var.

Örnek:
boost'un time_input_facet sınıfı ile belirtilen formatta okuma yapılabiliyor.
Bir başka örnek:
  

Örneği buradan aldım.
 
Java
Formatlama işleme için kullanılan parametrelerin görevleri aşağıdaki gibi.

Gün İçin
dd : Ayın kaçıncı günü olduğunu okur örneğin 08-AUG-12 12.00.00 AM için dd 08 kısmını okumak için kullanılır.
DD : Yılın kaçıncı günü olduğunu okur

EEE :  Günün harf olarak kısaltılmış halini okur. Örneğin İngilizce locale kullanılıyorsa "Sun" gibi
Ay için
MMM : Ayın harf olarak kısaltılmış halini okur. Örneğin İngilizce locale kullanılıyorsa "Dec" gibi
MM : Ayın rakam olarak girilmiş halini okur
Yıl İçin
yyyy : Yılı okur
yy :  Yılı 19xx olarak okur. 12 rakamı için 2012 yerine 1912'yı bulur. Kullanılmasını tavsiye etmem.
Saat İçin
hh : AM/PM formatında saati okur. Saat değeri 1-12 arasındadır.
HH : 24 saat formatında saati okur. Saat değeri 0-23 arasındadır.
aa : AM/PM kısmını okur
Dakika İçin
mm : Dakikayı okur
Saniye İçin
ss : Saniyeyi okur
Milisaniye İçin
SSS: Milisaniyeyi okur
Saat Dilimi İçin
z : Saat dilimi kısmını okur. Saat dilimlerine isim verilir.
Z : RFC 822 formatında saat dilimi. Bu formatta saat dilimi -0700 şeklinde gösterilir.

Java ile SimpleDateFormat sınıfı bu işi hallediyor.

DateFormat dateFormat = new SimpleDateFormat("E M d HH:mm:ss z yyyy");
Date date = dateFormat.parse("Thu Jun 07 13:01:59 IST 2007");
Bir başka örnekte eğer istenirse kullanılan tarih deseni applyPattern() metodu ile değiştirilebiliyor.
Apache Commons
DateUtils sınıfının parseDate veya parseDateStrictly metodları kullanılarak, formatını hiç bilmediğimiz bir stringi bir format dizisi vererek, okumak mümkün.

Joda ve DateTimeFormat.forPattern
Aşağıdaki örnek ISO 8601 ile aynı olmasına rağmen elle parse ediliyor.
String date = "2010-10-03T16:58:07.000+02:00";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
DateTime dateTime = formatter.parseDateTime(date);
Burada dikkat edilmesi gereken nokta DateTimeFormat sınıfına "dd.MM.yyyy" verilse bile yıl alanına 4 haneli yıl yerine iki haneli yıl girilse bile doğru parse ediyor. Örneği yıla 12 girilirse yılı 2012 yerine direk olan M.S. 12 gibi algılıyor.

Bir başka örnek ise
String date = "Sun, 20 May 2012 01:07:11 +0000";
DateTimeFormatter formatter = DateTimeFormat.forPattern("EEE, dd MMM YYYY HH:mm:ss Z");
DateTime dateTime = formatter.parseDateTime(date);

Joda ve DateTimeFormatter.patternForStyle
Buradaki soruda anlatıldığı gibi patternForStyle metodu ile  locale'e göre Short,Medium,Long,Full deseni bulunabilir.

Joda ve DateTimeFormatter.withOffsetParsed
DateTimeFormatter.parseDateTime() metodu verilen string'i yerel saat dilimine çevirir. Ancak çevirmesin istiyorsak withOffsetParsed() ile kullanabiliriz. Örnek:
DateTimeFormatter dfOne = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss 'GMT'Z yyyy");

//Yerel saate çevirir
//Mon Mar 16 04:10:40 GMT+0530 2009
DateTime dateTime1 = dfOne.parseDateTime("Mon Mar 16 8:40:40 GMT+1000 2009");

//Yerel saate çevirmez
//Mon Mar 16 08:40:40 GMT+1000 2009
DateTime dateTime3 = dfOne.withOffsetParsed().parseDateTime("Mon Mar 16 8:40:40 GMT+1000 2009");

 
Joda ve DateTimeFormatterBuilder
Android using Joda time to calculate diference between dates başlıklı soruda DateTimeFormatterBuilder kullanımına bir örnek var.

 Bir başka örnek ise
QT
QDate fixDate = QDate::fromString ("27092012", "ddMMyyyy");
C#
DateTime.ParseExact ile istenilen formatta okuma yapılabilir. Örnek:
DateTime date = DateTime.ParseExact(txtDate.Text, "dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture); 
Bir başka örnekte ise
DateTime a = DateTime.ParseExact("2013-Jan-31", "yyyy-MMM-dd", CultureInfo.InvariantCulture);
DateTime.TryParseExact metodu ise birden çok formatta okuma işlemini yapabilmeyi sağlar.

DateTime sınıfı da aynı QT'deki gibi Date ve Time olarak ayrı ayrı property'lere ayrılabilir.



Hiç yorum yok:

Yorum Gönder