Java 8 Date and Time API (java.time) Sinhala Tutorial - LocalDate, Instant Guide
හැඳින්වීම: Java වල Date/Time කළමනාකරණය පහසු කරමු!
අපේ Java project එකක දවසක්, වෙලාවක් manage කරන්න ඕන වුණාම, කීයෙන් කී දෙනාද තවමත් java.util.Date පාවිච්චි කරන්නේ? ඇත්තටම, අවංකවම කියනවා නම්, ඒක ටිකක් අවුල් සහගත, මතක තියාගන්න අමාරු API එකක්. කාලයක් තිස්සේ Java developersලා මේ ගැටලුවට මුහුණ දුන්නා. ඒක mutable (වෙනස් කළ හැකි) වීම, time zone ගැන හිතන්නේ නැති වීම, thread-safe නොවීම වගේ දේවල් නිසා අමාරුකම් ගොඩක් තිබ්බා.
හැබැයි, 2014 දී Java 8 එනකොට, මේ හැමදේටම පිළියමක් විදිහට අලුත් Date and Time API එකක් ආවා. ඒ තමයි java.time package එක. මේක Joda-Time කියන සුප්රසිද්ධ library එක මත පදනම් වෙලා නිර්මාණය කරපු, නවීන, භාවිතයට පහසු API එකක්. අද මේ article එකෙන් අපි මේ අලුත් API එකේ වැදගත් කොටස් දෙකක් ගැන කතා කරනවා: LocalDate සහ Instant. අපි බලමු කොහොමද මේවා පාවිච්චි කරලා අපේ code එක තවත් ලස්සනට, පහසුවට ලියාගන්නේ කියලා!
java.util.Date එකේ තිබ්බ ගැටළු මොනවද?
java.util.Date එකේ තිබ්බ ප්රධාන ගැටළු කිහිපයක් ගැන මුලින්ම කතා කරමු, මොකද එතකොට තමයි අලුත් API එකේ වටිනාකම හොඳින්ම තේරෙන්නේ.
- Mutable (වෙනස් කළ හැකි):
Dateobject එකක් නිර්මාණය කළාට පස්සේ ඒකේ අගය වෙනස් කරන්න පුළුවන්. මේ නිසා, අපි නොහිතන විදිහට side effects ඇති වෙන්න පුළුවන්, විශේෂයෙන්ම multi-threaded environment එකකදී. - Poor Naming (නමෙන් පැහැදිලි නැහැ):
Dateකියන නම තිබ්බට, ඇත්තටම ඒකේ දවස සහ වෙලාව කියන දෙකම අඩංගුයි. ඒ වගේම time zone එකක් define කරන්නේ නැහැ, ඒක JVM එකේ default time zone එකට අනුව තමයි වැඩ කරන්නේ. - Not Thread-Safe:
Dateobjects Thread-safe නොවන නිසා, එකමDateobject එකකට එකවර threads කිහිපයකින් access කරනකොට data corruption වෙන්න පුළුවන්. - Complicated API (සංකීර්ණ API):
java.util.Calendar,java.text.SimpleDateFormatවගේ ඒවාත් එක්කDateඑක පාවිච්චි කරන එක හරිම සංකීර්ණයි. ඒ වගේම format කරන්න, parse කරන්න අමාරුයි. Month index එක 0 ඉඳන් පටන් ගැනීම වගේ 'quirks' තිබ්බා.
මේ වගේ ප්රශ්න ගොඩක් නිසා තමයි Java community එකට වඩා හොඳ විසඳුමක් ඕන වුණේ.
java.time API එකට සාදරයෙන් පිළිගනිමු!
Java 8 සමගින් ආපු java.time API එක මේ හැම ගැටලුවකටම නවීන, පිළිගත හැකි විසඳුම් ගෙනාවා. මේකේ ප්රධානම ලක්ෂණ කිහිපයක් මෙන්න:
- Immutable (වෙනස් කළ නොහැකි): මේ API එකේ හැම object එකක්ම immutable. ඒ කියන්නේ object එකක් නිර්මාණය කළාට පස්සේ ඒකේ අගය වෙනස් කරන්න බැහැ. වෙනස්කමක් කරනවා නම් අලුත් object එකක් තමයි හැදෙන්නේ. මේක Thread-safety වලටත් උදව් වෙනවා.
- Clear Separation of Concerns (වෙන් කර හඳුනාගැනීම): Date, Time, DateTime, Instant, Duration, Period වගේ දේවල් වෙන වෙනම class වලින් නිරූපණය කරනවා. මේ නිසා code එක කියවන්න සහ තේරුම් ගන්න පහසුයි.
- Fluent API: Method chaining භාවිතයෙන් code එක ලස්සනට ලියන්න පුළුවන්. (උදා:
date.plusDays(1).minusMonths(2)) - Time Zone Support: Time zone support එක ගොඩක් හොඳට handle කරනවා.
LocalDate - දින කළමනාකරණයට (For Date Management)
LocalDate කියන්නේ දවසක් (year, month, day) නිරූපණය කරන්න පාවිච්චි කරන class එකක්. මේකේ වෙලාව හෝ time zone තොරතුරු අඩංගු වෙන්නේ නැහැ. ඔයාට user කෙනෙක්ගේ උපන් දිනය, holiday එකක් වගේ දේවල් manage කරන්න ඕන නම් LocalDate තමයි සුදුසුම දේ.
LocalDate පාවිච්චි කරන හැටි:
import java.time.LocalDate;
import java.time.DayOfWeek;
public class LocalDateExample {
public static void main(String[] args) {
// වර්තමාන දිනය ලබා ගැනීම
LocalDate today = LocalDate.now();
System.out.println("අද දවස: " + today); // Output: අද දවස: YYYY-MM-DD
// නිශ්චිත දිනයක් නිර්මාණය කිරීම (උපන් දිනයක් වගේ)
LocalDate birthday = LocalDate.of(1990, 5, 15);
System.out.println("උපන් දිනය: " + birthday); // Output: උපන් දිනය: 1990-05-15
// දින එකතු කිරීම හෝ අඩු කිරීම
LocalDate nextWeek = today.plusDays(7);
System.out.println("ලබන සතියේ දිනය: " + nextWeek);
LocalDate lastMonth = today.minusMonths(1);
System.out.println("පසුගිය මාසයේ අද දිනය: " + lastMonth);
// දිනයන් සංසන්දනය කිරීම
boolean isAfter = today.isAfter(birthday);
System.out.println("අද උපන් දිනයට පසුවද?: " + isAfter);
// සතියේ දවස, මාසය වගේ තොරතුරු ලබා ගැනීම
DayOfWeek dayOfWeek = today.getDayOfWeek();
System.out.println("අද සතියේ දවස: " + dayOfWeek); // Output: අද සතියේ දවස: MONDAY/TUESDAY etc.
int year = today.getYear();
System.out.println("වර්ෂය: " + year);
// leap year එකක්දැයි පරීක්ෂා කිරීම
System.out.println("2024 leap year එකක්ද?: " + LocalDate.of(2024, 1, 1).isLeapYear());
}
}
LocalDate කොච්චර පැහැදිලිද, පාවිච්චි කරන්න පහසුද කියලා මේ code එකෙන් පේනවා ඇති නේද? date calculations කරන එක මේකෙන් ගොඩක් simplify වෙනවා.
Instant - වේලාවේ නිශ්චිත මොහොතක් (A Specific Moment in Time)
Instant කියන්නේ කාල රේඛාවක (timeline) නිශ්චිත මොහොතක්, කාල කලාපයක් (time zone) නොසලකා. මේක සාමාන්යයෙන් යන්ත්ර මගින් කියවීමට සුදුසු (machine-readable) කාලය නිරූපණය කිරීමට යොදා ගන්නවා. Database එකකට timestamp එකක් save කරනකොට, හෝ distributed systems වල event එකක exact time එක define කරනකොට Instant එකක් පාවිච්චි කරන එක ගොඩක් ප්රයෝජනවත්.
Instant එකක් සාමාන්යයෙන් epoch (ජනවාරි 1, 1970, 00:00:00 UTC) එකෙන් පසු ගතවූ තත්පර ගණනක් හෝ නැනෝ තත්පර ගණනක් ලෙස ගබඩා වෙනවා. මේක හැම විටම UTC (Coordinated Universal Time) එකට අනුරූපයි.
Instant පාවිච්චි කරන හැටි:
import java.time.Instant;
import java.time.Duration;
public class InstantExample {
public static void main(String[] args) {
// වර්තමාන Instant එක ලබා ගැනීම (UTC)
Instant now = Instant.now();
System.out.println("වර්තමාන Instant: " + now); // Output: වර්තමාන Instant: YYYY-MM-DDTHH:MM:SS.NNNZ
// නිශ්චිත තත්පර ගණනකින් Instant එකක් නිර්මාණය කිරීම
Instant epochPlusTenSeconds = Instant.ofEpochSecond(10);
System.out.println("Epoch එකෙන් තත්පර 10කට පසු: " + epochPlusTenSeconds);
// Instant එකකට තත්පර, මිනිත්තු වගේ එකතු කිරීම
Instant later = now.plusSeconds(3600); // පැයක් එකතු කිරීම
System.out.println("පැයකට පසු Instant: " + later);
// Instant දෙකක් අතර කාල පරාසය (Duration) ගණනය කිරීම
Duration duration = Duration.between(epochPlusTenSeconds, now);
System.out.println("අවස්ථා දෙක අතර කාලය (තත්පර): " + duration.getSeconds());
// milliseconds ලබා ගැනීම
long milli = now.toEpochMilli();
System.out.println("Epoch milliseconds: " + milli);
}
}
Instant එකක් භාවිතයෙන් Global events වල timestamps manage කරන එක ගොඩක් පහසු වෙනවා. Time zone ගැටළු ගැන කරදර වෙන්න ඕන නැහැ, මොකද මේක හැම විටම UTC.
java.util.Date එකෙන් java.time එකට Convert කරමු
ඔයාගේ පැරණි project වල තවමත් java.util.Date objects තියෙන්න පුළුවන්. ඒත් කරදර වෙන්න එපා! අලුත් API එකට migrate වෙන්න පුළුවන් conversions තියෙනවා.
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
public class ConversionExample {
public static void main(String[] args) {
// පැරණි java.util.Date object එකක්
Date oldDate = new Date(); // මේක දැනට UTC එකේ Current time එකට අනුරූපයි
System.out.println("පැරණි Date object එක: " + oldDate);
// Date එක Instant එකකට convert කිරීම
Instant instantFromOldDate = oldDate.toInstant();
System.out.println("Instant එකට convert කළා: " + instantFromOldDate);
// Instant එක LocalDate එකකට convert කිරීම (System Default Time Zone එක භාවිතයෙන්)
LocalDate localDateFromInstant = instantFromOldDate.atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println("LocalDate එකට convert කළා (Default Time Zone): " + localDateFromInstant);
// අලුත් java.time object එකක් නැවත Date එකකට convert කිරීම (අවශ්ය නම්)
// මේක කරන්න පුළුවන් Instant එකක් හරහා පමණයි.
Instant newInstant = Instant.now();
Date newDate = Date.from(newInstant);
System.out.println("අලුත් Instant එක Date එකකට convert කළා: " + newDate);
}
}
Date.toInstant() සහ Date.from(Instant) වගේ methods පාවිච්චි කරලා පහසුවෙන් conversion කරන්න පුළුවන්. මතක තියාගන්න, Date එකක time zone information නැති නිසා LocalDate එකකට convert කරනකොට ZoneId එකක් අත්යවශ්යයි.
අවසාන වශයෙන්
Java 8 සමගින් හඳුන්වා දුන් java.time API එක, Java වල Date and Time කළමනාකරණය කරන විදිහ මුළුමනින්ම වෙනස් කළා. LocalDate සහ Instant කියන්නේ මේ API එකේ ඉතාම වැදගත් කොටස් දෙකක්. LocalDate මගින් දින පමණක් කළමනාකරණය කරන්නත්, Instant මගින් කාල රේඛාවක නිශ්චිත මොහොතක් නිරූපණය කරන්නත් පුළුවන්. මේවා භාවිතයෙන් අපේ code එක වඩාත් කියවිය හැකි, නඩත්තු කළ හැකි සහ දෝෂ රහිත එකක් බවට පත් වෙනවා.
ඉතින්, අද ඉඳන් ඔයාගේ project වලට අලුත් java.time API එක පාවිච්චි කරන්න පටන් ගන්න! ඒක java.util.Date වලට වඩා ගොඩක් පහසුයි, ආරක්ෂිතයි. මේ ගැන ඔයාට තියෙන අත්දැකීම්, ප්රශ්න පහලින් comment කරන්න. අපි හැමෝටම මේ අලුත් API එක ගැන ඉගෙන ගන්න උදව් වෙමු!