MERHABA! Bugün, daha önce karşılaşmadığımız yeni bir veri türüyle, yani tarihlerle çalışmaya başlayacağız. Zamanda nasıl kaybolmazsınız: DateTime ve Calendar - 1Randevunun ne olduğunu açıklamama gerek yok sanırım. :) Prensip olarak, güncel tarih ve saati sıradan bir Java Dizisinde saklayabiliriz.

public class Main {
   public static void main(String[] args) {

       String date = "June 11, 2018";
       System.out.println(date);
   }
}
Ancak bu yaklaşımın birçok dezavantajı vardır. Sınıf String, metinle çalışacak şekilde tasarlanmıştır ve yöntemleri bu görev için uygundur. Bir tarihi bir şekilde değiştirmemiz gerekirse (örneğin 2 saat ekleyin), Stringpek iyi çalışmaz. Ya da program derlendiğinde o anki tarih ve saati göstermek istiyorsak. Stringburada da yardımcı olmuyor: kodu yazıp çalıştırdığınızda, zaman değişmiş olacak ve konsol yanlış bilgileri gösterecek. Bu nedenle Java'nın yaratıcıları, tarih ve saat ile çalışmak için çeşitli sınıflar sağladı. Bunlardan ilkijava.util.Date

Tarih sınıfı

Tam adını belirttik çünkü bu java.sql.Datesınıfa başka bir Java paketi sahip. Onları karıştırmayın! Bununla ilgili bilmeniz gereken ilk şey, tarihi 1 Ocak 1970'ten bu yana geçen milisaniye sayısı olarak saklıyor olmasıdır. Bu zaman sisteminin kendi adı bile vardır: " Unix-time " Oldukça ilginç bir yaklaşım, katılıyor musun? :) Hatırlanması gereken ikinci şey şudur: Varsayılan yapıcıyı kullanarak bir nesne oluşturursanız Date, sonuç, nesnenin oluşturulduğu andaki geçerli tarih ve saati gösterir . StringOlarak temsil edilen bir tarihin böyle bir görevle mücadele edeceğini söylediğimizi hatırlıyor musunuz ? Sınıf Datekolaylıkla halleder.

public class Main {
   public static void main(String[] args) {

       Date date = new Date();
       System.out.println(date);
   }
}
Bu kodu birkaç kez çalıştırın ve zamanın art arda değiştiğini göreceksiniz. :) Bu mümkündür, çünkü süre milisaniye olarak kaydedilir: bunlar son derece küçük zaman birimleridir, bu nedenle sonuçlar oldukça doğrudur. Başka bir yapıcı sınıfı Date: 1 Ocak 1970 saat 00:00'dan bu yana geçen tam milisaniye sayısını gerekli tarihe iletebilirsiniz ve buna karşılık gelen bir tarih nesnesi oluşturulur:

public class Main {
   public static void main(String[] args) {

       Date date = new Date(1212121212121L);
       System.out.println(date);
   }
}
Konsol çıktısı: 30 Mayıs Cuma 04:20:12 GMT 2008 30 Mayıs 2008 tarihini alırız. "Cuma" haftanın gününü (Cuma, duh) ve GMT saat dilimini (Greenwich Ortalama Saati) belirtir. Milisaniye sayısı s olarak iletilir long, çünkü milisaniye sayısı genellikle bir int. Peki, tarihlerle hangi işlemleri gerçekleştirmemiz gerekebilir? Elbette en bariz olanı karşılaştırmadır . Bir tarihin diğerinden önce mi yoksa sonra mı geldiğini belirlemek için. Bu birkaç yolla yapılabilir. Date.getTime()Örneğin, 1 Ocak 1970 gece yarısından bu yana geçen milisaniye sayısını döndüren yöntemi çağırabilirsiniz . Yöntemi iki Date nesnesinde çağırmanız ve sonuçları karşılaştırmanız yeterlidir:

public class Main {
   public static void main(String[] args) {

       Date date1 = new Date();

       Date date2 = new Date();

       System.out.println((date1.getTime() > date2.getTime())?
               "date1 is later than date2" : "date1 is earlier than date2");
   }
}
Çıktı: tarih1, tarih2'den önce Ama daha uygun bir yol da var, örneğin Date sınıfı tarafından sağlanan özel yöntemleri kullanmak: before(), after()ve equals(). Hepsi bir boole değeri döndürür. Yöntem before(), tarihimizin argüman olarak iletilen tarihten önce olup olmadığını kontrol eder:

public class Main {
   public static void main(String[] args) throws InterruptedException {

       Date date1 = new Date();

       Thread.sleep(2000);// Suspend the program for 2 seconds
       Date date2 = new Date();

       System.out.println(date1.before(date2));
   }
}
Konsol çıktısı: true Benzer şekilde, after()yöntem tarihimizin argüman olarak iletilen tarihten sonra olup olmadığını kontrol eder:

public class Main {
   public static void main(String[] args) throws InterruptedException {

       Date date1 = new Date();

       Thread.sleep(2000);// Suspend the program for 2 seconds
       Date date2 = new Date();

       System.out.println(date1.after(date2));
   }
}
Konsol çıktısı: false Örneklerimizde, iki tarihin farklı olması garanti edilsin diye 2 saniyeliğine "programı uyku moduna alıyoruz". date1Hızlı bilgisayarlarda, ve öğesinin oluşturulması arasındaki süre date2bir milisaniyeden az olabilir ve bu da hem before()and after()öğesinin false döndürmesine neden olur. Ancak bu durumda, equals()yöntem true değerini döndürür! Sonuçta, her tarih için 1 Ocak 1970 saat 00:00'dan bu yana geçen milisaniye sayısını karşılaştırır . Nesneler, yalnızca milisaniye ile eşleşirlerse eşit kabul edilir :

public static void main(String[] args) {

   Date date1 = new Date();
   Date date2 = new Date();

   System.out.println(date1.getTime());
   System.out.println(date2.getTime());

   System.out.println(date1.equals(date2));
}
Burada dikkat etmeniz gereken bir şey daha var. OracleDate web sitesinde sınıfın belgelerini açarsanız , yöntemlerinin ve oluşturucularının çoğunun Kullanımdan Kaldırıldı olarak işaretlendiğini göreceksiniz (yani, kullanılması önerilmez). Java'nın yaratıcılarının kullanımdan kaldırılan sınıf bölümleri hakkında söyledikleri:
"@Deprecated açıklamalı bir program öğesi, genellikle tehlikeli olduğu veya daha iyi bir alternatif olduğu için programcıların kullanması önerilmeyen bir şeydir."
Bu, bu yöntemlerin hiç kullanılamayacağı anlamına gelmez. Bir IDE'de kullanımdan kaldırılan yöntemleri kullanarak kod çalıştırmayı denerseniz, büyük olasılıkla işe yarayacaktır. Örneğin, Date.getHours()bir nesneyle ilişkili saat sayısını döndüren, kullanımdan kaldırılan yöntemi düşünün Date.

public static void main(String[] args) {

   Date date1 = new Date();

   System.out.println(date1.getHours());
}
Kodu 14:21'de (14:21 PM) başlatırsanız, 14 sayısını gösterecektir. Gördüğünüz gibi, kullanımdan kaldırılan yöntemin üzeri çizilmiş, ancak yine de çalışıyor. Bu yöntemler, onları kullanan mevcut büyük kod gövdesini kırmamak için kaldırılmaz. Başka bir deyişle, bu yöntemler ne "kırılır" ne de "kaldırılır". Daha uygun bir alternatif mevcut olduğu için kullanımları önerilmez. Bu arada, belgeler özellikle bu alternatiften bahseder:
Zamanda nasıl kaybolmazsınız: DateTime ve Calendar - 2
Sınıfın yöntemlerinin çoğu Dategeliştirilmiş ve genişletilmiş sınıfa taşınmıştır Calendar. Sırada o sınıfla tanışacağız. :)

Takvim sınıfı

JDK 1.1 yeni bir sınıf tanıttı: Calendar. Java'da tarihlerle çalışmayı eskisinden biraz daha kolay hale getirdi. CalendarÇalışacağımız sınıfın tek uygulaması GregorianCalendarsınıftır. Dünyanın çoğu ülkesi tarafından gözlemlenen Gregoryen takvimini uygular. Ana avantajı, tarihlerle daha uygun bir biçimde çalışabilmesidir. Örneğin, şunları yapabilir:
  • Geçerli tarihe bir ay veya gün ekleyin
  • Yılın artık yıl olup olmadığını kontrol edin;
  • Tarihin tek tek bileşenlerini döndürür (örneğin, tüm tarihten ay sayısını çıkarın)
  • Aynı zamanda çok uygun bir sabitler sistemi içerir (birçoğu aşağıda göreceğiz).
Sınıfın bir diğer önemli geliştirmesi de Calendar.ERACalendar sabitidir : milattan önce (MÖ - İsa'dan önce) veya milattan önce (AD - Anno Domini) bir tarih belirtebilirsiniz. Bütün bunlara örneklerle bakalım. 25 Ocak 2017 tarihli bir nesne oluşturalım :calendar

public static void main(String[] args) {

  Calendar calendar = new GregorianCalendar(2017, 0 , 25);
}
Sınıfta Calendar(ve Datebu konuda sınıfta), aylar sıfırdan başlar , bu nedenle ikinci argüman olarak 0 sayısını iletiriz. Sınıfla çalışırken , bunun sadece bir takvimCalendar olduğunu, bireysel bir tarih olmadığını anlamak önemlidir . Tarih, belirli bir zaman aralığını gösteren birkaç sayıdır. Takvim, tarihlerle pek çok şey yapmanızı sağlayan bütün bir sistemdir. :) Nesneyi görüntülemeye çalışırsanız, bu fazlasıyla belirgindir : Çıktı: Zamanda nasıl kaybolmazsınız: DateTime ve Calendar - 3Calendarjava.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Avrupa/Londra",offset=0,dstSavings=0,useDaylight= false,transitions=79,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=1,ERA=?,YEAR=2017,MONTH=0,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=25,DAY_OF_YEAR=?,DAY_OF_WEEK=? ,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?] Ne kadar bilgi aldığınızı görün ! Bir takvim, normal bir tarihte olmayan bir dizi özelliğe sahiptir ve bunların tümü görüntülenir (yöntemtoString()sınıfta böyle çalışırCalendar). Takvimden basit bir tarih, yani birDatenesne almanız gerekiyorsa,Calendar.getTime()yöntem (isim en mantıklısı değil ama ne yapabilirsiniz?):

public static void main(String[] args) {

   Calendar calendar = new GregorianCalendar(2017, 0 , 25);
   Date date = calendar.getTime();
   System.out.println(date);
}
Çıktı: 25 Ocak Çarşamba 00:00:00 GMT 2017 Şimdi takvimi aldık ve onu sıradan bir tarihe "düşürdük". Daha ileri gidelim. CalendarAyları numaralarına göre belirlemeye ek olarak, sınıfın sabit alan değerlerini kullanabilirsiniz . CalendarBu sabitler , değiştirilemeyen önceden ayarlanmış bir değere sahip sınıfın statik alanlarıdır . Bu aslında daha da iyi bir seçenek çünkü bunları kullanmak kodunuzun okunabilirliğini artırıyor.

public static void main(String[] args) {
   GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
}
Calendar.JANuary , yılın aylarını temsil eden sabitlerden biridir. Bu adlandırılmış sabitleri kullanarak kimse, örneğin 3 sayısının Nisan anlamına geldiğini ve bizim Mart demeyi sevdiğimiz üçüncü ay olduğunu unutmaz. Sadece Calendar.APRIL yazın ve bitirdiniz. :) Yöntem kullanılarak tüm takvim alanları (sayı, ay, dakika, saniye vb.) ayrı ayrı belirtilebilirset(). Bu yöntem çok uygundur çünküCalendarsınıfın her alan için bir sabiti vardır ve ortaya çıkan kodun okunması çok kolaydır. Son örnekte bir tarih oluşturduk ancak bunun için bir saat belirlemedik. Saati ayarlayalım 19:42:12

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar();
   calendar.set(Calendar.YEAR, 2017);
   calendar.set(Calendar.MONTH, 0);
   calendar.set(Calendar.DAY_OF_MONTH, 25);
   calendar.set(Calendar.HOUR_OF_DAY, 19);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   System.out.println(calendar.getTime());
}
Çıktı: Çar 25 Ocak 19:42:12 GMT 2017 Yöntemi çağırıyoruz set(), bir sabit (değiştirmek istediğimiz alana bağlı olarak) ve alan için yeni bir değer iletiyoruz. set()Bu yöntemin, yalnızca bir alan için değil, birçok alan için değer ayarlamayı bilen bir tür "süper ayarlayıcı" olduğu ortaya çıktı . :) Sınıf, değerleri toplamak ve çıkarmak için yöntemi Calendarkullanır . add()Değiştirmek istediğiniz alanı ve bir sayıyı (mevcut değerden tam olarak ne kadar eklemek/çıkarmak istediğinizi) iletirsiniz. Örneğin oluşturduğumuz tarihten 2 ay öncesi olan bir tarih alalım:

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 19);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.add(Calendar.MONTH, -2); // To subtract, pass a negative number
   System.out.println(calendar.getTime());
}
Çıktı: 25 Kasım Cum 19:42:12 GMT 2016 Çok iyi! 2 ay önce randevu aldık. Bu sadece ayın değişmesine neden olmadı, yıl da 2017'den 2016'ya değişti. Elbette tarihleri ​​dönüştürürken, içinde bulunduğunuz yılı manuel olarak takip etmenize gerek kalmadan otomatik olarak hesaplanır. Ancak herhangi bir nedenle bu davranışı devre dışı bırakmanız gerekirse, bunu yapabilirsiniz. Yöntem , kalan değerleri etkilemedenroll() değerleri toplayabilir ve çıkarabilir . Örneğin, bunun gibi:

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.roll(Calendar.MONTH, -2);
   System.out.println(calendar.getTime());
}
Bir önceki örnektekiyle tamamen aynı şeyi yaptık: Geçerli tarihten itibaren 2 ay aldık. Ancak şimdi kod farklı bir şey yapıyor: ay Ocak'tan Kasım'a değişti, ancak yıl değişmeden kaldı: 2017! Çıktı: 25 Kasım Cumartesi 10:42:12 GMT 2017 İlerliyor. Yukarıda da söylediğimiz gibi tüm alanları ayrı ayrı alabiliyoruz Calendar. Bunu şu yöntemle yapıyoruz get():

public static void main(String[] args) {
   GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   System.out.println("Year: " + calendar.get(Calendar.YEAR));
   System.out.println("Month: " + calendar.get(Calendar.MONTH));
   System.out.println("Week in the month: " + calendar.get(Calendar.WEEK_OF_MONTH));// Week in this month?

   System.out.println("Day: " + calendar.get(Calendar.DAY_OF_MONTH));

   System.out.println("Hours: " + calendar.get(Calendar.HOUR));
   System.out.println("Minutes: " + calendar.get(Calendar.MINUTE));
   System.out.println("Seconds: " + calendar.get(Calendar.SECOND));
   System.out.println("Milliseconds: " + calendar.get(Calendar.MILLISECOND));

}
Çıktı: Yıl: 2017 Ay: 0 Hafta içi ay: 5 Gün: 25 Saat: 10 Dakika: 42 Saniye: 12 Milisaniye: 0 Yani sınıfın "süper ayarlayıcı" sına ek olarak Calendarbir de "süper alıcı" var ". :) Tabii bu dersin bir başka ilginç yönü de dönemlerle çalışmak. Bir "MÖ" tarihi oluşturmak için Calendar.ERA alanını kullanmanız gerekir. Örneğin, Hannibal'in Roma ordusunu yendiği Cannae Savaşı için bir tarih oluşturalım. Bu, MÖ 2 Ağustos 216'da oldu:

public static void main(String[] args) {
   GregorianCalendar cannae = new GregorianCalendar(216, Calendar.AUGUST, 2);
   cannae.set(Calendar.ERA, GregorianCalendar.BC);

   DateFormat df = new SimpleDateFormat("MMM dd, yyy GG");
   System.out.println(df.format(cannae.getTime()));
}
SimpleDateFormatBurada sınıfı, tarihi anlamamız için daha kolay bir biçimde yazdırmak için kullandık ("GG" harfleri, dönemin görüntülenmesini istediğimizi belirtir) . Çıkış: MÖ 02 Ağustos 216. Sınıfın Calendardaha birçok yöntemi ve sabiti vardır. Onlar hakkında belgelerde okuyabilirsiniz . Bu tarih biçimini beğenmediyseniz, 25 Kasım Cumartesi 10:42:12 GMT 2017,SimpleDateFormat olmasını istediğiniz gibi kolayca yapmak için kullanabilirsiniz .

public static void main(String[] args) {

   SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy");
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.roll(Calendar.MONTH, -2);
   System.out.println(dateFormat.format(calendar.getTime()));
}
Çıktı: 25 Kasım 2017 Cumartesi Böylesi çok daha iyi değil mi? :)