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

Adding info to the arithmetic section! #12

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
105 changes: 105 additions & 0 deletions src/api/arithmetic.md
Original file line number Diff line number Diff line change
@@ -1 +1,106 @@
# Arithmetic

Let's suppose you are creating an finance app for people who are above 18 years old. Normally, instead of asking the age itself, you would ask for the birthdate to track the age evolution, rigth?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Age may not be the best example, as all years are not the same length. Perhaps something occurring every so many days of weeks?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. What do you think about calculating the next payment date of a monthly subscription?

We could add an example of adding 30 days in a date, considering different date lengths. We could also consider when the current month is December and the result would be a date in the next year to show how to handle these "corner" cases.

I'm thinking of using Duration to add the amount of days in a Date object with the .add_days()

What are your thoughts on that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe calculating the date of arrival of an online purchase 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arrival for a purchase would work! That's something that wouldn't care about the lengths of months/years.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! I'll come up with an example and we can work upon that :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just commited the change in the example :)


In order to know the user age, you would get the today's date and subtract the user birthdate. That's sounds possible, but a little verbose for you to write it yourself. Fortunately, the `time` crate has you covered. Let's jump into that!

First, let's consider the user input being `"2000-30-10"`. This input need to be parsed to the `Date` type. The parsing feature needs to be explicited stated in your `Cargo.toml` file, otherwise it won`t work. Here is an example:

```rust
//Cargo.toml file
Rottschaefer marked this conversation as resolved.
Show resolved Hide resolved

[dependencies]
time = { version = "0.3", features = ["parsing"] }
```

Now we can import the `Date` with the parsing feature. We'll need a parsing type as well and we're going to use `Iso8601` in this one. Do not feel attached to the formatting now, you can change it later and this will be stated later in this book!

And, finally, we will use the OffsetDateTime to get the current date. Here we go then:

```rust
use time::{Date, OffsetDateTime};
use time::format_description::well_known::Iso8601;

fn get_age() {

let current_date = OffsetDateTime::now_utc().date();
let user_birthdate = Date::parse("2000-10-30", &Iso8601::DATE).unwrap();

}
```

Let's recap. In this code we are `OffsetDateTime::now_utc()` to get the current date with the timestamp and using the method `.date()` to select only the date itself in order to get the same format as our user input.

Now we have to take the `user_birthdate` from the `current_date` in order to know the age gap between these two dates. Here is how we are going to do that:

```rust
let gap_seconds = (current_date - user_birthdate).whole_seconds();
```

When we do `current_date - user_birthdate` we get an `Duration` type. You can take out the `.whole_seconds` method and see the output in the terminal:

```console
Finished dev [unoptimized + debuginfo] target(s) in 0.73s
Running `target\debug\rust_test.exe`

Duration {
seconds: 739411200,
nanoseconds: 0,
}
```

And then we use the `.whole_seconds` to get the gap between the dates in seconds. Now we just have to convert this in years. That`s the easy part! We just have to calculate how many seconds there are in a year and divide the gap we found by this number of seconds.

```rust

const SECONDS_PER_YEAR: i64 = 365*24*60*60;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once changed to days or weeks, constants like this can be avoided by utilizing the time::convert module. Alternatively, the duration itself can be divided by another duration, such as foo / Duration::WEEK.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the last commit, I used let time_to_deliver: Duration = 45*(Duration::DAY) . That's was what you meant?


let years = gap_seconds/SECONDS_PER_YEAR;

```

Knowing how many years our user has, we can use the a simple `if else` clause to tell him if he can open an account in our app:

```rust

if years >= 18{
println!("You're {years} years old and able to open an account :)");
}
else{
println!("You're only {years} years old. To open an account, you have to have at least 18 years old");
}


```

Here is the complete code :)

```rust

use time::{Date, OffsetDateTime};
use time::format_description::well_known::Iso8601;

fn get_age() {
const SECONDS_PER_YEAR: i64 = 365 * 24 * 60 * 60;

let user_birthdate = Date::parse("2000-10-30", &Iso8601::DATE).unwrap();
let current_date = OffsetDateTime::now_utc().date();

let gap_seconds = (current_date - user_birthdate).whole_seconds();

let years = gap_seconds / SECONDS_PER_YEAR;

if years >= 18 {
println!("You're {} years old and able to open an account :)", years);
} else {
println!("You're only {} years old. To open an account, you have to be at least 18 years old", years);
}
}

fn main() {
get_age();
}



```
1 change: 1 addition & 0 deletions src/api/conversion-between-types.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# Conversion between types