1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-20 04:29:09 -05:00

Fix that an incorrect day would be selected in MaterialDatePicker (#1723)

This commit is contained in:
Michael 2021-12-27 08:10:30 +01:00 committed by GitHub
parent 2eee50ad81
commit 6520f8a0d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 153 additions and 217 deletions

View File

@ -14,8 +14,6 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.view.ActionMode
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Attendance
@ -27,12 +25,10 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import io.github.wulkanowy.utils.openMaterialDatePicker
import java.time.LocalDate
import javax.inject.Inject
@ -224,29 +220,15 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
(activity as? MainActivity)?.showDialogFragment(AttendanceDialog.newInstance(lesson))
}
override fun showDatePickerDialog(currentDate: LocalDate) {
val baseDate = currentDate.firstSchoolDayInSchoolYear
val rangeStart = baseDate.toTimestamp()
val rangeEnd = LocalDate.now().plusWeeks(1).toTimestamp()
val constraintsBuilder = CalendarConstraints.Builder().apply {
setValidator(SchoolDaysValidator(rangeStart, rangeEnd))
setStart(rangeStart)
setEnd(rangeEnd)
}
val datePicker = MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
if (!parentFragmentManager.isStateSaved) {
datePicker.show(parentFragmentManager, null)
override fun showDatePickerDialog(selectedDate: LocalDate) {
openMaterialDatePicker(
selected = selectedDate,
rangeStart = selectedDate.firstSchoolDayInSchoolYear,
rangeEnd = LocalDate.now().plusWeeks(1),
onDateSelected = {
presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth)
}
)
}
override fun showExcuseDialog() {

View File

@ -48,7 +48,7 @@ interface AttendanceView : BaseView {
fun showAttendanceDialog(lesson: Attendance)
fun showDatePickerDialog(currentDate: LocalDate)
fun showDatePickerDialog(selectedDate: LocalDate)
fun showExcuseDialog()

View File

@ -5,17 +5,13 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.DialogHomeworkAddBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.openMaterialDatePicker
import io.github.wulkanowy.utils.toFormattedString
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import java.time.LocalDate
import javax.inject.Inject
@ -25,6 +21,7 @@ class HomeworkAddDialog : BaseDialogFragment<DialogHomeworkAddBinding>(), Homewo
@Inject
lateinit var presenter: HomeworkAddPresenter
// todo: move it to presenter
private var date: LocalDate? = null
override fun onCreate(savedInstanceState: Bundle?) {
@ -99,27 +96,16 @@ class HomeworkAddDialog : BaseDialogFragment<DialogHomeworkAddBinding>(), Homewo
dismiss()
}
override fun showDatePickerDialog(currentDate: LocalDate) {
val rangeStart = LocalDate.now().toTimestamp()
val rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear.toTimestamp()
val constraintsBuilder = CalendarConstraints.Builder().apply {
setStart(rangeStart)
setEnd(rangeEnd)
setValidator(SchoolDaysValidator(rangeStart, rangeEnd))
}
val datePicker = MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
date = it.toLocalDateTime().toLocalDate()
override fun showDatePickerDialog(selectedDate: LocalDate) {
openMaterialDatePicker(
selected = selectedDate,
rangeStart = LocalDate.now(),
rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear,
onDateSelected = {
date = it
binding.homeworkDialogDate.editText?.setText(date!!.toFormattedString())
}
if (!parentFragmentManager.isStateSaved) {
datePicker.show(this.parentFragmentManager, null)
}
)
}
override fun onDestroyView() {

View File

@ -17,5 +17,5 @@ interface HomeworkAddView : BaseView {
fun closeDialog()
fun showDatePickerDialog(currentDate: LocalDate)
fun showDatePickerDialog(selectedDate: LocalDate)
}

View File

@ -5,8 +5,6 @@ import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.LuckyNumber
@ -14,11 +12,9 @@ import io.github.wulkanowy.databinding.FragmentLuckyNumberHistoryBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import io.github.wulkanowy.utils.openMaterialDatePicker
import java.time.LocalDate
import javax.inject.Inject
@ -111,29 +107,15 @@ class LuckyNumberHistoryFragment :
binding.luckyNumberHistoryNextButton.visibility = if (show) VISIBLE else View.INVISIBLE
}
override fun showDatePickerDialog(currentDate: LocalDate) {
val baseDate = currentDate.firstSchoolDayInSchoolYear
val rangeStart = baseDate.toTimestamp()
val rangeEnd = LocalDate.now().plusWeeks(1).toTimestamp()
val constraintsBuilder = CalendarConstraints.Builder().apply {
setValidator(SchoolDaysValidator(rangeStart, rangeEnd))
setStart(rangeStart)
setEnd(rangeEnd)
}
val datePicker = MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
if (!parentFragmentManager.isStateSaved) {
datePicker.show(parentFragmentManager, null)
override fun showDatePickerDialog(selectedDate: LocalDate) {
openMaterialDatePicker(
selected = selectedDate,
rangeStart = selectedDate.firstSchoolDayInSchoolYear,
rangeEnd = LocalDate.now().plusWeeks(1),
onDateSelected = {
presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth)
}
)
}
override fun showContent(show: Boolean) {

View File

@ -28,7 +28,7 @@ interface LuckyNumberHistoryView : BaseView {
fun showNextButton(show: Boolean)
fun showDatePickerDialog(currentDate: LocalDate)
fun showDatePickerDialog(selectedDate: LocalDate)
fun showContent(show: Boolean)

View File

@ -9,8 +9,6 @@ import android.view.View.GONE
import android.view.View.VISIBLE
import androidx.core.text.parseAsHtml
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
@ -22,13 +20,11 @@ import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.timetable.additional.AdditionalLessonsFragment
import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import io.github.wulkanowy.utils.openMaterialDatePicker
import java.time.LocalDate
import javax.inject.Inject
@ -193,29 +189,15 @@ class TimetableFragment : BaseFragment<FragmentTimetableBinding>(R.layout.fragme
(activity as? MainActivity)?.showDialogFragment(TimetableDialog.newInstance(lesson))
}
override fun showDatePickerDialog(currentDate: LocalDate) {
val baseDate = currentDate.firstSchoolDayInSchoolYear
val rangeStart = baseDate.toTimestamp()
val rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear.toTimestamp()
val constraintsBuilder = CalendarConstraints.Builder().apply {
setValidator(SchoolDaysValidator(rangeStart, rangeEnd))
setStart(rangeStart)
setEnd(rangeEnd)
}
val datePicker = MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
if (!parentFragmentManager.isStateSaved) {
datePicker.show(parentFragmentManager, null)
override fun showDatePickerDialog(selectedDate: LocalDate) {
openMaterialDatePicker(
selected = selectedDate,
rangeStart = selectedDate.firstSchoolDayInSchoolYear,
rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear,
onDateSelected = {
presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth)
}
)
}
override fun openAdditionalLessonsView() {

View File

@ -48,7 +48,7 @@ interface TimetableView : BaseView {
fun showTimetableDialog(lesson: Timetable)
fun showDatePickerDialog(currentDate: LocalDate)
fun showDatePickerDialog(selectedDate: LocalDate)
fun popView()

View File

@ -4,8 +4,6 @@ import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.TimetableAdditional
@ -15,13 +13,11 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.timetable.additional.add.AdditionalLessonAddDialog
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import io.github.wulkanowy.utils.openMaterialDatePicker
import java.time.LocalDate
import javax.inject.Inject
@ -144,29 +140,17 @@ class AdditionalLessonsFragment :
(activity as? MainActivity)?.showDialogFragment(AdditionalLessonAddDialog.newInstance())
}
override fun showDatePickerDialog(currentDate: LocalDate) {
override fun showDatePickerDialog(selectedDate: LocalDate) {
val now = LocalDate.now()
val startOfSchoolYear = now.firstSchoolDayInSchoolYear.toTimestamp()
val endOfSchoolYear = now.lastSchoolDayInSchoolYear.toTimestamp()
val constraintsBuilder = CalendarConstraints.Builder().apply {
setValidator(SchoolDaysValidator(startOfSchoolYear, endOfSchoolYear))
setStart(startOfSchoolYear)
setEnd(endOfSchoolYear)
}
val datePicker = MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
if (!parentFragmentManager.isStateSaved) {
datePicker.show(parentFragmentManager, null)
openMaterialDatePicker(
selected = selectedDate,
rangeStart = now.firstSchoolDayInSchoolYear,
rangeEnd = now.lastSchoolDayInSchoolYear,
onDateSelected = {
presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth)
}
)
}
override fun showDeleteLessonDialog(timetableAdditional: TimetableAdditional) {

View File

@ -34,7 +34,7 @@ interface AdditionalLessonsView : BaseView {
fun showNextButton(show: Boolean)
fun showDatePickerDialog(currentDate: LocalDate)
fun showDatePickerDialog(selectedDate: LocalDate)
fun showAddAdditionalLessonDialog()

View File

@ -5,19 +5,15 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.DialogAdditionalAddBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.openMaterialDatePicker
import io.github.wulkanowy.utils.toFormattedString
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import java.time.LocalDate
import java.time.LocalTime
import javax.inject.Inject
@ -128,27 +124,15 @@ class AdditionalLessonAddDialog : BaseDialogFragment<DialogAdditionalAddBinding>
}
override fun showDatePickerDialog(selectedDate: LocalDate) {
val rangeStart = LocalDate.now().toTimestamp()
val rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear.toTimestamp()
val constraintsBuilder = CalendarConstraints.Builder().apply {
setStart(rangeStart)
setEnd(rangeEnd)
setValidator(SchoolDaysValidator(rangeStart, rangeEnd))
}
val datePicker = MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(selectedDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime().toLocalDate()
presenter.onDateSelected(date)
binding.additionalLessonDialogDateEdit.setText(date.toFormattedString())
}
if (!parentFragmentManager.isStateSaved) {
datePicker.show(parentFragmentManager, null)
openMaterialDatePicker(
selected = selectedDate,
rangeStart = LocalDate.now(),
rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear,
onDateSelected = {
presenter.onDateSelected(it)
binding.additionalLessonDialogDateEdit.setText(it.toFormattedString())
}
)
}
override fun showStartTimePickerDialog(selectedTime: LocalTime) {

View File

@ -6,8 +6,6 @@ import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.CompletedLesson
@ -16,14 +14,12 @@ import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear
import io.github.wulkanowy.utils.getCompatDrawable
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import io.github.wulkanowy.utils.openMaterialDatePicker
import java.time.LocalDate
import javax.inject.Inject
@ -150,29 +146,17 @@ class CompletedLessonsFragment :
)
}
override fun showDatePickerDialog(currentDate: LocalDate) {
override fun showDatePickerDialog(selectedDate: LocalDate) {
val now = LocalDate.now()
val startOfSchoolYear = now.firstSchoolDayInSchoolYear.toTimestamp()
val endOfSchoolYear = now.lastSchoolDayInSchoolYear.toTimestamp()
val constraintsBuilder = CalendarConstraints.Builder().apply {
setValidator(SchoolDaysValidator(startOfSchoolYear, endOfSchoolYear))
setStart(startOfSchoolYear)
setEnd(endOfSchoolYear)
}
val datePicker = MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
if (!parentFragmentManager.isStateSaved) {
datePicker.show(parentFragmentManager, null)
openMaterialDatePicker(
selected = selectedDate,
rangeStart = now.firstSchoolDayInSchoolYear,
rangeEnd = now.lastSchoolDayInSchoolYear,
onDateSelected = {
presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth)
}
)
}
override fun onSaveInstanceState(outState: Bundle) {

View File

@ -38,5 +38,5 @@ interface CompletedLessonsView : BaseView {
fun showCompletedLessonDialog(completedLesson: CompletedLesson)
fun showDatePickerDialog(currentDate: LocalDate)
fun showDatePickerDialog(selectedDate: LocalDate)
}

View File

@ -0,0 +1,51 @@
package io.github.wulkanowy.utils
import androidx.fragment.app.Fragment
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import kotlinx.parcelize.Parcelize
import java.time.LocalDate
import java.time.ZoneOffset
import java.time.temporal.ChronoUnit
fun Fragment.openMaterialDatePicker(
selected: LocalDate,
rangeStart: LocalDate,
rangeEnd: LocalDate,
onDateSelected: (LocalDate) -> Unit,
) {
val constraintsBuilder = CalendarConstraints.Builder().apply {
setValidator(CalendarDayRangeValidator(rangeStart, rangeEnd))
setStart(rangeStart.toTimestamp(ZoneOffset.UTC))
setEnd(rangeEnd.toTimestamp(ZoneOffset.UTC))
}
val datePicker = MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(selected.toTimestamp(ZoneOffset.UTC))
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime(ZoneOffset.UTC).toLocalDate()
onDateSelected(date)
}
if (!parentFragmentManager.isStateSaved) {
datePicker.show(parentFragmentManager, null)
}
}
@Parcelize
private class CalendarDayRangeValidator(
val start: LocalDate,
val end: LocalDate,
) : CalendarConstraints.DateValidator {
override fun isValid(dateLong: Long): Boolean {
val date = dateLong.toLocalDateTime().toLocalDate()
val daysUntilEnd = date.until(end, ChronoUnit.DAYS)
val daysUntilStart = date.until(start, ChronoUnit.DAYS)
return daysUntilStart <= 0 && daysUntilEnd >= 0
}
}

View File

@ -1,16 +0,0 @@
package io.github.wulkanowy.utils
import com.google.android.material.datepicker.CalendarConstraints
import kotlinx.parcelize.Parcelize
import java.time.temporal.ChronoUnit
@Parcelize
class SchoolDaysValidator(val start: Long, val end: Long) : CalendarConstraints.DateValidator {
override fun isValid(dateLong: Long): Boolean {
val date = dateLong.toLocalDateTime()
return date.until(end.toLocalDateTime(), ChronoUnit.DAYS) >= 0 &&
date.until(start.toLocalDateTime(), ChronoUnit.DAYS) <= 0
}
}

View File

@ -8,7 +8,6 @@ import java.time.DayOfWeek.SUNDAY
import java.time.Instant
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.Month
import java.time.ZoneId
import java.time.ZoneOffset
@ -23,13 +22,13 @@ private const val DEFAULT_DATE_PATTERN = "dd.MM.yyyy"
fun String.toLocalDate(format: String = DEFAULT_DATE_PATTERN): LocalDate =
LocalDate.parse(this, DateTimeFormatter.ofPattern(format))
fun LocalDateTime.toTimestamp() =
atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli()
fun LocalDateTime.toTimestamp(tz: ZoneId = ZoneId.systemDefault()) =
atZone(tz).withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli()
fun Long.toLocalDateTime(): LocalDateTime =
LocalDateTime.ofInstant(Instant.ofEpochMilli(this), ZoneId.systemDefault())
fun Long.toLocalDateTime(tz: ZoneId = ZoneId.systemDefault()): LocalDateTime =
LocalDateTime.ofInstant(Instant.ofEpochMilli(this), tz)
fun LocalDate.toTimestamp() = atTime(LocalTime.now()).toTimestamp()
fun LocalDate.toTimestamp(tz: ZoneId = ZoneId.systemDefault()) = atStartOfDay().toTimestamp(tz)
fun LocalDate.toFormattedString(pattern: String = DEFAULT_DATE_PATTERN): String =
format(DateTimeFormatter.ofPattern(pattern))

View File

@ -7,6 +7,7 @@ import org.junit.Test
import java.time.LocalDate.of
import java.time.LocalDateTime
import java.time.Month.JANUARY
import java.time.ZoneOffset
import java.util.Locale
class TimeExtensionTest {
@ -25,7 +26,10 @@ class TimeExtensionTest {
@Test
fun toFormattedStringLocalDateTimeTest() {
assertEquals("01.10.2018", LocalDateTime.of(2018, 10, 1, 10, 0, 0).toFormattedString())
assertEquals("2018-10-01 10:00:00", LocalDateTime.of(2018, 10, 1, 10, 0, 0).toFormattedString("uuuu-MM-dd HH:mm:ss"))
assertEquals(
"2018-10-01 10:00:00",
LocalDateTime.of(2018, 10, 1, 10, 0, 0).toFormattedString("uuuu-MM-dd HH:mm:ss")
)
}
@Test
@ -222,4 +226,18 @@ class TimeExtensionTest {
assertEquals(of(2020, 10, 18), endExamsDay)
}
}
@Test
fun getLocalDateToTimestampUTC() {
assertEquals(0L, of(1970, 1, 1).toTimestamp(ZoneOffset.UTC))
assertEquals(946684800000L, of(2000, 1, 1).toTimestamp(ZoneOffset.UTC))
assertEquals(1640131200000L, of(2021, 12, 22).toTimestamp(ZoneOffset.UTC))
}
@Test
fun getLocalDateTimeToUtcTimestamp() {
assertEquals(0L, LocalDateTime.of(1970, 1, 1, 0, 0, 0).toTimestamp(ZoneOffset.UTC))
assertEquals(946684800000L, LocalDateTime.of(2000, 1, 1, 0, 0, 0).toTimestamp(ZoneOffset.UTC))
assertEquals(1640131200000L, LocalDateTime.of(2021, 12, 22, 0, 0, 0).toTimestamp(ZoneOffset.UTC))
}
}