xhit / go-str2duration

Convert string to duration in golang
BSD 3-Clause "New" or "Revised" License
101 stars 7 forks source link

Proposal: Support parsing month #1

Open lylex opened 4 years ago

lylex commented 4 years ago

When I have a duration "1M", I need to parse it as "1 month". I hope to add this feature.

xhit commented 4 years ago

A month is not a fixed time like weeks, days and patterns below them.

A solution is suppose that a month is a fixed 30 days, but this doesn't seem right.

ghost commented 4 years ago

I have the same issue for months and years ^^ Must be a solution for managing that... I am thinking about it.

xhit commented 4 years ago

I will open the issue for proposals.

How many days in a month can be set before the parse because month is not fixed, same with year that can be leap.

xhit commented 3 years ago

one month default value is:30

And how to convert 1+ months? This package is for duration, so If user want a duration of three months, the expect, for example, from January 1 to April 1, using 30 or 31 fixed days cannot solve this.

gabrielmocan commented 1 year ago

@xhit What about Rust's approach? https://docs.rs/parse_duration/latest/parse_duration/

"Years are defined using the average over 400 years in the Gregorian calendar. As such, a year is equivalent to 365.2425 days. A month is defined as one twelfth of a year."

gabrielmocan commented 1 year ago

And for those wondering what's the basis of 400 years, it is a full gregorian calendar cycle.

"Calendar cycles repeat completely every 400 years, which equals 146,097 days.[1][2] Of these 400 years, 303 are regular years of 365 days and 97 are leap years of 366 days. A mean calendar year is 365+97/400 days = 365.2425 days, or 365 days, 5 hours, 49 minutes and 12 seconds.[3]"

xhit commented 1 year ago

Hi, sorry for delay and sorry for grammar mistakes, I'm learning English.

@gabrielmocan the actual calendar cycle has a desfase, we need to add a day every 3300 years. With duration we need to be precise and simple, so the Gregorian calendar can be used, but isn't perfect enough.

Using continued fraction we can get that a more precise and simple, so a mathematical calendar is 365+1211/5000. This has 1 day of desfase every 800,000 years, only we need to change the rule a little:

A leap year is when divisible by 4, except when ends in 00 and can be divisible by 500. And if the year is divisible by 5000 add two days

But the real problem here is: what to expect if the duration is 1y, the mathematical calendar, the Gregorian or exactly one human year (same day, hour, minute, second changing only the year)? Do we need to specify it in the duration with a method?

@baoyachi I can see that one month is fixed 30 days, and 1 year is fixed 365. Am I correct? If yes, I think it's fine to leave that to the devs, if they aren't ok with that they can add or subtract to the duration and make the package simple.

gen2thomas commented 1 year ago

this approach @gabrielmocan mentioned (year = 365.25 days, month = 30.44 days) is also used by "systemd", see https://man7.org/linux/man-pages/man7/systemd.time.7.html

so IMO this would be a generally accepted solution, at least as a default

what to expect if the duration is 1y

my answer: this depends on the given offset and should be handled by the Add method. Maybe some tests with the function Sub can clarify some open questions.