SkillAgentSearch skills...

ComposeDatePicker

Elegant and fully-localized Persian Date Picker for Jetpack Compose — simple, flexible, and Farsi-friendly.

Install / Use

/learn @MohammadSadeghMehrafzoon/ComposeDatePicker

README

Compose DatePicker Persian

📆 Compose DatePicker Persian Library

Compose DatePicker BottomSheet is a powerful, flexible, and beautifully designed component for selecting Persian (Jalali) dates. Built on Jetpack Compose, it provides a smooth and professional experience for date selection in Persian apps.

✨ Features

  • ✅ Full Persian calendar support, fully compatible with Jetpack Compose
  • 🌐 Complete Persian language support (days, months, numbers)
  • 📅 Date output in both Persian (Jalali) and Gregorian formats
  • 🖋️ Custom Persian fonts with multiple weights
  • ⚙️ Optimized architecture, ready to use in Compose-based projects
  • 📆 Support for selecting only month and year without requiring a day selection (ideal for use cases where day selection is unnecessary)
  • 🎨 Fully customizable UI: colors, fonts, sizes, and layout
  • 📅 Ability to provide an initial default date to be pre-selected when opening the Persian date picker, useful for cases where the user has previously selected a date and now needs to edit it.
  • 📅 Support for configurable minimum and maximum year limits, allowing precise control over the selectable year range (with sensible defaults when not explicitly defined)

🛠️ Library Setup

Step 1: Add JitPack to settings.gradle.kts

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}

Step 2: Adding the Dependency

dependencies {
    implementation("com.github.MohammadSadeghMehrafzoon:ComposeDatePicker:V1.1.4")
}

💻 Sample Code

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DatePickerModalBottomSheet() {
    val datePickerController = rememberDialogDatePicker()
    val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
    val coroutine = rememberCoroutineScope()

    var persianFullDate by remember { mutableStateOf("") }
    var gregorianDate by remember { mutableStateOf("") }
    var persianMonth by remember { mutableStateOf("") }
    var timestamp by remember { mutableStateOf("") }
    var fullDate by remember { mutableStateOf("") }
    var persianMonthNameAndPersianYear by remember { mutableStateOf("") }
    var getMiladiFullDate by remember { mutableStateOf("") }

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text("با کلیک بر روی دکمه زیر تاریخ مورد نظر خود را انتخاب کنید")
        Spacer(Modifier.height(10.dp))
        Button(
            onClick = {
                coroutine.launch { bottomSheetState.show() }
            },
            colors = ButtonDefaults.buttonColors(containerColor = Color.Unspecified),
            shape = RoundedCornerShape(10.dp),
        ) {
            Text(
                text = "انتخاب تاریخ",
                textAlign = TextAlign.Center,
            )
        }
        Spacer(Modifier.height(20.dp))
        Text(persianFullDate)
        Text(gregorianDate)
        Text(persianMonth)
        Text(fullDate)
        Text(persianMonthNameAndPersianYear)
        Text(getMiladiFullDate)
        if (timestamp.isNotEmpty()){
            Text("timestamp $timestamp")
        }

    }


    if (bottomSheetState.isVisible) {
        DatePickerModalBottomSheet(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight(),
            onSubmitClick = {
                persianFullDate = datePickerController.getPersianFullDate()
                gregorianDate = datePickerController.getGregorianDate().toString()
                persianMonth = datePickerController.getPersianMonth().toString()
                timestamp = datePickerController.getTimestamp().toString()
                fullDate = datePickerController.getFullDate()
                persianMonthNameAndPersianYear = datePickerController.getPersianMonthNameAndPersianYear()
                getMiladiFullDate = datePickerController.getMiladiFullDate()
            },
            sheetState = bottomSheetState,
            controller = datePickerController,
            onDismissRequest = {
                coroutine.launch { bottomSheetState.hide() }
            },
            font = RegularFont,
            textButtonStyle = TextStyle(fontFamily = FontFamily(Font(BoldFont))),
            //minYear = MinYear.On(1400),
            //maxYear = MaxYear.On(1407),
            //useInitialDate = true,
            //initialDate = Triple(1404,6,27)
            //datePickerWithoutDay = true
            //titleStyle = TextStyle(fontFamily = FontFamily(Font(MediumFont))),
            //titleBottomSheet = "تاریخ مورد نظر خود را انتخاب کنید",
            //titleModifier = Modifier.padding(start = 10.dp)
        )
    }
}

📅 Features of Compose DatePicker Persian

📅 Persian Date Functions

| 🔧 Function | 📝 Description | |-------------------------------------|---------------------------------------------------------------------------------| | getPersianYear(): Int | Returns the Persian year (e.g., 1403) | | getPersianMonth(): Int | Returns the Persian month number from 1 to 12 (e.g., 3 for Khordad) | | getPersianDay(): Int | Returns the Persian day of the month from 1 to 31 (e.g., 19) | | getPersianMonthName(): String | Returns the Persian month name (e.g., "خرداد") | | getPersianDayOfWeekName(): String | Returns the Persian day of the week name (e.g., "چهارشنبه") |

🌍 Gregorian Date Functions

| 🔧 Function | 📝 Description | |-------------------------------------|---------------------------------------------------------------------------------| | getGregorianYear(): Int | Returns the Gregorian year (e.g., 2025) | | getGregorianMonth(): Int | Returns the Gregorian month number from 1 to 12 (e.g., 6 for June) | | getGregorianDay(): Int | Returns the Gregorian day of the month (e.g., 11) | | getGregorianDate(): Date | Returns the full Gregorian date as a Date object |

🧠 General Date Information

| 🔧 Function | 📝 Description | |-------------------------|---------------------------------------------------------------------------------| | getDayOfWeek(): Int | Returns the day of the week number (the meaning of the number may vary depending on the implementation) |

🗓️ Formatted Date Strings

| 🔧 Function | 📝 Description | |--------------------------------------------------|--------------------------------------------------------------------------------------------------| | getFullDate(): String | Returns the full Persian date in yyyy/MM/dd format (e.g., "1403/03/19") | | getPersianMonthNameAndPersianYear(): String | Returns a combination of Persian month name and year (e.g., "خرداد 1403") | | getMiladiFullDate(): String | Returns the full Gregorian date in yyyy/MM/dd format (e.g., "2025/06/11") | | getPersianFullDate(): String | Returns the detailed Persian date (e.g., "چهارشنبه 19 خرداد 1403") |

⏱️ Timestamp Utility

| 🔧 Function | 📝 Description | |-------------------------|--------------------------------------------------------------------------------------------------| | getTimestamp(): Long | Returns the Unix timestamp (number of milliseconds since 1970-01-01) for the current date |

🔤 Persian Fonts

| Font Variable | Font Weight | Usage Description | |-------------------------|-------------------|-------------------------------------------------------------------------| | BoldFont | Bold (700) | Suitable for titles and highly emphasized sections | | MediumFont | Medium (500) | Ideal for buttons or semi-bold texts | | RegularFont | Regular (400) | Used for general body text and main content | | LightFont | Light (300) | Suitable for secondary or descriptive texts | | ThinFont | Thin (200) | Suitable for very light and delicate text | | HairlineFont | Hairline (100) | The thinnest font weight, ideal for decorative or neutral text |

⚙️ Configurable Parameters of ComposeDatePickerBottomSheet

| Parameter | Type / Description | |----------------------|------------------------------------------------------------------------------------------------------| | modifier | Modifier — Used to configure the overall layout of the Bottom Sheet. | | titleModifier | Modifier — Modifier for the top title inside the Bottom Sheet.

Related Skills

View on GitHub
GitHub Stars11
CategoryDevelopment
Updated2mo ago
Forks0

Languages

Kotlin

Security Score

80/100

Audited on Feb 2, 2026

No findings