A modern, beautiful, and self-contained Lunar and Gregorian date picker dialog library for Android Jetpack Compose, built in accordance with Material 3 design guidelines.
- Double Calendar Support: Seamlessly select dates on both Gregorian (Solar) and Chinese Lunar calendars.
- Material 3 Design: Features smooth transitions, visual feedback cards, a 3-column year picker, and manual text-input mode.
- Self-Contained Components: Exposes both the low-level
LunarDatePickerand a high-levelLunarDatePickerDialogwrapper. - Localizations: Supports English (
en), Simplified Chinese (zh-CN), and Traditional Chinese (zh-TW/zh-HK). - Open Source Ready: Packageable as a standard Android Library
.aardependency.
Beautiful Material 3 Lunar DatePicker in Action
In your root settings.gradle.kts, ensure you have mavenCentral() in the repositories block:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}Add the library dependency to your module's build.gradle.kts:
dependencies {
implementation("io.github.gracethings:lunar-datepicker-compose:1.0.0") // Replace with actual published version / jitpack dependency
// Built on: cn.6tail:lunar:1.7.7
implementation("cn.6tail:lunar:1.7.7")
}You can easily show the Lunar Date Picker Dialog with a single-line composable call.
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.*
import io.github.gracethings.lunardatepicker.LunarDatePickerDialog
import java.time.Instant
import java.time.LocalDate
import java.time.ZoneOffset
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DatePickerExample() {
var showDialog by remember { mutableStateOf(false) }
var selectedDate by remember { mutableStateOf(LocalDate.now()) }
val datePickerState = rememberDatePickerState(
initialSelectedDateMillis = selectedDate.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli()
)
if (showDialog) {
LunarDatePickerDialog(
state = datePickerState,
onConfirm = {
datePickerState.selectedDateMillis?.let { millis ->
selectedDate = Instant.ofEpochMilli(millis)
.atZone(ZoneOffset.UTC)
.toLocalDate()
}
showDialog = false
},
onDismiss = {
showDialog = false
}
)
}
}The library provides LunarUtils to format and retrieve Lunar descriptions easily:
import io.github.gracethings.lunardatepicker.LunarUtils
import java.time.LocalDate
val date = LocalDate.of(2026, 10, 1)
// Returns "十月初一"
val desc = LunarUtils.getLunarDescription(date)
// Returns "十月"
val monthDesc = LunarUtils.getLunarMonth(date)
// Returns "初一"
val dayDesc = LunarUtils.getLunarDay(date)本项目的中文文档已移动至独立的 README.zh-CN.md。请点击链接查看完整的安装和使用指南。
Apache License 2.0