Java 8 içerisinde zaman temsili için yeni bir Date-Time API geliştirildi. Java programlama dilinde zamansal işlemler için JSR 310: Date and Time API şartnamesi yer almaktadır. Java 8 ile birlikte yeniden düzenlenen bu şartname, yepyeni özellikler sunmaktadır. Yeni geliştirilen Date-Time API’nin referans implementörü ThreeTen projesidir.
Yeni Date-Time API ile kolay kullanım, anlaşılırlık, thread-safety gibi hususlarda iyileştirmeler karşımıza çıkıyor. Bu yeni API’ ye dair bileşenler (sınıf, arayüz, enum vs.) java.time paketi altında yer almaktadır. Şimdi sizlerle java.time paketi içerisinde yer alan bileşenler ile ilgili kolay anlaşılır örnekler paylaşmak istiyorum.
java.time paketindeki sınıfların genel olarak kurucu metodu private erişim belirleyicisine sahiptir, bu sebeple new anahtar ifadesiyle oluşturulamazlar. Onun yerine now, of , from, parse gibi metodlarla yeni nesneler oluşturulabilmektedir. java.time paketi içerisindeki zamansal sınıflar immutable’ dir. Bu sebeple bir nesne oluşturulduktan sonra içerisindeki veriler kesinlikle düzenlenemezler. Bu da mevcut sınıfları thread-safety hale getirmektedir. (
Bkz. Thread safety & immutability). Bu yazımızda LocalDate
, LocalTime
, LocalDateTime
, ZoneId
ve ZonedDateTime
sınıflarının kullanımını irdeleyeceğiz.
LocalDate sınıfı ile tarihsel zaman temsil edilir. Örneğin: 10/10/2010
tarihini LocalDate
ile temsil edebiliriz.
Örnekler
"of" metodu ile LocalDate
nesnesi oluşturulabilir.
LocalDate.of(1988, 07, 16); // 1988-07-16
LocalDate.of(1988, Month.JULY, 16) // 1988-07-16 (Month enum)
"now" metodu ile o anın tarihi elde edilir.
LocalDate now = LocalDate.now(); // 2014-04-05
"with*" metodu ile eldeki bir LocalDate
için gün, ay, yıl alanları düzenlenebilir. LocalDate sınıfı immutable
’dir. Bu sebeple with metodu farklı bir LocalDate nesne döndürür. O anki nesneyi düzenlemez.
LocalDate now = LocalDate.now(); // 2014-04-05
now.withYear(2016); // 2016-04-05
now.withMonth(8).withDayOfMonth(17); // 2014-08-17
now
.with(ChronoField.YEAR, 2012)
.with(ChronoField.MONTH_OF_YEAR, 8)
.with(ChronoField.DAY_OF_MONTH,3); // 2012-08-03
"plus*" metodu ile eldeki bir LocalDate için gün, ay, yıl alanları artırılabilir. LocalDate
sınıfı immutable’dir. Bu sebeple plus
metodu farklı bir LocalDate nesne döndürür. O anki nesneyi düzenlemez.
now
.plusWeeks(2)
.plusDays(3)
.plusYears(3)
.plusDays(7); //
now
.plus(2, ChronoUnit.WEEKS)
.plus(3, ChronoUnit.YEARS)
.plus(3, ChronoUnit.DECADES); //
"minus*" metodu ile eldeki bir LocalDate için gün
, ay
, yıl
alanları azaltılabilir. LocalDate
sınıfı immutable’dir. Bu sebeple minus metodu farklı bir LocalDate nesne döndürür. O anki nesneyi düzenlemez.
now.minusDays(5).minusMonths(2); //
now
.minus(2, ChronoUnit.WEEKS)
.minus(3, ChronoUnit.YEARS)
.minus(33, ChronoUnit.DAYS); //
LocalTime sınıfı ile saatsel zaman temsil edilir. Örneğin: 20:11 , 18:15:55
saatlerini LocalTime ile temsil edebiliriz. LocalTime
ile saat, dakika, saniye, salise temsil edilebilir.
Örnekler
LocalTime now= LocalTime.now();
LocalTime time= LocalTime.of(18, 20, 55); // 18:20:55
time.getHour(); // 18
time.getMinute(); // 20
time.getSecond(); // 55
LocalTime.NOON; // 12:00
LocalTime.MIDNIGHT; // 00:00
LocalTime.parse("10:05"); // 10:05
time
.plusSeconds(45)
.minusSeconds(5)
.minus(5, ChronoUnit.SECONDS); // 18:20:35
LocalDateTime sınıfı ile hem tarihsel hem saatsel zaman temsil edilir. Örneğin: 10/10/2010 15:22:33
zamanını LocalDateTime
ile sınıfsal olarak temsil edebiliriz.
Örnekler
LocalDateTime now = LocalDateTime.now();
LocalDateTime dateTime =
LocalDateTime.of(2014, Month.JANUARY, 3, 4, 5, 45);
dateTime.getYear(); // 2014
dateTime.getMonth(); // JANUARY
dateTime.getDayOfMonth(); // 3
dateTime.getHour(); // 4
dateTime.getMinute(); // 5
dateTime.getSecond(); // 45
// LocalDateTime2LocalDate ve LocalDateTime2LocalTime
LocalDate date = dateTime.toLocalDate();
LocalTime time = dateTime.toLocalTime();
dateTime
.minusDays(3)
.plusYears(3)
.plusMinutes(3)
.minusWeeks(5)
.plusSeconds(2)
.plus(3, ChronoUnit.DECADES)
.minus(3, ChronoUnit.DECADES);
ZoneId sınıfı, dünya üzerindeki saat dilimlerinin Java taraflı nesnel karşılığını temsil için oluşturulan yeni bir Java 8 bileşenidir.
Java 8 için tüm saat dilimlerinin listelenmesi için ZoneId
sınıfının getAvailableZoneIds
metodu kullanılabilmektedir. Örneğin aşağıdaki kod, tüm saat dilimlerini sıralı olarak listelemektedir.
Set<String> zones = ZoneId.getAvailableZoneIds();
zones.stream().sorted().forEach(System.out::println);
… Africa/Abidjan Africa/Accra Africa/Addis_Ababa … America/Argentina/Tucuman America/Argentina/Ushuaia America/Aruba America/Asuncion … Asia/Istanbul Asia/Jakarta Asia/Jayapura … Etc/GMT+12 Etc/GMT+2 Etc/GMT+3 … Europe/Isle_of_Man Europe/Istanbul Europe/Jersey …
O anki çalışılan makinadaki saat dilimi için ZoneId sınıfının systemDefault metodu kullanılabilir.
ZoneId.systemDefault(); // Europe/Athens
JVM varsayılan saat dilimini mevcut işletim sistemi üzerinden almaktadır. Eğer istenirse mevcut Java sanal makinesinin varsayılan saat dilimi -Duser.timezone=<Time Zone>
ifadesiyle düzenlenebilmektedir.
-Duser.timezone=Europe/Istanbul gibi.
ZonedDateTime sınıfı aslında saat dilimi katıştırılmış LocalDateTime sınıfıdır desek yeridir. LocalDateTime sınıfından farkı genel olarak temsil ettiği zamanı saat dilimi içerir olarak sunmasıdır.
Örnekler
ZonedDateTime.now();
/* 2014-04-05T16:33:16.320+03:00[Europe/Athens] */
ZoneId istanbul = ZoneId.of("Europe/Istanbul");
ZonedDateTime.now(istanbul);
// 2014-04-05T16:33:16.330+03:00[Europe/Istanbul]
// Japonyada tarih/saat kaç?
ZonedDateTime.now(ZoneId.of("Japan"));
// 2014-04-05T22:33:16.331+09:00[Japan]
Bir ZonedDateTime
nesnesi LocalDateTime
, LocalDate
ve LocalTime
karşılıklarına dönüştürülebilmektedir.
LocalDateTime localDateTime = japan.toLocalDateTime();
/* 2014-04-05T22:33:16.331 */
LocalDate localDate = japan.toLocalDate(); // 2014-04-05
LocalTime localTime = japan.toLocalTime(); // 22:33:16.331
Kaynaklar
[1] http://www.threeten.org/ [2] http://java.dzone.com/articles/introducing-new-date-and-time [3] http://docs.oracle.com/javase/tutorial/datetime/index.html
Tekrar görüşmek dileğiyle..