-
-
Notifications
You must be signed in to change notification settings - Fork 11
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
1ab2dde
d1b67a4
a824e7b
1e07e0e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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? | ||
|
||
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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the last commit, I used |
||
|
||
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(); | ||
} | ||
|
||
|
||
|
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
# Conversion between types | ||
|
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 🤔
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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 :)