Takip et

Java 8 Tarih ve Zaman API’si: LocalDate, LocalDateTime ve Instant

Java 8 Tarih ve Zaman API’si: LocalDate, LocalDateTime ve Instant Java’nın eski tarih ve zaman API’si (java.util.Date ve java.util.Calendar), geli

Java 8 Tarih ve Zaman API’si: LocalDate, LocalDateTime ve Instant

Java’nın eski tarih ve zaman API’si (java.util.Date ve java.util.Calendar), geliştiricilere yıllarca hizmet vermiş olsa da, kullanım zorlukları, iş parçacığı güvenliği sorunları ve zaman dilimi yönetimi karmaşıklıkları nedeniyle sıklıkla eleştirilmiştir. Bu eksiklikleri gidermek amacıyla Java 8 ile birlikte tamamen yeni bir tarih ve zaman API’si olan java.time paketi tanıtıldı. Bu yeni API, Joda-Time projesinden esinlenerek daha okunabilir, değişmez (immutable) ve iş parçacığı açısından güvenli sınıflar sunar. Bu rehberde, Java 8’in en temel ve sık kullanılan tarih/saat sınıflarından olan LocalDate, LocalDateTime ve Instant‘ı detaylı olarak inceleyeceğiz.

Java 8 Tarih ve Zaman API’sinin Temelleri

java.time paketi, tarih ve zamanı çeşitli şekillerde temsil etmek için tasarlanmış bir dizi sınıf sunar. Bu sınıflar, farklı ihtiyaçlara yönelik olarak spesifik sorumluluklara sahiptir:

  • LocalDate: Yalnızca tarihi (yıl, ay, gün) temsil eder, saat veya zaman dilimi bilgisi içermez.
  • LocalTime: Yalnızca saati (saat, dakika, saniye, nanosaniye) temsil eder, tarih veya zaman dilimi bilgisi içermez.
  • LocalDateTime: Tarih ve saati bir arada temsil eder, ancak zaman dilimi bilgisi içermez.
  • Instant: Evrensel saat (UTC) tabanlı, epoch’tan itibaren geçen süreyi nanosaniye hassasiyetinde gösteren bir anlık zaman noktasıdır. Zaman dilimi bilgisi içermez, ancak bir zaman dilimiyle birleştirilerek anlam kazanır.
  • ZonedDateTime: Bir LocalDateTime‘a bir ZoneId (zaman dilimi) ekleyerek belirli bir coğrafi bölgedeki tam tarih ve zamanı temsil eder.
  • Duration: İki Instant, LocalDateTime veya LocalTime arasındaki zaman farkını saniye ve nanosaniye cinsinden ölçer.
  • Period: İki LocalDate arasındaki zaman farkını yıl, ay ve gün cinsinden ölçer.

Bu rehberde, özellikle LocalDate, LocalDateTime ve Instant üzerinde duracağız.

LocalDate: Sadece Tarih Bilgisi

LocalDate sınıfı, bir takvim tarihini (yıl, ay, gün) temsil eder. Saat veya zaman dilimi bilgisi içermez. Bu özelliği onu doğum tarihleri, tatil günleri veya bir olayın gerçekleştiği tarih gibi durumlarda ideal kılar. Değişmez (immutable) bir sınıftır, yani bir LocalDate nesnesi oluşturulduktan sonra değeri değiştirilemez; herhangi bir işlem yeni bir LocalDate nesnesi döndürür.

LocalDate Oluşturma

LocalDate nesnelerini oluşturmanın birkaç yolu vardır:

  • Mevcut Tarihi Alma: now() metodu ile sistemin varsayılan zaman dilimine göre mevcut tarihi alabilirsiniz.
  • Belirli Bir Tarih Oluşturma: of() metodu ile yıl, ay ve gün değerlerini vererek belirli bir tarih oluşturabilirsiniz.
  • Metin Dizisinden Ayrıştırma: parse() metodu ile ISO-8601 formatında bir metin dizisinden tarih ayrıştırabilirsiniz.

import java.time.LocalDate;
import java.time.Month;

public class LocalDateOrnekleri {
    public static void main(String[] args) {
        // 1. Mevcut tarihi alma
        LocalDate bugun = LocalDate.now();
        System.out.println("Bugünün tarihi: " + bugun); // Örn: 2023-10-26

        // 2. Belirli bir tarih oluşturma
        LocalDate dogumGunu = LocalDate.of(1990, 5, 15);
        System.out.println("Doğum günü: " + dogumGunu); // 1990-05-15

        LocalDate baskaBirGun = LocalDate.of(2024, Month.JANUARY, 1); // Month enum kullanılarak
        System.out.println("Başka bir gün: " + baskaBirGun); // 2024-01-01

        // 3. Metin dizisinden ayrıştırma
        LocalDate tatilGunu = LocalDate.parse("2023-12-31");
        System.out.println("Tatil günü: " + tatilGunu); // 2023-12-31

        // Hatalı formatta ayrıştırma denemesi (DateTimeParseException fırlatır)
        // LocalDate hataliTarih = LocalDate.parse("31.12.2023"); 
    }
}

LocalDate ile İşlemler

LocalDate, tarih üzerinde çeşitli manipülasyonlar ve sorgulamalar yapmanızı sağlayan zengin bir metod setine sahiptir:

  • Tarih Bileşenlerini Alma: getYear(), getMonth(), getDayOfMonth(), getDayOfWeek() gibi metotlar.
  • Tarih Ekleme/Çıkarma: plusDays(), minusMonths(), plusYears() gibi metotlar.
  • Tarihi Değiştirme: withYear(), withMonth(), withDayOfMonth() gibi metotlar.
  • Karşılaştırma: isBefore(), isAfter(), isEqual() metotları.
  • Artık Yıl Kontrolü: isLeapYear() metodu.

import java.time.DayOfWeek;
import java.time.LocalDate;

public class LocalDateIslemleri {
    public static void main(String[] args) {
        LocalDate bugun = LocalDate.now();
        System.out.println("Bugün: " + bugun);

        // Tarih bileşenlerini alma
        int yil = bugun.getYear();
        Month ay = bugun.getMonth();
        int gun = bugun.getDayOfMonth();
        DayOfWeek haftaninGunu = bugun.getDayOfWeek();

        System.out.println("Yıl: " + yil + ", Ay: " + ay + ", Gün: " + gun + ", Haftanın Günü: " + haftaninGunu);

        // Tarih ekleme/çıkarma (yeni nesne döndürür)
        LocalDate gelecekHafta = bugun.plusWeeks(1);
        System.out.println("Gelecek hafta: " + gelecekHafta);

        LocalDate gecmisAy = bugun.minusMonths(1);
        System.out.println("Geçmiş ay: " + gecmisAy);

        // Tarihi değiştirme (yeni nesne döndürür)
        LocalDate yeniYil = bugun.withYear(2025).withMonth(1).withDayOfMonth(1);
        System.out.println("Yeni Yıl (2025): " + yeniYil);

        // Karşılaştırma
        LocalDate yarin = bugun.plusDays(1);
        System.out.println("Bugün yarından önce mi? " + bugun.isBefore(yarin)); // true
        System.out.println("Bugün yarına eşit mi? " + bugun.isEqual(yarin));   // false

        // Artık yıl kontrolü
        LocalDate artikYil = LocalDate.of(2024, 1, 1);
        System.out.println("2024 artık yıl mı? " + artikYil.isLeapYear()); // true
        LocalDate normalYil = LocalDate.of(2023, 1, 1);
        System.out.println("2023 artık yıl mı? " + normalYil.isLeapYear()); // false
    }
}

Pratik Bilgiler: LocalDate

  • Veritabanı Saklama: LocalDate genellikle SQL’deki DATE tipi sütunlara doğrudan eşlenebilir. JPA/Hibernate gibi ORM’ler Java 8 tarih tiplerini otomatik olarak destekler.
  • Doğum Tarihleri: Kişilerin doğum tarihlerini saklamak için mükemmeldir, çünkü saat veya zaman dilimi doğum gününün kendisi için genellikle önemsizdir.
  • Etkinlik Tarihleri: Belirli bir günde gerçekleşecek etkinliklerin tarihlerini (konserler, resmi tatiller) yönetmek için kullanışlıdır.

LocalDateTime: Tarih ve Saat Bilgisi

LocalDateTime sınıfı, bir tarih (yıl, ay, gün) ve bir saat (saat, dakika, saniye, nanosaniye) kombinasyonunu temsil eder. Ancak, LocalDate gibi, herhangi bir zaman dilimi bilgisi içermez. Bu, onu belirli bir yerel bağlamda (örneğin, bir sunucunun yerel saati veya bir kullanıcının zaman dilimi henüz belirlenmemiş bir etkinlik saati) tarih ve saati kaydetmek için uygun kılar. Eğer zaman dilimi önemliyse, ZonedDateTime veya Instant kullanmalısınız.

LocalDateTime Oluşturma

LocalDateTime nesneleri de benzer yöntemlerle oluşturulabilir:

  • Mevcut Tarih ve Saati Alma: now() metodu ile.
  • Belirli Bir Tarih ve Saat Oluşturma: of() metodu ile.
  • Metin Dizisinden Ayrıştırma: parse() metodu ile ISO-8601 formatında.
  • LocalDate ve LocalTime Birleştirme: Var olan bir LocalDate ve LocalTime nesnesini birleştirerek.

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class LocalDateTimeOrnekleri {
    public static void main(String[] args) {
        // 1. Mevcut tarih ve saati alma
        LocalDateTime simdi = LocalDateTime.now();
        System.out.println("Şimdi: " + simdi); // Örn: 2023-10-26T10:30:45.123456789

        // 2. Belirli bir tarih ve saat oluşturma
        LocalDateTime randevu = LocalDateTime.of(2023, 11, 15, 14, 30);
        System.out.println("Randevu: " + randevu); // 2023-11-15T14:30

        LocalDateTime etkinlik = LocalDateTime.of(2024, 1, 1, 9, 0, 0, 0); // Nanosaniye ile
        System.out.println("Etkinlik: " + etkinlik); // 2024-01-01T09:00

        // 3. Metin dizisinden ayrıştırma
        LocalDateTime logZamani = LocalDateTime.parse("2023-10-26T08:00:00");
        System.out.println("Log Zamanı: " + logZamani); // 2023-10-26T08:00

        // 4. LocalDate ve LocalTime birleştirme
        LocalDate tarih = LocalDate.of(2023, 12, 25);
        LocalTime saat = LocalTime.of(18, 0);
        LocalDateTime noelPartisi = LocalDateTime.of(tarih, saat);
        System.out.println("Noel Partisi: " + noelPartisi); // 2023-12-25T18:00
    }
}

LocalDateTime ile İşlemler

LocalDateTime de LocalDate‘a benzer manipülasyon metotlarına sahiptir, ancak hem tarih hem de saat bileşenleri üzerinde işlem yapabilir:

  • Bileşenleri Alma: getYear(), getMonth(), getHour(), getMinute() vb.
  • Ekleme/Çıkarma: plusDays(), minusHours(), plusMinutes() vb.
  • Değiştirme: withDayOfMonth(), withHour() vb.
  • Karşılaştırma: isBefore(), isAfter(), isEqual().

import java.time.LocalDateTime;

public class LocalDateTimeIslemleri {
    public static void main(String[] args) {
        LocalDateTime simdi = LocalDateTime.now();
        System.out.println("Şimdi: " + simdi);

        // Saat bileşenlerini alma
        int saat = simdi.getHour();
        int dakika = simdi.getMinute();
        System.out.println("Saat: " + saat + ", Dakika: " + dakika);

        // Tarih ve saat ekleme/çıkarma
        LocalDateTime gelecekHaftaAyniSaat = simdi.plusWeeks(1);
        System.out.println("Gelecek hafta aynı saat: " + gelecekHaftaAyniSaat);

        LocalDateTime besSaatSonra = simdi.plusHours(5);
        System.out.println("5 saat sonra: " + besSaatSonra);

        // Tarih ve saati değiştirme
        LocalDateTime geceYarisi = simdi.withHour(0).withMinute(0).withSecond(0).withNano(0);
        System.out.println("Bugünün gece yarısı: " + geceYarisi);

        // Karşılaştırma
        LocalDateTime yarinAyniSaat = simdi.plusDays(1);
        System.out.println("Şimdi yarından önce mi? " + simdi.isBefore(yarinAyniSaat)); // true
    }
}

Pratik Bilgiler: LocalDateTime

  • Veritabanı Saklama: SQL’deki DATETIME veya TIMESTAMP (zaman dilimi olmayan) sütunlara eşlenebilir.
  • Kullanıcı Arayüzü Gösterimi: Kullanıcının kendi yerel zaman diliminde görmesi gereken tarih ve saatler için başlangıç noktası olabilir. Ancak, global uygulamalarda bu bilgiyi ZonedDateTime‘a dönüştürmek genellikle daha güvenlidir.
  • Loglama: Bir uygulamanın yerel zaman diliminde olayları kaydetmek için yaygın olarak kullanılır.

Instant: Anlık Zaman Noktası (UTC)

Instant sınıfı, zaman çizelgesinde tek, değişmez bir anlık noktayı temsil eder. Bu, “epoch” olarak bilinen 1 Ocak 1970 UTC’den bu yana geçen saniye sayısıyla ölçülür ve nanosaniye hassasiyetine kadar desteklenir. Instant, insan odaklı bir tarih ve saat bilgisi yerine, makine odaklı, evrensel (UTC) bir zaman damgasıdır. Zaman dilimi veya takvim sistemi bilgisi içermez.

Instant Oluşturma

  • Mevcut Anı Alma: now() metodu ile.
  • Epoch’tan Oluşturma: ofEpochSecond() veya ofEpochMilli() metotları ile.
  • Metin Dizisinden Ayrıştırma: parse() metodu ile ISO-8601 formatında (YYYY-MM-DDThh:mm:ss.nnnnnnnZ).

import java.time.Instant;

public class InstantOrnekleri {
    public static void main(String[] args) {
        // 1. Mevcut anı alma (UTC)
        Instant simdiInstant = Instant.now();
        System.out.println("Şimdi (Instant): " + simdiInstant); // Örn: 2023-10-26T07:30:45.123456789Z ('Z' UTC'yi belirtir)

        // 2. Epoch'tan saniye veya milisaniye ile oluşturma
        Instant epochSaniye = Instant.ofEpochSecond(0);
        System.out.println("Epoch başlangıcı: " + epochSaniye); // 1970-01-01T00:00:00Z

        Instant onSaniyeSonra = Instant.ofEpochSecond(10);
        System.out.println("Epoch'tan 10 saniye sonra: " + onSaniyeSonra); // 1970-01-01T00:00:10Z

        Instant epochMilisaniye = Instant.ofEpochMilli(1678886400000L); // 2023-03-15 00:00:00 UTC
        System.out.println("Milisaniyeden oluşturulan Instant: " + epochMilisaniye); // 2023-03-15T00:00:00Z

        // 3. Metin dizisinden ayrıştırma
        Instant belirliAn = Instant.parse("2023-01-01T00:00:00Z");
        System.out.println("Belirli bir an: " + belirliAn); // 2023-01-01T00:00:00Z
    }
}

Instant ile İşlemler

Instant ile de zaman ekleme/çıkarma ve karşılaştırma işlemleri yapılabilir:

  • Zaman Ekleme/Çıkarma: plusSeconds(), minusMillis(), plus(), minus() metotları.
  • Karşılaştırma: isBefore(), isAfter(), isEqual() metotları.
  • Dönüşümler: toEpochMilli() metodu ile milisaniye cinsinden epoch değerini alabilirsiniz.

import java.time.Instant;
import java.time.Duration;

public class InstantIslemleri {
    public static void main(String[] args) {
        Instant simdi = Instant.now();
        System.out.println("Şimdi (Instant): " + simdi);

        // 5 dakika sonrası
        Instant besDakikaSonra = simdi.plusSeconds(300); // 5 dakika = 300 saniye
        System.out.println("5 dakika sonra: " + besDakikaSonra);

        // 2 saat öncesi (Duration kullanarak)
        Instant ikiSaatOnce = simdi.minus(Duration.ofHours(2));
        System.out.println("2 saat önce: " + ikiSaatOnce);

        // Karşılaştırma
        System.out.println("Şimdi 5 dakika sonradan önce mi? " + simdi.isBefore(besDakikaSonra)); // true

        // Epoch milisaniyesine dönüştürme (eski Date API ile uyumluluk için)
        long epochMilli = simdi.toEpochMilli();
        System.out.println("Epoch milisaniye: " + epochMilli);
    }
}

Pratik Bilgiler: Instant

  • Veritabanı Saklama: SQL’deki TIMESTAMP WITH TIME ZONE veya BIGINT (epoch milisaniye/saniye olarak) sütunlara eşlenebilir. En güvenli ve taşınabilir yol genellikle epoch değerini (long) saklamaktır.
  • Sistemler Arası İletişim: Farklı zaman dilimlerinde çalışan sistemler arasında zaman damgalarını iletmek için idealdir. Tüm sistemler aynı anlık noktayı (UTC) referans alır, bu da zaman dilimi dönüşümlerindeki hataları önler.
  • Olay Sıralaması: Olayların kronolojik sırasını belirlemek için kullanılır, çünkü zaman diliminden bağımsızdır.

Zaman Dilimleri ile Çalışma: ZoneId ve ZonedDateTime

LocalDate ve LocalDateTime yerel tarih ve saatleri temsil ederken, Instant evrensel bir zaman noktasını temsil eder. Ancak gerçek dünya uygulamalarında genellikle belirli bir zaman dilimindeki tarih ve saati bilmemiz gerekir. İşte burada ZoneId ve ZonedDateTime devreye girer.

ZoneId: Bir coğrafi bölgenin zaman dilimini temsil eder (örneğin, “Europe/Istanbul”, “America/New_York”).

ZonedDateTime: Bir LocalDateTime‘a bir ZoneId ekleyerek belirli bir zaman dilimindeki tam tarih ve saati temsil eder.

Dönüşümler


import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class ZamanDilimiOrnekleri {
    public static void main(String[] args) {
        // İstanbul zaman dilimi
        ZoneId istanbulZone = ZoneId.of("Europe/Istanbul");
        System.out.println("İstanbul Zaman Dilimi: " + istanbulZone);

        // New York zaman dilimi
        ZoneId newYorkZone = ZoneId.of("America/New_York");
        System.out.println("New York Zaman Dilimi: " + newYorkZone);

        // 1. LocalDateTime'dan ZonedDateTime'a
        LocalDateTime yerelSimdi = LocalDateTime.now();
        System.out.println("Yerel şimdi (LocalDateTime): " + yerelSimdi);

        ZonedDateTime istanbulSimdi = ZonedDateTime.of(yerelSimdi, istanbulZone);
        System.out.println("İstanbul şimdi (ZonedDateTime): " + istanbulSimdi); // Kendi yerel saatinizi İstanbul'a göre ayarlar

        // 2. Instant'tan ZonedDateTime'a
        Instant evrenselSimdi = Instant.now();
        System.out.println("Evrensel şimdi (Instant): " + evrenselSimdi);

        ZonedDateTime istanbulAnlik = ZonedDateTime.ofInstant(evrenselSimdi, istanbulZone);
        System.out.println("İstanbul anlık (ZonedDateTime): " + istanbulAnlik);

        ZonedDateTime newYorkAnlik = ZonedDateTime.ofInstant(evrenselSimdi, newYorkZone);
        System.out.println("New York anlık (ZonedDateTime): " + newYorkAnlik);

        // Farklı zaman dilimlerinde aynı anın gösterimi
        System.out.println("Aynı anın İstanbul'da görünümü: " + istanbulAnlik.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss VV")));
        System.out.println("Aynı anın New York'ta görünümü: " + newYorkAnlik.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss VV")));

        // ZonedDateTime'dan Instant'a geri dönüş
        Instant geriDonenInstant = istanbulAnlik.toInstant();
        System.out.println("Geri dönen Instant: " + geriDonenInstant); // Orijinal Instant ile aynı olmalı
    }
}

Önemli Not: LocalDateTime.now(), JVM’in çalıştığı makinenin varsayılan zaman dilimini kullanır. Bu nedenle, LocalDateTime‘dan ZonedDateTime‘a dönüşüm yaparken, ZonedDateTime.of(localDateTime, zoneId) metodu, localDateTime‘ın zaten belirtilen zoneId‘da olduğu varsayılır. Eğer localDateTime‘ın başka bir zaman diliminde olduğunu ve belirtilen zoneId‘a dönüştürülmesi gerektiğini düşünüyorsanız, önce Instant‘a dönüştürüp sonra ZonedDateTime.ofInstant(instant, zoneId) kullanmak daha güvenlidir.

Formatlama ve Ayrıştırma (DateTimeFormatter)

Tarih ve zaman nesnelerini kullanıcı dostu metinlere dönüştürmek (formatlama) ve metinlerden tarih/zaman nesneleri oluşturmak (ayrıştırma) için DateTimeFormatter sınıfı kullanılır.


import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class FormatlamaAyrıştırma {
    public static void main(String[] args) {
        LocalDate tarih = LocalDate.of(2023, 10, 26);
        LocalDateTime tarihSaat = LocalDateTime.of(2023, 10, 26, 14, 35, 50);
        Instant anlik = Instant.now();
        ZonedDateTime zdt = ZonedDateTime.ofInstant(anlik, ZoneId.of("Europe/Istanbul"));

        // 1. Önceden Tanımlanmış Formatlayıcılar
        System.out.println("LocalDate (ISO_DATE): " + tarih.format(DateTimeFormatter.ISO_DATE)); // 2023-10-26
        System.out.println("LocalDateTime (ISO_LOCAL_DATE_TIME): " + tarihSaat.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); // 2023-10-26T14:35:50
        System.out.println("Instant (ISO_INSTANT): " + anlik.format(DateTimeFormatter.ISO_INSTANT)); // 2023-10-26T07:35:50.123456789Z

        // 2. Özel Formatlayıcılar
        DateTimeFormatter ozelTarihFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy EEEE");
        System.out.println("Özel Tarih Formatı: " + tarih.format(ozelTarihFormat)); // 26.10.2023 Perşembe

        DateTimeFormatter ozelTarihSaatFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        System.out.println("Özel Tarih/Saat Formatı: " + tarihSaat.format(ozelTarihSaatFormat)); // 2023/10/26 14:35:50

        DateTimeFormatter ozelZdtFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss VV");
        System.out.println("Özel ZonedDateTime Formatı: " + zdt.format(ozelZdtFormat)); // 2023-10-26 10:35:50 Europe/Istanbul

        // 3. Ayrıştırma
        String tarihStr = "15.08.2024";
        LocalDate ayrilmisTarih = LocalDate.parse(tarihStr, DateTimeFormatter.ofPattern("dd.MM.yyyy"));
        System.out.println("Ayrıştırılmış Tarih: " + ayrilmisTarih); // 2024-08-15

        String tarihSaatStr = "2023-01-01 12:00:00";
        LocalDateTime ayrilmisTarihSaat = LocalDateTime.parse(tarihSaatStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println("Ayrıştırılmış Tarih/Saat: " + ayrilmisTarihSaat); // 2023-01-01T12:00
    }
}

Sonuç

Java 8’in java.time paketi, tarih ve zaman yönetimi için modern, temiz ve güçlü bir çözüm sunar. LocalDate, LocalDateTime ve Instant sınıfları, farklı ihtiyaçlar için özel olarak tasarlanmıştır:

  • LocalDate: Yalnızca tarih bilgisi gerektiren durumlar (doğum günleri, tatiller).
  • LocalDateTime: Zaman dilimi bilgisi olmadan tarih ve saat bilgisi gerektiren durumlar (yerel olaylar, log kayıtları).
  • Instant: Evrensel, zaman diliminden bağımsız bir anlık zaman noktası (sistemler arası iletişim, veritabanı zaman damgaları).
Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.