DatePicker & TimePicker in Compose: Material3 Date/Time Selection

Published: (March 1, 2026 at 08:19 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

DatePickerDialog & State Management

The DatePickerDialog composable paired with rememberDatePickerState() provides a controlled approach to date selection:

var showDatePicker by remember { mutableStateOf(false) }
val datePickerState = rememberDatePickerState()

if (showDatePicker) {
    DatePickerDialog(
        onDismissRequest = { showDatePicker = false },
        confirmButton = {
            TextButton(onClick = {
                val selectedDate = datePickerState.selectedDateMillis
                showDatePicker = false
            }) {
                Text("OK")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }
}

Button(onClick = { showDatePicker = true }) {
    Text("Select Date")
}

SelectableDates for Range Restriction

Control which dates are selectable using the SelectableDates interface:

class DateRangeValidator(
    private val minDateMillis: Long,
    private val maxDateMillis: Long
) : SelectableDates {
    override fun isSelectableDate(utcTimeMillis: Long): Boolean {
        return utcTimeMillis >= minDateMillis && utcTimeMillis = 2024 && year  Unit,
    }
}

Example: Custom DatePickerField

Below is an example of a reusable composable that integrates a DatePickerDialog with an OutlinedTextField:

@Composable
fun DatePickerField(
    value: LocalDateTime,
    onValueChange: (LocalDateTime) -> Unit,
    label: String,
    modifier: Modifier = Modifier
) {
    var showPicker by remember { mutableStateOf(false) }
    val datePickerState = rememberDatePickerState(
        initialSelectedDateMillis = value.toMillis()
    )

    OutlinedTextField(
        value = value.format(DateTimeFormatter.ofPattern("MMM dd, yyyy")),
        onValueChange = {},
        label = { Text(label) },
        readOnly = true,
        trailingIcon = {
            IconButton(onClick = { showPicker = true }) {
                Icon(Icons.Default.DateRange, contentDescription = null)
            }
        },
        modifier = modifier
    )

    if (showPicker) {
        DatePickerDialog(
            onDismissRequest = { showPicker = false },
            confirmButton = {
                TextButton(onClick = {
                    datePickerState.selectedDateMillis?.let { mills ->
                        onValueChange(
                            LocalDateTime.ofInstant(
                                Instant.ofEpochMilli(mills),
                                ZoneId.systemDefault()
                            )
                        )
                    }
                    showPicker = false
                }) {
                    Text("OK")
                }
            }
        ) {
            DatePicker(state = datePickerState)
        }
    }
}

Best Practices

  • State Management: Always use rememberDatePickerState() to preserve state across recompositions.
  • Validation: Implement SelectableDates for business‑logic constraints.
  • User Feedback: Show the selected date/time in the UI immediately.
  • Accessibility: Ensure picker fields have proper labels and content descriptions.
  • Timezone Awareness: Be explicit about timezone handling when converting timestamps.

Material3 date/time pickers provide a modern, Material Design‑compliant experience that your users expect.

8 Android App Templates → https://myougatheax.gumroad.com/

0 views
Back to Blog

Related posts

Read more »