Skip to content

amirroid/JalaliDate

Repository files navigation

JalaliDate

Maven Central Android iOS Desktop JS Wasm

📆 JalaliDate is a Kotlin Multiplatform library for handling Persian (Jalali) dates, with support for formatting, parsing, and calendar conversions.


Features

  • Supports Kotlin Multiplatform (android, jvm, ios, js, wasmJs)
  • Accurate conversion between Jalali and Gregorian calendars
  • Two built-in calendar conversion algorithms
  • Powerful and flexible formatting and parsing system
  • Inspired by SimpleDateFormat but tailored for Jalali date logic

📦 Installation

// build.gradle.kts

sourceSets {
    val commonMain by getting {
        dependencies {
            implementation("io.github.amirroid:jalalidate:x.y.z")
        }
    }
}

🔁 Conversion Algorithms

This library includes two built-in algorithms for converting between Jalali and Gregorian calendars:

Algorithm Name Description
BirashkAlgorithm Based on the astronomical method by Dr. Ahmad Birashk — accurate and reliable
KhayyamAlgorithm Based on Khayyam–Jalali calendar rules — lightweight and approximate (used as the default)

You can change the default algorithm globally:

JalaliDateGlobalConfiguration.convertAlgorithm = BirashkAlgorithm

Or specify per-instance:

val date =
    JalaliDateTime(jalaliYear = 1402, jalaliMonth = 5, jalaliDay = 9, algorithm = BirashkAlgorithm)

🛠️ Formatting

Format any JalaliDateTime instance using pattern strings:

val date = JalaliDateTime(1402, 5, 9, 14, 3, 7)
val formatted = date.format {
    byUnicodePattern("yyyy/MM/dd HH:mm:ss")
}
println(formatted) // 1402/05/09 14:03:07

You can also use manual formatting:

val formatted = date.format {
    year()
    chars("/")
    month()
    chars("/")
    day()
}

⏱️ Parsing

Parse back a string into a JalaliDateTime:

val formatter = JalaliDateTime.Format { byUnicodePattern("yyyy-MM-dd HH:mm:ss") }
// Or
val formatter = JalaliDateTimeFormatter().byUnicodePattern("yyyy MMM dd")
val date = formatter.parse("1402/05/09")
println(date.jalaliYear) // 1402

Any missing field (like time) will default to current system time.


🧾 Pattern Reference

Symbol Description Example (value)
yyyy Full year 1402
yy Last two digits 02
MMMM Full month name مرداد / Mordad
MMM Short month name مرد / Mor
MM 2-digit month 05
M 1 or 2-digit month 5
EEEE Full weekday name شنبه / Saturday
EEE Short weekday name ش / Sat
E Weekday number 1
dd 2-digit day 09
d 1 or 2-digit day 9
HH Hour (24h, 2-digit) 14
H Hour (24h) 14
mm Minutes (2-digit) 03
m Minutes 3
ss Seconds (2-digit) 07
s Seconds 7

You can also combine static characters using chars(...):

val formatter = JalaliDateTimeFormatter()
    .year()
    .chars(" year - ")
    .dayOneDigit()
    .chars(" - ")
    .monthFullName()

Output:

1402 year - مرداد - 9

Note:
You can change the locale in two ways:

  • Globally (the default locale is Persian):
  JalaliDateGlobalConfiguration.formatterLocale = Locale.ENGLISH
  • Locally when formatting a date:
  date.format {
      applyLocale(Locale.ENGLISH)
      byUnicodePattern("MMMM yyyy")
  }

📚 Examples

Format with month name
val date = JalaliDateTime(1402, 5, 9)
val formatted = date.format {
    byUnicodePattern("yyyy dd MMMM")
}
// Output: 1402 مرداد 09

Parse with short month name
val input = "1402 مرد 09"
val formatter = JalaliDateTimeFormatter().byUnicodePattern("yyyy dd MMM")
val date = formatter.parse(input)
println(date.jalaliMonth) // 5

Using plus and minus operators with DateTimeInterval
val date = JalaliDateTime(1402, 5, 10, 12, 30, 15)
date + 5.days - 2.months // JalaliDateTime with Jalali date 1402/03/15 and time 12:30:15
date - 1.years + 10.days // JalaliDateTime with Jalali date 1401/05/20 and time 12:30:15

Using copyGregorian and copyJalali
JalaliDateTime(1402, 5, 10, 14, 45, 30).copyGregorian(year = 2023, month = 8, day = 1)
// Returns JalaliDateTime corresponding to Gregorian 2023/08/01

JalaliDateTime(1402, 5, 10, 14, 45, 30).copyJalali(year = 1403, month = 6, day = 20)
// JalaliDateTime(year=1403, month=6, day=20, hour=14, minute=45, second=30)

Main properties of JalaliDateTime
val date = JalaliDateTime(1402, 7, 15, 10, 20, 30)

date.gregorianYear // 2023
date.gregorianMonth // 10
date.gregorianDay // 7

date.jalaliYear // 1402
date.jalaliMonth // 7
date.jalaliDay // 15

date.algorithm::class.simpleName // "KhayyamAlgorithm" or "BirashkAlgorithm"

date.hour // 10
date.minute // 20
date.second // 30

date.weekOfYear // 29
date.isJalaliLeapYear // false
date.isGregorianLeapYear // false

date.monthLength // 30
date.monthName.english // "Mehr"
date.monthName.persian // "مهر"

date.dayOfWeek() // DayOfWeek.SATURDAY
date.dayOfWeek(weekStartDay = DayOfWeek.SUNDAY) // DayOfWeek.SATURDAY
date.dayOfWeekNumber() // 1 (if week starts on Saturday)

📜 License

MIT


For any suggestions or issues, feel free to open an Issue or contribute via PR.

About

A Kotlin Multiplatform library for Jalali (Persian) date handling, conversion, formatting and parsing.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages