Skip to content

Commit

Permalink
Add helper function to calculate days in between, and add function to…
Browse files Browse the repository at this point in the history
… return date time in ISO 8601 format.
  • Loading branch information
shivathapaa committed Sep 9, 2024
1 parent 0c9575a commit 3bc72a8
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -263,16 +263,7 @@ internal object DateConverters {
return totalNepDaysCount
}

// Three overload functions for month details
fun getNepaliMonth(
nepaliYear: Int, nepaliMonth: Int
): NepaliMonthCalendar {
// Calculate and return the month details
return calculateNepaliMonthDetails(
nepaliYear = nepaliYear, nepaliMonth = nepaliMonth
)
}

// Two overload functions for month details
fun getNepaliMonth(
nepaliYear: Int, nepaliMonth: Int, addedMonthsCount: Int
): NepaliMonthCalendar {
Expand All @@ -291,6 +282,32 @@ internal object DateConverters {
)
}

/**
* Calculates the total number of days between two [SimpleDate] objects in the Nepali calendar.
*
* @param startDate The starting date.
* @param endDate The ending date.
* @return The number of days between the two dates. Returns -1 if either date is invalid,
* and throws exception if the year is not found in [daysInMonthMap].
*/
fun nepaliDaysInBetween(startDate: SimpleDate, endDate: SimpleDate): Int {
if (startDate.year > endDate.year) {
return -nepaliDaysInBetween(endDate, startDate)
}

if (!isNepaliCalendarInConversionRange(startDate.year, startDate.month, startDate.dayOfMonth)
|| !isNepaliCalendarInConversionRange(endDate.year, endDate.month, endDate.dayOfMonth)
) {
throw IllegalArgumentException("Out of Range: Nepali start year ${startDate.year} or end year " +
"${startDate.year} is out of range to compare. Check range value from NepaliDatePickerDefaults.")
}

val startOffset = calculateDayOffset(minNepaliYear, startDate.year, startDate.month) + startDate.dayOfMonth
val endOffset = calculateDayOffset(minNepaliYear, endDate.year, endDate.month) + endDate.dayOfMonth

return endOffset - startOffset
}

private fun getCustomCalendarUsingDayMonthYear(
year: Int,
month: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import dev.shivathapaa.nepalidatepickerkmp.data.SimpleTime
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime

@Immutable
Expand Down Expand Up @@ -83,16 +84,8 @@ internal class NepaliCalendarModel(val locale: NepaliDateLocale = NepaliDateLoca
return DateConverters.getTotalDaysInNepaliMonth(year, month)
}

fun calculateFirstAndLastDayOfNepaliMonth(
nepaliYear: Int, nepaliMonth: Int
): NepaliMonthCalendar {
return DateConverters.calculateNepaliMonthDetails(nepaliYear, nepaliMonth)
}

fun getNepaliMonth(nepaliYear: Int, nepaliMonth: Int): NepaliMonthCalendar {
return DateConverters.getNepaliMonth(
nepaliYear = nepaliYear, nepaliMonth = nepaliMonth
)
return DateConverters.calculateNepaliMonthDetails(nepaliYear, nepaliMonth)
}

fun getNepaliMonth(simpleNepaliDate: SimpleDate): CustomCalendar {
Expand Down Expand Up @@ -121,6 +114,40 @@ internal class NepaliCalendarModel(val locale: NepaliDateLocale = NepaliDateLoca
)
}

fun nepaliDaysInBetween(startDate: SimpleDate, endDate: SimpleDate): Int {
return DateConverters.nepaliDaysInBetween(startDate, endDate)
}

fun formatEnglishDateToIsoFormat(englishDate: SimpleDate, time: SimpleTime): String {
val localDateTime = LocalDateTime(
englishDate.year,
englishDate.month,
englishDate.dayOfMonth,
time.hour,
time.minute,
time.second,
time.nanosecond
)

return localDateTime.toInstant(timeZone).toString()
}

fun formatNepaliDateToIsoFormat(nepaliDate: SimpleDate, time: SimpleTime): String {
val convertedEnglishDate = convertToEnglishDate(nepaliDate.year, nepaliDate.month, nepaliDate.dayOfMonth)

val localDateTime = LocalDateTime(
convertedEnglishDate.year,
convertedEnglishDate.month,
convertedEnglishDate.dayOfMonth,
time.hour,
time.minute,
time.second,
time.nanosecond
)

return localDateTime.toInstant(timeZone).toString()
}

/**
* Formats a Nepali date based on the specified user preferences.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import dev.shivathapaa.nepalidatepickerkmp.data.NepaliMonthCalendar
import dev.shivathapaa.nepalidatepickerkmp.data.SimpleDate
import dev.shivathapaa.nepalidatepickerkmp.data.SimpleTime
import dev.shivathapaa.nepalidatepickerkmp.data.englishMonths
import kotlinx.datetime.LocalDate
import kotlinx.datetime.daysUntil

@Immutable
object NepaliDateConverter {
Expand Down Expand Up @@ -108,7 +110,7 @@ object NepaliDateConverter {
fun getNepaliMonthCalendar(
nepaliYear: Int, nepaliMonth: Int
): NepaliMonthCalendar {
return calendarModel.calculateFirstAndLastDayOfNepaliMonth(nepaliYear, nepaliMonth)
return calendarModel.getNepaliMonth(nepaliYear, nepaliMonth)
}

/**
Expand Down Expand Up @@ -296,6 +298,81 @@ object NepaliDateConverter {
)
}

/**
* Calculates the total number of days between two [SimpleDate] objects in the Nepali calendar.
*
* The end date is not added. You can add 1 to its returned value to include the end date too.
*
* @param startDate The starting date.
* @param endDate The ending date.
* @return The number of days between the two dates. Throws exception if the year is not in
* range [NepaliDatePickerDefaults.NepaliYearRange], or returns -1 if either date is invalid.
*/
fun getNepaliDaysInBetween(startDate: SimpleDate, endDate: SimpleDate): Int {
return calendarModel.nepaliDaysInBetween(startDate, endDate)
}

/**
* Calculates the total number of days between two [SimpleDate] objects in the English calendar.
*
* The end date is not added. You can add 1 to its returned value to include the end date too.
*
* @param startDate The starting date.
* @param endDate The ending date.
* @return The number of days between the two dates.
*/
fun getEnglishDaysInBetween(startDate: SimpleDate, endDate: SimpleDate): Int {
val startLocalDate = LocalDate(startDate.year, startDate.month, startDate.dayOfMonth)
val endLocalDate = LocalDate(endDate.year, endDate.month, endDate.dayOfMonth)

return startLocalDate.daysUntil(endLocalDate)
}

/**
* Converts an English (Gregorian) date and time to ISO 8601 UTC format.
*
* @param englishDate The date in the Gregorian calendar (English date) as a [SimpleDate].
* @param time The time of day as a [SimpleTime], default is the current time.
*
* @return A string in ISO 8601 format representing the UTC date and time.
* The result is in the format `YYYY-MM-DDTHH:mm:ssZ` (Zulu time).
*
* Example:
* ```
* val englishDate = SimpleDate(2024, 9, 9)
* val time = SimpleTime(14, 30, 15, 0)
* val isoFormat = NepaliDateConverter.formatEnglishDateToIsoFormat(englishDate, time)
* println(isoFormat) // Outputs: "2024-09-09T09:00:15Z"
* ```
*/
fun formatEnglishDateToIsoFormat(englishDate: SimpleDate, time: SimpleTime = currentTime): String {
return calendarModel.formatEnglishDateToIsoFormat(englishDate, time)
}

/**
* Converts a Nepali (Bikram Sambat) date and time to ISO 8601 UTC format.
*
* The Nepali date (Bikram Sambat) is first converted to the equivalent Gregorian (English) date,
* and then the time is appended to produce a complete timestamp in UTC.
*
* @param nepaliDate The date in the Nepali Bikram Sambat calendar as a [SimpleDate].
* @param time The time of day as a [SimpleTime], default is the current time.
*
* @return A string in ISO 8601 format representing the UTC date and time.
* The result is in the format `YYYY-MM-DDTHH:mm:ssZ` (Zulu time).
*
* Example:
* ```
* val nepaliDate = SimpleDate(2081, 5, 24) // Bikram Sambat date
* val time = SimpleTime(14, 30, 15, 0)
* val isoFormat = NepaliDateConverter.formatNepaliDateToIsoFormat(nepaliDate, time)
* println(isoFormat) // Outputs: "2024-09-09T09:00:15Z"
* ```
*/
fun formatNepaliDateToIsoFormat(nepaliDate: SimpleDate, time: SimpleTime = currentTime): String {
return calendarModel.formatNepaliDateToIsoFormat(nepaliDate, time)
}

/**
* @param dayOfWeek takes value between 1 to 7.
* @param format gives name of day either in short or medium or full name. i.e. Sunday, Mon, T, आईतबार, आईत, आ, etc.
Expand Down

0 comments on commit 3bc72a8

Please sign in to comment.