Skip to content

Commit

Permalink
Replace dayOfMonth with day and monthNumber with month
Browse files Browse the repository at this point in the history
`monthNumber` is still called that in the formatting facilities
to distinguish `monthNumber` from `monthName`, and also in
`DateTimeComponents` because `monthNumber` can contain
out-of-bounds data and is useful even aside from being a view of
`Month`.

Fixes #84

Blocked by an IDE bug:
<https://youtrack.jetbrains.com/issue/KTIJ-29647/ReplaceWith-of-properties-just-erases-code>
  • Loading branch information
dkhalanskyjb committed May 27, 2024
1 parent bc8adee commit 8885ea5
Show file tree
Hide file tree
Showing 30 changed files with 288 additions and 154 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ val datetimeInSystemZone: LocalDateTime = currentMoment.toLocalDateTime(TimeZone
```

A `LocalDateTime` instance exposes familiar components of the Gregorian calendar:
`year`, `month`, `dayOfMonth`, `hour`, and so on up to `nanosecond`.
`year`, `month`, `day`, `hour`, and so on up to `nanosecond`.
The property `dayOfWeek` shows what weekday that date is,
and `dayOfYear` shows the day number since the beginning of a year.

Expand Down Expand Up @@ -210,7 +210,7 @@ can define their own format or use some of the predefined ones:
val dateFormat = LocalDate.Format {
monthNumber(padding = Padding.SPACE)
char('/')
dayOfMonth()
day()
char(' ')
year()
}
Expand Down
60 changes: 44 additions & 16 deletions core/common/src/LocalDate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package kotlinx.datetime
import kotlinx.datetime.format.*
import kotlinx.datetime.serializers.*
import kotlinx.serialization.Serializable
import kotlin.internal.*

/**
* The date part of [LocalDateTime].
Expand Down Expand Up @@ -96,7 +97,7 @@ public expect class LocalDate : Comparable<LocalDate> {
* Creates a new format for parsing and formatting [LocalDate] values.
*
* Only parsing and formatting of well-formed values is supported. If the input does not fit the boundaries
* (for example, [dayOfMonth] is 31 for February), consider using [DateTimeComponents.Format] instead.
* (for example, [day] is 31 for February), consider using [DateTimeComponents.Format] instead.
*
* There is a collection of predefined formats in [LocalDate.Formats].
*
Expand Down Expand Up @@ -157,19 +158,19 @@ public expect class LocalDate : Comparable<LocalDate> {
/**
* Constructs a [LocalDate] instance from the given date components.
*
* The components [monthNumber] and [dayOfMonth] are 1-based.
* The components [month] and [day] are 1-based.
*
* The supported ranges of components:
* - [year] the range is platform-dependent, but at least is enough to represent dates of all instants between
* [Instant.DISTANT_PAST] and [Instant.DISTANT_FUTURE]
* - [monthNumber] `1..12`
* - [dayOfMonth] `1..31`, the upper bound can be less, depending on the month
* - [month] `1..12`
* - [day] `1..31`, the upper bound can be less, depending on the month
*
* @throws IllegalArgumentException if any parameter is out of range or if [dayOfMonth] is invalid for the
* @throws IllegalArgumentException if any parameter is out of range or if [day] is invalid for the
* given [monthNumber] and [year].
* @sample kotlinx.datetime.test.samples.LocalDateSamples.constructorFunctionMonthNumber
*/
public constructor(year: Int, monthNumber: Int, dayOfMonth: Int)
public constructor(year: Int, month: Int, day: Int)

/**
* Constructs a [LocalDate] instance from the given date components.
Expand All @@ -178,13 +179,13 @@ public expect class LocalDate : Comparable<LocalDate> {
* - [year] the range is platform-dependent, but at least is enough to represent dates of all instants between
* [Instant.DISTANT_PAST] and [Instant.DISTANT_FUTURE]
* - [month] all values of the [Month] enum
* - [dayOfMonth] `1..31`, the upper bound can be less, depending on the month
* - [day] `1..31`, the upper bound can be less, depending on the month
*
* @throws IllegalArgumentException if any parameter is out of range or if [dayOfMonth] is invalid for the
* @throws IllegalArgumentException if any parameter is out of range or if [day] is invalid for the
* given [month] and [year].
* @sample kotlinx.datetime.test.samples.LocalDateSamples.constructorFunction
*/
public constructor(year: Int, month: Month, dayOfMonth: Int)
public constructor(year: Int, month: Month, day: Int)

/**
* Returns the year component of the date.
Expand All @@ -193,11 +194,8 @@ public expect class LocalDate : Comparable<LocalDate> {
*/
public val year: Int

/**
* Returns the number-of-the-month (1..12) component of the date.
*
* Shortcut for `month.number`.
*/
/** @suppress */
@Deprecated("Use the 'month' property instead", ReplaceWith("this.month.number"), level = DeprecationLevel.WARNING)
public val monthNumber: Int

/**
Expand All @@ -210,8 +208,12 @@ public expect class LocalDate : Comparable<LocalDate> {
/**
* Returns the day-of-month (`1..31`) component of the date.
*
* @sample kotlinx.datetime.test.samples.LocalDateSamples.dayOfMonth
* @sample kotlinx.datetime.test.samples.LocalDateSamples.day
*/
public val day: Int

/** @suppress */
@Deprecated("Use the 'day' property instead", ReplaceWith("this.day"), level = DeprecationLevel.WARNING)
public val dayOfMonth: Int

/**
Expand Down Expand Up @@ -259,6 +261,32 @@ public expect class LocalDate : Comparable<LocalDate> {
public override fun toString(): String
}

/**
* @suppress
*/
@Deprecated(
"Use the constructor that accepts a 'month' and a 'day'",
ReplaceWith("LocalDate(year = year, month = monthNumber, day = dayOfMonth)"),
level = DeprecationLevel.WARNING
)
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@LowPriorityInOverloadResolution
public fun LocalDate(year: Int, monthNumber: Int, dayOfMonth: Int): LocalDate =
LocalDate(year = year, month = monthNumber, day = dayOfMonth)

/**
* @suppress
*/
@Deprecated(
"Use the constructor that accepts a 'day'",
ReplaceWith("LocalDate(year = year, month = month, day = dayOfMonth)"),
level = DeprecationLevel.WARNING
)
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@LowPriorityInOverloadResolution
public fun LocalDate(year: Int, month: Month, dayOfMonth: Int): LocalDate =
LocalDate(year = year, month = month, day = dayOfMonth)

/**
* Formats this value using the given [format].
* Equivalent to calling [DateTimeFormat.format] on [format] with `this`.
Expand Down Expand Up @@ -287,7 +315,7 @@ public fun String.toLocalDate(): LocalDate = LocalDate.parse(this)
* @sample kotlinx.datetime.test.samples.LocalDateSamples.atTimeInline
*/
public fun LocalDate.atTime(hour: Int, minute: Int, second: Int = 0, nanosecond: Int = 0): LocalDateTime =
LocalDateTime(year, monthNumber, dayOfMonth, hour, minute, second, nanosecond)
LocalDateTime(year, month.number, day, hour, minute, second, nanosecond)

/**
* Combines this date's components with the specified [LocalTime] components into a [LocalDateTime] value.
Expand Down
80 changes: 64 additions & 16 deletions core/common/src/LocalDateTime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.datetime.format.*
import kotlinx.datetime.serializers.LocalDateTimeIso8601Serializer
import kotlinx.datetime.serializers.LocalDateTimeComponentSerializer
import kotlinx.serialization.Serializable
import kotlin.internal.*

/**
* The representation of a specific civil date and time without a reference to a particular time zone.
Expand Down Expand Up @@ -137,15 +138,15 @@ public expect class LocalDateTime : Comparable<LocalDateTime> {
*
* // `08/30 18:43:13`, using a custom format:
* LocalDateTime.Format {
* monthNumber(); char('/'); dayOfMonth()
* monthNumber(); char('/'); day()
* char(' ')
* hour(); char(':'); minute()
* optional { char(':'); second() }
* }
* ```
*
* Only parsing and formatting of well-formed values is supported. If the input does not fit the boundaries
* (for example, [dayOfMonth] is 31 for February), consider using [DateTimeComponents.Format] instead.
* (for example, [day] is 31 for February), consider using [DateTimeComponents.Format] instead.
*
* There is a collection of predefined formats in [LocalDateTime.Formats].
*
Expand Down Expand Up @@ -194,27 +195,27 @@ public expect class LocalDateTime : Comparable<LocalDateTime> {
/**
* Constructs a [LocalDateTime] instance from the given date and time components.
*
* The components [monthNumber] and [dayOfMonth] are 1-based.
* The components [month] and [day] are 1-based.
*
* The supported ranges of components:
* - [year] the range is platform-dependent, but at least is enough to represent dates of all instants between
* [Instant.DISTANT_PAST] and [Instant.DISTANT_FUTURE]
* - [monthNumber] `1..12`
* - [dayOfMonth] `1..31`, the upper bound can be less, depending on the month
* - [month] `1..12`
* - [day] `1..31`, the upper bound can be less, depending on the month
* - [hour] `0..23`
* - [minute] `0..59`
* - [second] `0..59`
* - [nanosecond] `0..999_999_999`
*
* @throws IllegalArgumentException if any parameter is out of range,
* or if [dayOfMonth] is invalid for the given [monthNumber] and [year].
* or if [day] is invalid for the given [month] and [year].
*
* @sample kotlinx.datetime.test.samples.LocalDateTimeSamples.constructorFunctionWithMonthNumber
*/
public constructor(
year: Int,
monthNumber: Int,
dayOfMonth: Int,
month: Int,
day: Int,
hour: Int,
minute: Int,
second: Int = 0,
Expand All @@ -228,21 +229,21 @@ public expect class LocalDateTime : Comparable<LocalDateTime> {
* - [year] the range is platform-dependent, but at least is enough to represent dates of all instants between
* [Instant.DISTANT_PAST] and [Instant.DISTANT_FUTURE]
* - [month] all values of the [Month] enum
* - [dayOfMonth] `1..31`, the upper bound can be less, depending on the month
* - [day] `1..31`, the upper bound can be less, depending on the month
* - [hour] `0..23`
* - [minute] `0..59`
* - [second] `0..59`
* - [nanosecond] `0..999_999_999`
*
* @throws IllegalArgumentException if any parameter is out of range,
* or if [dayOfMonth] is invalid for the given [month] and [year].
* or if [day] is invalid for the given [month] and [year].
*
* @sample kotlinx.datetime.test.samples.LocalDateTimeSamples.constructorFunction
*/
public constructor(
year: Int,
month: Month,
dayOfMonth: Int,
day: Int,
hour: Int,
minute: Int,
second: Int = 0,
Expand All @@ -263,11 +264,8 @@ public expect class LocalDateTime : Comparable<LocalDateTime> {
*/
public val year: Int

/**
* Returns the number-of-the-month (1..12) component of the [date].
*
* @sample kotlinx.datetime.test.samples.LocalDateTimeSamples.dateComponents
*/
/** @suppress */
@Deprecated("Use the 'month' property instead", ReplaceWith("month.number"), level = DeprecationLevel.WARNING)
public val monthNumber: Int

/**
Expand All @@ -282,6 +280,10 @@ public expect class LocalDateTime : Comparable<LocalDateTime> {
*
* @sample kotlinx.datetime.test.samples.LocalDateTimeSamples.dateComponents
*/
public val day: Int

/** @suppress */
@Deprecated("Use the 'day' property instead", ReplaceWith("day"), level = DeprecationLevel.WARNING)
public val dayOfMonth: Int

/**
Expand Down Expand Up @@ -383,6 +385,52 @@ public expect class LocalDateTime : Comparable<LocalDateTime> {
public override fun toString(): String
}

/**
* @suppress
*/
@Deprecated(
"Use the constructor that accepts a 'month' and a 'day'",
ReplaceWith("LocalDateTime(year = year, month = monthNumber, day = dayOfMonth, hour = hour, minute = minute, second = second, nanosecond = nanosecond)"),
level = DeprecationLevel.WARNING
)
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@LowPriorityInOverloadResolution
public fun LocalDateTime(
year: Int,
monthNumber: Int,
dayOfMonth: Int,
hour: Int,
minute: Int,
second: Int = 0,
nanosecond: Int = 0,
): LocalDateTime = LocalDateTime(
year = year, month = monthNumber, day = dayOfMonth,
hour = hour, minute = minute, second = second, nanosecond = nanosecond
)

/**
* @suppress
*/
@Deprecated(
"Use the constructor that accepts a 'day'",
ReplaceWith("LocalDateTime(year = year, month = month, day = dayOfMonth, hour = hour, minute = minute, second = second, nanosecond = nanosecond)"),
level = DeprecationLevel.WARNING
)
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@LowPriorityInOverloadResolution
public fun LocalDateTime(
year: Int,
month: Month,
dayOfMonth: Int,
hour: Int,
minute: Int,
second: Int = 0,
nanosecond: Int = 0,
): LocalDateTime = LocalDateTime(
year = year, month = month, day = dayOfMonth,
hour = hour, minute = minute, second = second, nanosecond = nanosecond
)

/**
* Formats this value using the given [format].
* Equivalent to calling [DateTimeFormat.format] on [format] with `this`.
Expand Down
35 changes: 31 additions & 4 deletions core/common/src/LocalTime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import kotlinx.datetime.format.*
import kotlinx.datetime.serializers.LocalTimeIso8601Serializer
import kotlinx.datetime.serializers.LocalTimeComponentSerializer
import kotlinx.serialization.Serializable
import kotlin.internal.*


/**
Expand Down Expand Up @@ -364,8 +365,21 @@ public fun String.toLocalTime(): LocalTime = LocalTime.parse(this)
*
* @sample kotlinx.datetime.test.samples.LocalTimeSamples.atDateComponentWiseMonthNumber
*/
public fun LocalTime.atDate(year: Int, monthNumber: Int, dayOfMonth: Int = 0): LocalDateTime =
LocalDateTime(year, monthNumber, dayOfMonth, hour, minute, second, nanosecond)
public fun LocalTime.atDate(year: Int, month: Int, day: Int = 0): LocalDateTime =
LocalDateTime(year, month, day, hour, minute, second, nanosecond)

/** @suppress */
@Deprecated(
"Use the overload that accepts a 'month' and a 'day' instead",
ReplaceWith("this.atDate(year = year, month = monthNumber, day = dayOfMonth)"),
DeprecationLevel.WARNING
)
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@LowPriorityInOverloadResolution
public fun LocalTime.atDate(year: Int, monthNumber: Int, dayOfMonth: Int, fakeArgument: Unit = Unit): LocalDateTime =
fakeArgument.let {
LocalDateTime(year, monthNumber, dayOfMonth, hour, minute, second, nanosecond)
}

/**
* Combines this time's components with the specified date components into a [LocalDateTime] value.
Expand All @@ -375,8 +389,21 @@ public fun LocalTime.atDate(year: Int, monthNumber: Int, dayOfMonth: Int = 0): L
*
* @sample kotlinx.datetime.test.samples.LocalTimeSamples.atDateComponentWise
*/
public fun LocalTime.atDate(year: Int, month: Month, dayOfMonth: Int = 0): LocalDateTime =
LocalDateTime(year, month, dayOfMonth, hour, minute, second, nanosecond)
public fun LocalTime.atDate(year: Int, month: Month, day: Int = 0): LocalDateTime =
LocalDateTime(year, month, day, hour, minute, second, nanosecond)

/** @suppress */
@Deprecated(
"Use the overload that accepts a 'month' and a 'day' instead",
ReplaceWith("this.atDate(year = year, month = month, day = dayOfMonth)"),
DeprecationLevel.WARNING
)
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@LowPriorityInOverloadResolution
public fun LocalTime.atDate(year: Int, month: Month, dayOfMonth: Int, fakeArgument: Unit = Unit): LocalDateTime =
fakeArgument.let {
LocalDateTime(year, month, dayOfMonth, hour, minute, second, nanosecond)
}

/**
* Combines this time's components with the specified [LocalDate] components into a [LocalDateTime] value.
Expand Down
Loading

0 comments on commit 8885ea5

Please sign in to comment.