Skip to content

Commit

Permalink
Add support for time with some helper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
shivathapaa committed Sep 7, 2024
1 parent 20949b4 commit fcc1783
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 4 deletions.
2 changes: 1 addition & 1 deletion nepali-date-picker/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ mavenPublishing {
coordinates(
groupId = "io.github.shivathapaa",
artifactId = "nepali-date-picker",
version = "2.0.0-beta07"
version = "2.0.0-beta08"
)

// POM metadata for the published artifact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,46 @@ import dev.shivathapaa.nepalidatepickerkmp.data.NepaliDateLocale
import dev.shivathapaa.nepalidatepickerkmp.data.NepaliDatePickerLang
import dev.shivathapaa.nepalidatepickerkmp.data.NepaliMonthCalendar
import dev.shivathapaa.nepalidatepickerkmp.data.SimpleDate
import dev.shivathapaa.nepalidatepickerkmp.data.SimpleTime
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.todayIn
import kotlinx.datetime.toLocalDateTime

@Immutable
internal class NepaliCalendarModel(val locale: NepaliDateLocale = NepaliDateLocale()) {
private val timeZone = TimeZone.of(zoneId = "Asia/Kathmandu")
private val localEnglishDateTime: LocalDateTime = Clock.System.now().toLocalDateTime(timeZone)

val today
get(): CustomCalendar {
return getNepaliDateInstance()
}

val todayEnglish
get(): SimpleDate = SimpleDate(
year = localEnglishDateTime.year,
month = localEnglishDateTime.monthNumber,
dayOfMonth = localEnglishDateTime.dayOfMonth
)

val currentTime
get(): SimpleTime {
val nowTime: LocalDateTime = Clock.System.now().toLocalDateTime(timeZone)

return SimpleTime(
hour = nowTime.hour,
minute = nowTime.minute,
second = nowTime.second,
nanosecond = nowTime.nanosecond
)
}

private fun getNepaliDateInstance(): CustomCalendar {
val now = Clock.System.todayIn(TimeZone.of("Asia/Kathmandu"))
return DateConverters.convertToNepaliCalendar(
englishYYYY = now.year, englishMM = now.monthNumber, englishDD = now.dayOfMonth
englishYYYY = localEnglishDateTime.year,
englishMM = localEnglishDateTime.monthNumber,
englishDD = localEnglishDateTime.dayOfMonth
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import dev.shivathapaa.nepalidatepickerkmp.data.NepaliDateLocale
import dev.shivathapaa.nepalidatepickerkmp.data.NepaliDatePickerLang
import dev.shivathapaa.nepalidatepickerkmp.data.NepaliMonthCalendar
import dev.shivathapaa.nepalidatepickerkmp.data.SimpleDate
import dev.shivathapaa.nepalidatepickerkmp.data.SimpleTime
import dev.shivathapaa.nepalidatepickerkmp.data.englishMonths

@Immutable
Expand All @@ -36,6 +37,28 @@ object NepaliDateConverter {
val todayNepaliDate
get() = calendarModel.today

/**
* Strictly adjusted to `Asia/Kathmandu` TimeZone.
*
* @return the current date in the English calendar as a [SimpleDate].
*/
val todayEnglishDate: SimpleDate
get() = calendarModel.todayEnglish

/**
* Gets the current time in Kathmandu.
*
* This property returns a [SimpleTime] object representing the current hour, minute, second,
* and nanosecond in the `Asia/Kathmandu` time zone. The time is calculated fresh each time
* this property is accessed, so you always get the most up-to-date time.
*
* Get formatted time string using [getFormattedTimeInNepali] and [getFormattedTimeInEnglish]
*
* @return A [SimpleTime] object representing the current time.
*/
val currentTime: SimpleTime
get() = calendarModel.currentTime

/**
* This function converts english date to nepali date.
*
Expand Down Expand Up @@ -332,6 +355,78 @@ object NepaliDateConverter {
return calendarModel.formatNepaliDate(customCalendar, locale)
}

/**
* Formats a [SimpleTime] object into a time string in English.
*
* @param simpleTime The [SimpleTime] object to format.
* @param use12HourFormat If true, the time will be formatted in 12-hour format (e.g., "09:45 AM").
* If false, the time will be formatted in 24-hour format (e.g., "21:45").
*
* @return A formatted time string in English.
*
* ```
* val time = SimpleTime(16, 30, 0, 0)
* val nepaliTime12Hour = getFormattedTimeInNepali(time) // Output: "4:30 PM"
* val nepaliTime24Hour = getFormattedTimeInNepali(time, false) // Output: "16:30"
* ```
*/
fun getFormattedTimeInEnglish(simpleTime: SimpleTime, use12HourFormat: Boolean = true): String {
return if (use12HourFormat) {
val amPm = if (simpleTime.hour < 12) "AM" else "PM"
val standardHour =
if (simpleTime.hour == 0) 12 else if (simpleTime.hour > 12) simpleTime.hour - 12 else simpleTime.hour

"$standardHour:${simpleTime.minute.toString().padStart(2, '0')} $amPm"
} else {
"${simpleTime.hour}:${simpleTime.minute.toString().padStart(2, '0')}"
}
}

/**
* Formats a [SimpleTime] object into a Nepali time string.
*
* This function generates a formatted time string in Nepali.
*
* The time of day is determined using hour values to Nepali names:
* * 4-10: "बिहान"
* * 11-15: "दिउँसो"
* * 16-19: "साँझ"
* * Other: "राति"
*
* The hour is displayed in 12-hour format if `use12HourFormat` is true, otherwise in 24-hour format.
* Minutes are always displayed with two digits (e.g., 05, 30).
* Digits are converted to Nepali using the [convertToNepaliNumber] function.
*
* @param simpleTime The [SimpleTime] object to format.
* @param use12HourFormat If true (default), the time will be formatted in 12-hour format including the time of day.
* If false, the time will be formatted in 24-hour format.
*
* @return A formatted time string in Nepali.
*
* ```
* val time = SimpleTime(16, 30, 0, 0)
* val nepaliTime12Hour = getFormattedTimeInNepali(time) // Output: "साँझ ४ : ३०"
* val nepaliTime24Hour = getFormattedTimeInNepali(time, false) // Output: "१६ : ३०"
* ```
*/
fun getFormattedTimeInNepali(simpleTime: SimpleTime, use12HourFormat: Boolean = true): String {
val hourOfDay =
when (simpleTime.hour) {
in 4..10 -> "बिहान"
in 11..15 -> "दिउँसो"
in 16..19 -> "साँझ"
else -> "राति"
}

val hour = if (use12HourFormat && simpleTime.hour > 12) simpleTime.hour - 12 else simpleTime.hour
val formattedHour = if (use12HourFormat && simpleTime.hour == 0) 12 else hour

return if (use12HourFormat) {
"$hourOfDay ${formattedHour.toString().convertToNepaliNumber()} : ${simpleTime.minute.toString().padStart(2, '0').convertToNepaliNumber()}"
}
else "${formattedHour.toString().convertToNepaliNumber()} : ${simpleTime.minute.toString().padStart(2, '0').convertToNepaliNumber()}"
}

/**
* Overload function of above [formatNepaliDate] function without date validation.
* Formats a Nepali date based on the specified user preferences. (Without validation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ data class SimpleDate(
}
}

/**
* Represents a 24Hrs format time of day (hour, minute, second, nanosecond).
* Strictly adjusted to the `Asia/Kathmandu` TimeZone.
*
* @property hour Hour of the day (0-23).
* @property minute Minute of the hour (0-59).
* @property second Second of the minute (0-59).
* @property nanosecond Nanosecond of the second (0-999,999,999).
*/
@Immutable
data class SimpleTime(
val hour: Int,
val minute: Int,
val second: Int,
val nanosecond: Int
)

/**
* Represents a date in a custom calendar system with detailed information.
*
Expand Down

0 comments on commit fcc1783

Please sign in to comment.