LocalDate, LocalTime at LocalDateTime: ano ito, paggawa sa petsa

May-akda: IT Sectr Nai-publish: 2026-07-13 Oras ng pagbabasa: 12 min

LocalDate, LocalTime at LocalDateTime — pangunahing mga klase ng java.time package na nagbibigay ng paggawa sa petsa at oras nang walang koneksyon sa time zone. Ayon sa dokumentasyon ng Oracle (Java 17, 2024), ang mga uri na ito ay dinisenyo bilang immutable at thread-safe, na ginagawang ligtas ang mga ito para sa multi-threaded na application. Naging available ang mga ito sa Android sa pamamagitan ng desugaring simula API 26, at para sa mas lumang bersyon sa pamamagitan ng library na ThreeTenABP.

Mga pangunahing punto

  • LocalDate — immutable na klase para sa representasyon ng petsa (taon, buwan, araw) nang walang oras at time zone.
  • LocalTime — immutable na klase para sa representasyon ng oras (oras, minuto, segundo, nanosegundo) nang walang petsa at time zone.
  • LocalDateTime — kombinasyon ng LocalDate at LocalTime, nag-iimbak ng parehong petsa at oras nang walang koneksyon sa zone.
  • Lahat ng tatlong klase ay sumusuporta sa mga operasyong aritmetika — pagdaragdag at pagbabawas ng mga araw, buwan, oras sa pamamagitan ng plus at minus na mga metodo.
  • Sa Android ang mga uri na ito ay available sa pamamagitan ng desugaring (API 26+) o library na ThreeTenABP (API < 26).

Ano ang LocalDate, LocalTime at LocalDateTime?

LocalDate — klase na kumakatawan sa petsa sa format na taon-buwan-araw nang walang impormasyon tungkol sa oras at time zone. Ginagamit ito para sa pag-iimbak ng data tulad ng petsa ng kapanganakan, petsa ng kaganapan o petsa ng pag-expire.

Ang LocalDate ay nag-iimbak ng taon sa saklaw mula -999999999 hanggang +999999999, buwan mula 1 hanggang 12 at araw ng buwan na isinasaalang-alang ang mga leap year. Ang klase ay ganap na immutable — bawat operasyon ay nagbabalik ng bagong object.

LocalTime ay kumakatawan sa oras ng araw: oras, minuto, segundo at nanosegundo. Pinakamataas na presisyon — hanggang nanosegundo. Ang LocalTime ay hindi naglalaman ng impormasyon tungkol sa petsa at time zone, na ginagawang maginhawa para sa pag-iimbak ng oras ng pagbubukas ng tindahan o tagal ng proseso.

LocalDateTime ay pinagsasama ang LocalDate at LocalTime sa isang object. Ito ang pinakamadalas na ginagamit na uri kapag kailangang mag-imbak ng parehong petsa at oras, ngunit hindi kinakailangan ang koneksyon sa time zone. Halimbawa, petsa at oras ng konsiyerto sa lokal na format.

Ayon sa Oracle Java Documentation (2024), lahat ng tatlong klase ay dinisenyo batay sa mga ideya mula sa library na Joda-Time, ngunit may pinahusay na arkitektura at buong integrasyon sa standard library.

Paano nakaayos ang java.time package?

Ang java.time package ay lumitaw sa Java 8 bilang kapalit ng mga luma nang klase na Date, Calendar at SimpleDateFormat. Ang arkitektura nito ay binuo sa mga prinsipyo ng immutable object at fluent-interface.

Ang pangunahing tampok — lahat ng pangunahing klase ay value-based. Nangangahulugan ito na ang kanilang mga instance ay inihahambing ayon sa halaga, hindi sa referens, at hindi sila maaaring mamana. Para sa paghahambing ng dalawang object ay ginagamit ang metodo na equals, hindi ang operator na ==.

Ang package ay nahahati sa ilang kategorya. Mga uri na walang time zone — LocalDate, LocalTime, LocalDateTime — ay ginagamit para sa lokal na petsa at oras. Mga uri na may time zone — ZonedDateTime, OffsetDateTime, OffsetTime — ay nagdaragdag ng impormasyon tungkol sa offset o zone. Mga agarang uri — Instant — ay kumakatawan sa punto sa timeline sa UTC.

Ang paghahati na ito ay lumulutas sa problemang katangian ng lumang API: hindi alam ng programmer kung ang Date object ay naglalaman ng impormasyon tungkol sa time zone o hindi. Sa java.time bawat uri ay nagdedeklara nang malinaw ng semantika nito.

LocalDate: paggawa sa petsa

Ang klase na LocalDate ay nagbibigay ng maraming metodo para sa paggawa, pagbasa at pagbabago ng petsa. Ang kasalukuyang petsa ay maaaring makuha sa pamamagitan ng static na metodo na now(). Ang isang tiyak na petsa — sa pamamagitan ng metodo na of(int year, int month, int dayOfMonth).

Para sa pagbasa ng mga component ng petsa ay ginagamit ang mga getter: getYear(), getMonthValue(), getDayOfMonth(), getDayOfWeek(), getDayOfYear(). Ang metodo na getMonth() ay nagbabalik ng enum Month, at getDayOfWeek() — enum DayOfWeek.

Sinusuportahan ng LocalDate ang pagsusuri ng petsa. Ang mga metodo na isBefore(), isAfter() at isEqual() ay nagpapahintulot ng paghahambing ng mga petsa. Ang metodo na isLeapYear() ay sumusuri kung ang taon ay leap year. Ang metodo na lengthOfMonth() ay nagbabalik ng bilang ng mga araw sa buwan, at lengthOfYear() — sa taon.

Para sa pagbabago ay ginagamit ang mga metodo na withYear(), withMonth(), withDayOfMonth(), na nagbabalik ng bagong object na may binagong component. Ang mga metodo na plusDays(), minusMonths() at katulad ay nagsasagawa ng aritmetika ng petsa.

LocalTime: paggawa sa oras

LocalTime ay kumakatawan sa oras ng araw na may presisyon hanggang nanosegundo. Standard na format — ISO-8601 (HH:mm:ss.nnnnnnnnn). Pinakamababang halaga — 00:00, pinakamataas — 23:59:59.999999999.

Maaaring gumawa ng LocalTime object sa pamamagitan ng now() para sa kasalukuyang oras, of(int hour, int minute), of(int hour, int minute, int second) o of(int hour, int minute, int second, int nanoOfSecond). Ang metodo na parse(CharSequence text) ay nagpa-parse ng string sa ISO-8601 na format.

Ang mga getter ay kinabibilangan ng getHour(), getMinute(), getSecond(), getNano(). Ang metodo na toSecondOfDay() ay nagbabalik ng bilang ng mga segundo mula simula ng araw, at toNanoOfDay() — nanosegundo. Ito ay maginhawa para sa pagkalkula ng tagal sa loob ng isang araw.

Sinusuportahan ng LocalTime ang parehong operasyon ng paghahambing at pagbabago tulad ng LocalDate: plusHours(), minusMinutes(), withHour(), withMinute(). Ang mga metodo na isBefore() at isAfter() ay gumagana na isinasaalang-alang ang cyclical na kalikasan ng oras sa loob ng isang araw.

LocalDateTime: kombinasyon ng petsa at oras

LocalDateTime ay pinagsasama ang mga kakayahan ng LocalDate at LocalTime sa isang klase. Nag-iimbak ng parehong petsa at oras, ngunit walang time zone. Ito ang pinaka-flexible na lokal na uri, ngunit nangangailangan ng pag-iingat kapag ginagamit sa mga distributed system.

Maaaring gumawa ng LocalDateTime sa pamamagitan ng static na metodo na now(), of(LocalDate date, LocalTime time), of(int year, Month month, int dayOfMonth, int hour, int minute) at kanilang mga overload. Maaari ring pagsamahin ang LocalDate at LocalTime sa pamamagitan ng metodo na atTime().

Ang LocalDateTime ay nagbibigay ng access sa lahat ng field ng petsa at oras sa pamamagitan ng kaukulang mga getter: toLocalDate() at toLocalTime() ay nagbabalik ng mga hiwalay na component. Ang metodo na truncatedTo(TemporalUnit unit) ay nagpapahintulot ng pag-round ng oras sa isang naibigay na presisyon — halimbawa, hanggang minuto.

Para sa conversion sa time zone ay ginagamit ang metodo na atZone(ZoneId zone), na nagbabalik ng ZonedDateTime. Ito ang tanging paraan upang magdagdag ng time zone sa LocalDateTime.

Paano gumawa ng mga object ng petsa at oras?

Lahat ng tatlong klase ay gumagamit ng pare-parehong pattern ng paggawa sa pamamagitan ng static na factory method. Ang mga constructor ng klase ay idineklara bilang private — hindi maaaring gumawa ng object nang direkta sa pamamagitan ng new.

Mga pangunahing paraan ng paggawa:

  • now() — kasalukuyang petsa/oras mula sa system clock
  • of(...) — mula sa mga component (taon, buwan, araw, atbp.)
  • parse(String) — mula sa string sa ISO-8601 na format
  • from(TemporalAccessor) — mula sa ibang temporal na object

Ang metodo na of ay may maraming overload. Para sa LocalDate kailangan ang taon, buwan at araw. Para sa LocalTime — oras at minuto (opsyonal segundo at nanosegundo). Para sa LocalDateTime — taon, buwan, araw, oras, minuto. Ang buwan ay maaaring ibigay bilang int (1-12) o bilang enum Month.

kotlin
val today = LocalDate.now()
val specificDate = LocalDate.of(2026, Month.JULY, 21)
val parsedDate = LocalDate.parse("2026-07-21")

val currentTime = LocalTime.now()
val lunchTime = LocalTime.of(13, 30, 0)
val parsedTime = LocalTime.parse("13:30:00")

val now = LocalDateTime.now()
val meeting = LocalDateTime.of(2026, 7, 21, 15, 0)

Conversion sa pagitan ng mga uri

Ang mga klase ng java.time ay dinisenyo para sa madaling conversion sa isa’t isa. LocalDate ay maaaring i-convert sa LocalDateTime sa pamamagitan ng metodo na atTime(LocalTime) o atStartOfDay(). LocalTime — sa pamamagitan ng atDate(LocalDate).

LocalDateTime ay maaaring i-convert pabalik sa LocalDate sa pamamagitan ng toLocalDate() at sa LocalTime sa pamamagitan ng toLocalTime(). Para sa conversion sa ZonedDateTime ay ginagamit ang metodo na atZone(ZoneId).

Ang conversion sa java.util.Date (para sa compatibility sa lumang code) ay nangangailangan ng intermediate na hakbang sa pamamagitan ng Instant at time zone. Ayon sa Baeldung (2024), ang operasyong ito ay isinasagawa sa pamamagitan ng Date.from(instant).

kotlin
val date = LocalDate.of(2026, 7, 21)
val dateTime = date.atTime(LocalTime.of(10, 30))

val time = LocalTime.of(14, 0)
val dateTimeFromTime = time.atDate(date)

val extractedDate = dateTime.toLocalDate()
val extractedTime = dateTime.toLocalTime()

val zoned = dateTime.atZone(ZoneId.of("Europe/Moscow"))

Pag-format at pag-parse

Para sa pag-format at pag-parse ay ginagamit ang klase na DateTimeFormatter. Nagbibigay ito ng mga paunang natukoy na format sa pamamagitan ng mga constant (ISO_LOCAL_DATE, ISO_LOCAL_TIME, ISO_LOCAL_DATE_TIME) at kakayahang lumikha ng sariling mga format sa pamamagitan ng mga pattern.

Ang mga pattern ng pag-format ay gumagamit ng mga simbolo: yyyy — taon, MM — buwan (dalawang digit), dd — araw, HH — oras (0-23), mm — minuto, ss — segundo. Ang metodo na format() ay tinatawag sa object ng petsa-oras o sa pamamagitan ng DateTimeFormatter.

Sinusuportahan din ng DateTimeFormatter ang lokalisasyon sa pamamagitan ng static na metodo na ofLocalizedDate(FormatStyle), ofLocalizedTime(FormatStyle) at ofLocalizedDateTime(FormatStyle). Ang mga istilong available ay SHORT, MEDIUM, LONG at FULL.

kotlin
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
val formatted = LocalDateTime.now().format(formatter)

val parsed = LocalDate.parse(
    "21.07.2026",
    DateTimeFormatter.ofPattern("dd.MM.yyyy")
)

Paghahambing ng mga object ng petsa-oras

Lahat ng tatlong klase ay nag-iimplementa ng interface na Comparable, na nagpapahintulot ng natural na paghahambing. Ang metodo na compareTo() ay nagbabalik ng negatibong numero, zero o positibo depende sa pagkakasunod-sunod. Ang mga metodo na isBefore(), isAfter() at isEqual() ay nagbabalik ng boolean.

Para sa LocalDate ang paghahambing ay ginagawa nang kronolohikal — ang mas naunang petsa ay mas maliit. Para sa LocalTime — ayon sa oras ng araw. Para sa LocalDateTime — una ayon sa petsa, pagkatapos ayon sa oras. Lahat ng paghahambing ay wastong isinasaalang-alang ang mga leap year at bilang ng mga araw sa mga buwan.

Mahalagang pagkakaiba mula sa lumang API: ang equals() para sa LocalDate, LocalTime at LocalDateTime ay naghahambing ng mga halaga, hindi mga referens. Nangangahulugan ito na ang dalawang object na may parehong field ay magiging pantay, kahit na sila ay magkaibang instance.

kotlin
val d1 = LocalDate.of(2026, 7, 21)
val d2 = LocalDate.of(2026, 12, 25)

if (d1.isBefore(d2)) {
    Log.d("Petsa", "ang d1 ay bago ang d2")
}

val sortedDates = listOf(d2, d1).sorted()

Aritmetika ng petsa at oras

Lahat ng tatlong klase ay sumusuporta sa mga operasyong aritmetika sa pamamagitan ng mga metodo na plus at minus. Para sa LocalDate ay available ang plusDays(), plusWeeks(), plusMonths(), plusYears() at mga katulad na minus-metodo. Sinusuportahan ng LocalTime ang plusHours(), plusMinutes(), plusSeconds(), plusNanos().

Ang LocalDateTime ay nagmamana ng lahat ng operasyong aritmetika ng parehong uri. Tampok ng LocalDate: kapag nagdaragdag ng buwan, ang mga resulta ay wastong humahawak ng iba’t ibang haba ng mga buwan. Halimbawa, Enero 31 + 1 buwan = Pebrero 28 (29 sa leap year).

Para sa mas kumplikadong operasyon ay may mga klase na Period (para sa mga petsa) at Duration (para sa oras). Ang mga metodo na plus(TemporalAmount) at minus(TemporalAmount) ay tumatanggap ng mga object na ito.

kotlin
val today = LocalDate.now()
val nextWeek = today.plusDays(7)
val nextMonth = today.plusMonths(1)
val lastYear = today.minusYears(1)

val now = LocalTime.now()
val inTwoHours = now.plusHours(2)
val halfHourAgo = now.minusMinutes(30)

Mga halimbawa ng code sa Kotlin

Isaalang-alang natin ang isang praktikal na halimbawa: application para sa pagtatala ng mga work shift. Kailangang kalkulahin ang tagal ng shift at matukoy kung ito ay pumapatak sa oras ng gabi. Gumagamit kami ng LocalTime para sa oras ng simula at pagtatapos, LocalDate para sa petsa at LocalDateTime para sa pagkalkula ng mga shift na lumalampas sa hatinggabi.

kotlin
data class Shift(
    val startTime: LocalTime,
    val endTime: LocalTime,
    val date: LocalDate
) {
    fun isOvernight(): Boolean = endTime.isBefore(startTime)

    fun durationInMinutes(): Long {
        val start = LocalDateTime.of(date, startTime)
        val end = LocalDateTime.of(
            if (isOvernight()) date.plusDays(1) else date,
            endTime
        )
        return Duration.between(start, end).toMinutes()
    }
}

Pangalawang halimbawa — pagkalkula ng edad ng user. Gumagamit kami ng LocalDate para sa petsa ng kapanganakan at inihahambing ito sa kasalukuyang petsa, isinasaalang-alang ang araw at buwan ng kapanganakan.

kotlin
fun calculateAge(birthDate: LocalDate): Int {
    val today = LocalDate.now()
    val period = Period.between(birthDate, today)
    return period.years
}

Pangatlong halimbawa — paggawa sa mga notipikasyon. Ang LocalDateTime ay ginagamit para sa pag-iiskedyul ng mga paalala. Sinusuri namin kung ang naka-iskedyul na oras ay dumating na.

kotlin
data class Reminder(
    val id: Long,
    val scheduledAt: LocalDateTime
) {
    fun isDue(): Boolean =
        LocalDateTime.now().isAfter(scheduledAt)
}

Suporta sa Android: antas ng API at desugaring

Ang built-in na suporta para sa java.time ay lumitaw sa Android simula API 26 (Android 8.0 Oreo). Para sa mga device na may mas lumang bersyon ng Android kailangang gumamit ng desugaring — mekanismo na nagdaragdag ng suporta para sa mga bagong Java API sa mga naunang bersyon.

Ang desugaring sa Android Gradle Plugin ay na-configure sa pamamagitan ng compileOptions sa build.gradle. Sapat na itakda ang isCoreLibraryDesugaringEnabled = true at idagdag ang library na desugar_jdk_libs. Pagkatapos nito, ang java.time ay magiging available para sa lahat ng antas ng API simula 14.

Para sa mga proyektong hindi maaaring gumamit ng desugaring (halimbawa, legacy project sa AGP na mas mababa sa 4.0), mayroong library na ThreeTenABP — backport ng java.time. Nagbibigay ito ng parehong mga klase (LocalDate, LocalTime, LocalDateTime), ngunit sa package na org.threeten.bp.

groovy
@Suppress("UnstableApiUsage")
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

Mga karaniwang pagkakamali at kung paano maiiwasan ang mga ito

Unang karaniwang pagkakamali — paggamit ng LocalDateTime sa mga distributed system nang hindi isinasaalang-alang ang time zone. Kung ang server ay nasa Europe/Moscow at ang client ay nasa Asia/Tokyo, ang LocalDateTime ay bibigyang-kahulugan nang magkaiba. Solusyon: gumamit ng Instant o ZonedDateTime para sa pandaigdigang data.

Pangalawang pagkakamali — maling pag-parse ng mga string. Bilang default, inaasahan ng LocalDate.parse() ang format na ISO-8601 (yyyy-MM-dd). Kung ang string ay nasa ibang format, kailangang ibigay nang tahasan ang DateTimeFormatter. Dapat ding pangasiwaan ang DateTimeParseException upang hindi mag-crash ang application sa hindi wastong input.

Pangatlong pagkakamali — pagbalewala sa kaligtasan ng null. Ang LocalDate, LocalTime at LocalDateTime ay mga object na maaaring maging null. Sa Kotlin inirerekomenda ang paggamit ng nullable types na may tahasang pagsusuri o Elvis operator. Sa Java — suriin ang null bago tumawag ng mga metodo.

Pang-apat na pagkakamali — pagkalito sa pagitan ng LocalDateTime at ZonedDateTime. Ang LocalDateTime ay walang anumang impormasyon tungkol sa time zone. Kung kailangang magpadala ng absolute time moment — gumamit ng zonal types. Kung sapat na ang lokal na oras — lokal na uri.

Mga madalas itanong

Ano ang pagkakaiba ng LocalDate at Date sa Java?

Ang Date ay nag-iimbak ng bilang ng mga millisecond mula 1970-01-01 UTC, habang ang LocalDate ay nag-iimbak ng taon, buwan at araw nang walang koneksyon sa time zone. Ang Date ay mutable at hindi thread-safe, ang LocalDate — immutable at thread-safe. Ang Date ay luma na simula Java 8.

Maaari bang gamitin ang LocalDateTime sa database?

Oo, ang LocalDateTime ay mahusay na nami-map sa SQL type na TIMESTAMP WITHOUT TIME ZONE. Sinusuportahan ito ng JPA at Room sa pamamagitan ng TypeConverter. Para sa TIMESTAMP WITH TIME ZONE gamitin ang ZonedDateTime o OffsetDateTime.

Paano makukuha ang bilang ng mga araw sa pagitan ng dalawang petsa?

Gamitin ang ChronoUnit.DAYS.between(startDate, endDate). Ang metodo na ito ay nagbabalik ng long — pagkakaiba sa mga araw. Para sa mas detalyadong pagkalkula gamitin ang Period.between(), na nagbabalik ng Period na may mga taon, buwan at araw.

Ano ang gagawin kung kailangang panatilihin ang presisyon ng oras hanggang millisecond?

Sinusuportahan ng LocalTime ang presisyon hanggang nanosegundo (9 decimal places). Kung kailangan ang presisyon hanggang millisecond, gamitin ang truncateTo(ChronoUnit.MILLIS) bago mag-imbak. Pinipigilan nito ang mga problema sa pag-round sa serialization.

Bakit ang LocalDate.now() ay nagbabalik ng ibang petsa sa iba’t ibang device?

Ang metodo na now() ay gumagamit ng system clock ng device at default na time zone. Kung ang mga device ay nasa magkaibang time zone, ang petsa ay maaaring magkaiba. Para sa pare-parehong timestamp gamitin ang Instant.now(), na palaging nagbabalik ng oras sa UTC.

Buod

  • LocalDate — immutable na klase para sa petsa nang walang oras at time zone. Ginagamit para sa pag-iimbak ng mga petsa ng kapanganakan, deadline, petsa ng kaganapan.
  • LocalTime — immutable na klase para sa oras ng araw na may presisyon hanggang nanosegundo. Angkop para sa pag-iimbak ng mga oras ng pagbubukas, tagal ng proseso.
  • LocalDateTime — kombinasyon ng petsa at oras nang walang koneksyon sa zone. Pinaka-flexible na lokal na uri, ngunit hindi angkop para sa mga distributed system.
  • Lahat ng tatlong klase ay sumusuporta sa aritmetika, paghahambing, pag-format at pag-parse sa pamamagitan ng pare-parehong API batay sa DateTimeFormatter.
  • Sa Android ang java.time ay available sa pamamagitan ng built-in na suporta mula API 26 o sa pamamagitan ng desugaring para sa mas lumang bersyon.
  • Para sa pandaigdigang timestamp at data na may time zone gamitin ang ZonedDateTime o Instant sa halip ng lokal na uri.
  • Sa pag-parse ng mga string, lagi mong ibigay ang DateTimeFormatter para sa hindi standard na format at pangasiwaan ang DateTimeParseException.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din