DEV Community

Discussion on: How a calculation of previous month in golang can break production

Collapse
 
pochmurnygrzech profile image
Grzegorz Kotlarz

Hello, thanks for your input 😊 Interesting to see how other languages work! Also, thanks for your clarification on why it happens - I forgot to write it in the post.

About the correctness - from my perspective, there is no easy way to tell which of the outputs is correct. Based on my experience from Python and C#, I've expectations that GoLang will produce the same output. I'm not blaming any of the languages, cause, for me, there is no correct answer 🤷‍♂️ There is only an assumption of language/library creator, and I wrote this post to aware other programmers.

BTW - Interesting things happen when you are subtracting from 31.05.2021 and, immediately, adding a one month to the previous calculation - neither in C# nor Go, you are not back to 31.05.2021. You will be at 30.05.2021, or at 1.06.2021.
Examples:
play.golang.org/p/rd1xjc1CbKJ
dotnetfiddle.net/fTO9IX

Collapse
 
glavic profile image
Glavić

1.6. is correct when calculating overflow dates into equation.
31.5. minus 1 month is 31.4. whish is overflown by 1 day, so this becomes 1.5.
And then you add 1 month on 1.5. which becomes 1.6. This is expacted bahavious in Go and PHP. Sorry I don't know why python and C# are doing that way :(

Thread Thread
 
glavic profile image
Glavić • Edited

On other hand, PostgreSQL and MySQL both return 30.4. on 31.5.-month.

MySQL:

select date_add("2021-05-30", interval -1 month)
Enter fullscreen mode Exit fullscreen mode

PostgreSQL:

select '2021-05-31'::timestamp - '1 month'::interval
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
pochmurnygrzech profile image
Grzegorz Kotlarz • Edited

Very thanks for your input and curiosity. I also dig deeper into other languages. Ruby and Java behave like C#.

Interesting thing happens in Rust, where you don't have a method to add or subtract months. You can however do something like this:

    let end_of_april = NaiveDate::from_ymd(end_of_may.year(), end_of_may.month() - 1, end_of_may.day());
Enter fullscreen mode Exit fullscreen mode

and it... panics because of the out-of-range date. You can check the snippet

I ran onto it here.

Thread Thread
 
glavic profile image
Glavić

This is really interesting, that one language decided to overflow in positive and other into negative days... So when developing we must be familiar with this and act accordingly. Tnx for the overview in other languages.