commonMain.io.islandtime.Month.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core-metadata Show documentation
Show all versions of core-metadata Show documentation
A multiplatform library for working with dates and times
The newest version!
package io.islandtime
import io.islandtime.format.DateTimeTextProvider
import io.islandtime.format.TextStyle
import io.islandtime.locale.Locale
import io.islandtime.measures.IntDays
import io.islandtime.measures.IntMonths
import io.islandtime.measures.LongMonths
import io.islandtime.measures.days
/**
* A month of the year.
*/
enum class Month {
JANUARY {
override val lengthInCommonYear = 31.days
override val firstDayOfCommonYear = 1
},
FEBRUARY {
override val lengthInCommonYear = 28.days
override val lengthInLeapYear = 29.days
override val firstDayOfCommonYear = 32
},
MARCH {
override val lengthInCommonYear = 31.days
override val firstDayOfCommonYear = 60
},
APRIL {
override val lengthInCommonYear = 30.days
override val firstDayOfCommonYear = 91
},
MAY {
override val lengthInCommonYear = 31.days
override val firstDayOfCommonYear = 121
},
JUNE {
override val lengthInCommonYear = 30.days
override val firstDayOfCommonYear = 152
},
JULY {
override val lengthInCommonYear = 31.days
override val firstDayOfCommonYear = 182
},
AUGUST {
override val lengthInCommonYear = 31.days
override val firstDayOfCommonYear = 213
},
SEPTEMBER {
override val lengthInCommonYear = 30.days
override val firstDayOfCommonYear = 244
},
OCTOBER {
override val lengthInCommonYear = 31.days
override val firstDayOfCommonYear = 272
},
NOVEMBER {
override val lengthInCommonYear = 30.days
override val firstDayOfCommonYear = 305
},
DECEMBER {
override val lengthInCommonYear = 31.days
override val firstDayOfCommonYear = 335
};
/**
* The ISO month number, from 1-12.
*/
val number: Int get() = ordinal + 1
/**
* The number of days in the month in a common year.
*/
abstract val lengthInCommonYear: IntDays
/**
* The number of days in the month in a leap month.
*/
open val lengthInLeapYear: IntDays
get() = lengthInCommonYear
/**
* The day of the year corresponding to the month's first day in a common year.
*
* For example, the first day of [MARCH] is the 60th day of a common year.
*/
abstract val firstDayOfCommonYear: Int
/**
* The day of the year corresponding to the month's first day in a leap year.
*
* For example, the first day of [MARCH] is the 61st day of a leap year.
*/
val firstDayOfLeapYear: Int
get() = when (this) {
JANUARY, FEBRUARY -> firstDayOfCommonYear
else -> firstDayOfCommonYear + 1
}
/**
* The localized name of the month, if available for the [locale] in the specified style. The result depends on the
* configured [DateTimeTextProvider] and may differ between platforms.
*
* @param style the style of text
* @param locale the locale
* @return the localized name or `null` if unavailable for the specified locale
* @see displayName
*/
fun localizedName(style: TextStyle, locale: Locale): String? {
return DateTimeTextProvider.monthTextFor(number.toLong(), style, locale)
}
/**
* A textual representation of the month, suitable for display purposes. The localized name will be returned, if
* available. If not, the ISO month number (1-12) will be returned instead.
*
* The result depends on the configured [DateTimeTextProvider] and may differ between platforms.
*
* @param style the style of text
* @param locale the locale
* @return the localized name or [number] if unavailable for the specified locale
* @see localizedName
*/
fun displayName(style: TextStyle, locale: Locale): String {
return localizedName(style, locale) ?: number.toString()
}
/**
* Returns the number of days in the month for a particular year.
* @param year retrieve the length of the month within this year
* @return the number of days in the month
*/
fun lengthIn(year: Int): IntDays {
return when (this) {
FEBRUARY -> if (isLeapYear(year)) lengthInLeapYear else lengthInCommonYear
else -> lengthInCommonYear
}
}
/**
* Returns the last day of the month in a particular year.
*/
fun lastDayIn(year: Int) = lengthIn(year).value
/**
* Returns the day of the year that this month's first days falls on. This may vary depending on whether or not the
* year is a leap year. For example, the first day of [MARCH] will be either 60th or 61st day of the year.
* @param year retrieve the day of year number within this year
* @return the first day of year number
*/
fun firstDayOfYearIn(year: Int): Int {
return if (isLeapYear(year)) firstDayOfLeapYear else firstDayOfCommonYear
}
/**
* Returns the day of the year that this month's last day falls on. This may vary depending on whether or not the
* year is a leap year. For example, the last of [FEBRUARY] will be either 59th or 60th day of the year.
* @param year retrieve the day of year number within this year
* @return the last day of year number
*/
fun lastDayOfYearIn(year: Int): Int {
val isLeap = isLeapYear(year)
return if (isLeap) {
firstDayOfLeapYear + lengthInLeapYear.value - 1
} else {
firstDayOfCommonYear + lengthInCommonYear.value - 1
}
}
/**
* Returns the range of valid days for this month within a given year
* @param year retrieve the day range within this year
* @return the range of valid days
*/
fun dayRangeIn(year: Int): IntRange {
return 1..lengthIn(year).value
}
/**
* Adds months to this month, wrapping when the beginning or end of the year is reached.
*/
operator fun plus(months: IntMonths) = plus(months.value % 12)
/**
* Adds months to this month, wrapping when the beginning or end of the year is reached.
*/
operator fun plus(months: LongMonths) = plus((months.value % 12).toInt())
/**
* Subtracts months from this month, wrapping when the beginning or end of the year is reached.
*/
operator fun minus(months: IntMonths) = plus(-(months.value % 12))
/**
* Subtracts months from this month, wrapping when the beginning or end of the year is reached.
*/
operator fun minus(months: LongMonths) = plus(-(months.value % 12).toInt())
private fun plus(monthsToAdd: Int): Month {
return values()[(ordinal + (monthsToAdd + 12)) % 12]
}
companion object {
inline val MIN get() = JANUARY
inline val MAX get() = DECEMBER
}
}
/**
* Converts an ISO month number, from 1-12, to a [Month].
*/
fun Int.toMonth(): Month {
if (this !in Month.MIN.number..Month.MAX.number) {
throw DateTimeException("'$this' is not a valid month of the year")
}
return Month.values()[this - 1]
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy