Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Substitute for YearMonth? #168

Open
boswelja opened this issue Dec 21, 2021 · 16 comments
Open

Substitute for YearMonth? #168

boswelja opened this issue Dec 21, 2021 · 16 comments
Labels
breaking change This could break existing code
Milestone

Comments

@boswelja
Copy link

java.time has a YearMonth class for referring to a particular month in the year, what's the kotlinx-datetime equivalent? LocalDate also stores a day of the month which isn't ideal

@elizarov
Copy link
Contributor

data class YearMonth(val year: Int, val month: Int) should do the trick.

@dkhalanskyjb
Copy link
Contributor

data class YearMonth(val year: Int, val month: Month)

for additional type safety.

@boswelja
Copy link
Author

Well yes, but I think it would be nice for the library to provide it out of the box. Wouldn't you agree?

@dkhalanskyjb
Copy link
Contributor

Do you need this to support any operations that would meaningfully interact with the rest of the library? What functionality would you want from such a class?

@boswelja
Copy link
Author

Things like isLeapYear and isValidDay are handy, but proper support for plus and minus operations would be great.

@dkhalanskyjb
Copy link
Contributor

  • isValidDay is fairly straightforward: just attempt to construct a LocalDate. Failure means either that the year is very far away, or that the day is invalid. We wouldn't introduce a new data structure just for that unless we expected that it is common for people to know the year and the month and want to check several days-of-month for whether they are valid. Can you think of a popular use case for this?
  • Could you clarify what use you have for isLeapYear? In any case, it doesn't look like YearMonth is a good place for isLeapYear (the month is not relevant at all).
  • What do you plan to use plus and minus for? Of everything listed, a compelling use case for them would be the strongest argument for introducing a YearMonth. I'm interested in high-level details about the problem area, like "I have a calendar app with an exciting new feature: ZZZ. For that, I need to be able to have a YearMonth object and add years and months to it".

@boswelja
Copy link
Author

I agree isValidDate is pretty simple to implement myself, but if I'm importing a date/time library I don't expect to need my own implementation (plus there's probably a nicer way to do it instead of catching LocalDate construction).

isLeapYear probably doesn't have many practical uses, I can see why it makes sense to not include it in a YearMonth and it's possibly too niche to implement.

Funnily enough my use case is a calendar with a month view that the user can swipe through. The current implementation takes a start and end YearMonth and creates it's data by iterating from start to end via plusMonths(1). Having a YearMonth with at least plus is a must for my current approach.

@wkornewald
Copy link
Contributor

See also my early draft PR #173 which could be the starting point for arbitrary precision date handling and type safety via sealed interfaces. Medical data comes with date fields containing Year or YearMonth or other arbitrary precision levels (within one single field) and we need to parse, display, sort, compare, etc. such values.

It would be great to have that use-case supported in this lib instead of having everyone reinvent the wheel.

@boswelja
Copy link
Author

Any updates on this? I'm happy to get something together in a PR, just need to know if it's something the maintainers want to go ahead with

@morki
Copy link

morki commented Mar 21, 2023

Another use case for me would be:

  • default serialization format YYYY-MM for kotlinx.serialization implemented like for other temporal classes
  • ability for other kotlin libraries (database, serialization, http frameworks, html <input type="month"> MDN etc.) to standardize on one implementation and cooperate

@dkhalanskyjb
Copy link
Contributor

@morki, this does not explain why this would be useful. Sure, if YearMonth is useful, serialization for it is also useful, and it would be good for the other things to standardize, but why is it useful?

@morki
Copy link

morki commented Mar 21, 2023

For me only as a standardized wrapper with "well known" serialization. For example for parsing <input type="month"> posted in HTTP server etc. From functional point o view, I only use methods like YearMonth.startOfMonth(): LocalDate and YearMonth.endOfMonth(): LocalDate for range filtering in database.

The other useful common type is YearWeek (also <input type="week">). But I understand your position. I just tried to write what I was feeling. Thank you for this awesome library :)

@dkhalanskyjb
Copy link
Contributor

We don't yet have a position to understand, or this issue would be closed one way or another. You're using <input type="month">, but what does it represent, why is <input type="month"> used? The example shown in the Mozilla documentation is "What month were you born in?", which is a question I personally have never seen in the wild, and as a selector used to display the month in a calendar.

Also, ISO 8601 describes serialization for this: 2023-03, basically the initial part of the ISO 8601 date.

@GrahamBorland
Copy link

GrahamBorland commented Mar 21, 2023

Calendars, finance apps (your monthly bank statement), fitness apps (you ran how far this month?), sales reports... the concept of a specific month in a specific year is ubiquitous.

@dkhalanskyjb dkhalanskyjb added the breaking change This could break existing code label Dec 1, 2023
@SteinerOk
Copy link

Relevant for me.
My use case: thermal energy billing system. Our billing period is a month of the year, based on this we take the number of days in a month and multiply by 24 and get the “service provision time” and then carry out calculations...

@dkhalanskyjb dkhalanskyjb modified the milestones: 0.9.0, 0.7.0 Apr 12, 2024
@dalewking
Copy link

As a team transitioning away from Klock, I do make use of its YearMonth type and have been wanting a replacement for it.

plus and minus for number of months is vital. Having it handle the fact that adding a month and having it take care of incrementing the years without having to handle this yourself is part of the usefulness.

Some useful properties from Klock's implementation is number days in the month, number of days from the start of the year to the start of the month and number of days from end of month to end of year.

We have a schedule part of our app. It may be showing a day, week, or month. When we load the data we load the given month, the previous month, and the next month. We cache the data loaded using the YearMonth as the key to the cache. So the current date is basically a Date that corresponds to the day in day mode or the first day of the week in week mode. With YearMonth i can just say something of the form:

                    getScheduleData(
                        date.yearMonth - 1.months,
                        date.yearMonth + 1.months,
                    )

I can't say the class is absolutely necessary. The alternative would be to use a LocalDate that is the first day of the month. YearMonth is just more convenient and doesn't cost a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change This could break existing code
Projects
None yet
Development

No branches or pull requests

9 participants