How to always show milliseconds when parsing datetime with chrono in rust? - datetime

I am trying to format a chrono::NaiveDate like this: %Y-%m-%dT%H:%M:%S%.f
According to the third example in the documentation I expected this to work like so:
use chrono::NaiveDate;
fn main() {
let date = NaiveDate::from_ymd(2015, 7, 1).and_hms_milli(0, 0, 0, 0);
println!("{}", date.format("%Y-%m-%dT%H:%M:%S%.f"));
}
However instead of the desired output 2015-07-01T00:00:00.000 this prints 2015-07-01T00:00:00.
Rust Playground is here
Apparently the milliseconds only get included, if they are not zero:
use chrono::NaiveDate;
fn main() {
let date = NaiveDate::from_ymd(2015, 7, 1).and_hms_milli(0, 0, 0, 1);
println!("{}", date.format("%Y-%m-%dT%H:%M:%S%.f"));
}
is there an option to always include them?

You can use .3f as the last specifier. This is similar to .%f but left-aligned but fixed to a length of 3
println!("{}", date.format("%Y-%m-%dT%H:%M:%S%.3f"));

Related

Memory management basics of Rust lang

i need some help with understanding of rust basics and memory basics at all. I think this will be helpful for those who come across this after me.
memory adress
(1) Here i create a function thats return pointer to a vector. Why there is two different adresses if there must be the same pointer?
fn get_pointer(vec: &[i32]) -> &[i32] {
vec
}
fn main() {
let vector = vec![1, 2, 3, 4, 5];
let first_element = get_pointer(&vector);
let vector: Vec<String> = Vec::new();
println!(
"Vector: {:p}, and func result: {:p}",
&vector, first_element
);
}
Output: Vector: 0x5181aff7e8, and func result: 0x17e5bad99b0
different adresses of one element?
(2) Now im creating a function thats return a pointer to the first element of a Vector
fn get_pointer_to_first_element(vec: &[i32]) -> &i32 {
&vec[0];
}
fn main() {
let vector = vec![1, 2, 3, 4, 5];
let first_element = get_pointer_to_first_element(&vector);
println!(
"from variable: {:p}, from function: {:p}",
&vector[0], &first_element
);
}
from variable: 0x1f9a887da80, from function: 0x15fe2ffb10
variables defined in functions
(3) Okay, i understand thats question is even more stupid, but i realy cant get it.
Here i create a pointer variable inside a function, and it must be deleted with its "value" when program leaves scope of a function, so why i can use that value after call of the function?
also bonus question about deleting value after shadowing, is that true? Why?
fn get_pointer_to_first_element(vec: &[i32]) -> &i32 {
let pointer = &vec[0];
pointer
} // here variable "pointer" and its value must be deleted, isn't it? how then i can operate it after calling a function?
fn main() {
let vector = vec![1, 2, 3, 4, 5];
let first_element = get_pointer_to_first_element(&vector);
let vector: Vec<String> = Vec::new(); // Bonus question: "vector" variable is new now, so previous must be deleted?
println!("first element is available and its {first_element}. ");
}
Vector: 0x5181aff7e8, and func result: 0x17e5bad99b0
I tried to use the same things with arrays, but result is the same.
In order:
You allocated a new vector, so of course it'll have a different address. first_element points to the original vector. It was initialized with that value and it'll keep it. Even if you had not, your function takes a slice as an argument; not a Vec. Those are different types. The Vec is itself a pointer. The slice is a separate reference to, as the name suggests, a slice of the data on the heap it points to.
fn main() {
let vector = vec![1, 2, 3];
println!(
"Normal: {:p}. Calculated /w a function: {:p}. Slice: {:p}.",
&vector,
get_vec_address(&vector),
get_slice_address(&vector)
);
// This outputs:
// Normal: 0x7fff91db1550. Calculated /w a function: 0x7fff91db1550. Slice: 0x55ddbc54a9d0.
}
fn get_vec_address(vec: &Vec<i32>) -> &Vec<i32> {
vec
}
/// `&vector` is coerced from `&Vec` into `&[i32]`.
/// To learn more about Deref coercions, go to:
/// https://doc.rust-lang.org/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods
fn get_slice_address(slice: &[i32]) -> &[i32] {
slice
}
Run this snippet on Rust Playground. See this cheat sheet on containers for a visual explanation.
As the comment says, you're taking the reference of a reference.
pointer isn't dropped. It's moved as the return value. To get a better understanding of scope, you might want to review the chapters on scope and lifetimes.
As for your bonus question, shadowing a variable doesn't drop it. It'll still live to the end of the scope. If there are existing references to it, it can still be used. For example, this is valid code:
fn main() {
let vector = vec![1, 2, 3];
let first_element = &vector[0];
let vector = vec![4, 5, 6];
println!("{first_element}");
println!("{vector:?}");
// This will print:
// 1
// [4, 5, 6]
}
Run this snippet on Rust Playground.

How to get Timestamp of the current Date and time in Rust

I simply want to retrieve the current Time and Date and store it in a variable.
For this, I tried to use the chrono::DateTime.
In the documentation I found this:
use chrono::{DateTime, TimeZone, NaiveDateTime, Utc};
let dt = DateTime::<Utc>::from_utc(NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11), Utc);
This lets me store a specific Date and Time but I couldn't figure out how to retrieve the actual current date and time and put it in my DateTime-Variable.
Use rust, use it now:
use chrono;
fn main() {
println!("{:?}", chrono::offset::Local::now());
println!("{:?}", chrono::offset::Utc::now());
}
To answer the question in the title of how to get the current timestamp:
use chrono::Utc;
let dt = Utc::now();
let timestamp: i64 = dt.timestamp();
println!("Current timestamp is {}", timestamp);
Standart Rust timestamp method:
use std::time::SystemTime;
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis(); // See struct std::time::Duration methods
println!("{}", now);

Not understanding how to access the elements of a vector in Rust [duplicate]

This question already has answers here:
Why does printing a pointer print the same thing as printing the dereferenced pointer?
(2 answers)
Closed 4 years ago.
This is my first encounter with Rust, and I am reading the chapter on vectors in the current version of the Rust Book. I do have previous experience with other languages (mostly functional ones, where the following issues are hidden).
Running the following code snippet (from the book) returns 3:
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("{}", third);
}
The first thing that I do not understand is why the third inside the println! macro isn't referenced. I would have expected the above code to print the memory address of the 3rd element of v (as in C and C++), not its content.
Consider now the code (notice the reference this time inside println!):
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("{}", *third);
}
Why does the code code above produce exactly the same output as the one above it, as if the * made no difference?
Finally, let us rewrite the above code snippets eliminating references completely:
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: i32 = v[2];
println!("{}", third);
}
Why does this last version produce the same output as the previous two? And what type does v[2] really have: is it an &i32 or an i32?
Are all of the above a manifestation of the automatic dereferencing that is only once alluded to in a previous chapter? (If so, then the book should be rewritten, because it is more confusing than clarifying.)
Disclaimer: I'm learning Rust too, so please take this with a grain of salt.
To understand what happens, it might be easier with cargo-expand.
For the code
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("{}", third);
}
we get (I've removed irrelevant codes)
fn main() {
...
let third: ...
{
::io::_print(::std::fmt::Arguments::new_v1_formatted(
...
&match (&third,) {
(arg0,) => [::std::fmt::ArgumentV1::new(arg0, ::std::fmt::Display::fmt)],
},
...
));
};
}
for the first/last case, and
fn main() {
...
let third: ...
{
::io::_print(::std::fmt::Arguments::new_v1_formatted(
...
&match (&*third,) {
(arg0,) => [::std::fmt::ArgumentV1::new(arg0, ::std::fmt::Display::fmt)],
},
...
));
};
}
for the second case.
Which, roughly, means that, for {} formatter, the function fmt (of the trait Display) will be called for a reference to third or *third respectively.
Let's apply this logic for
second case: third: &i32 then *third: i32, this is where impl Display for i32 applies.
first case: third: &i32, this works also because of impl<'_, T> Display for &'_ T (where T is i32)
last case: third: i32: is the same as the first case. Moreover, v[2] (which is of type i32) works because impl Index for Vec (note that: let third = v[2] works because impl Copy for i32, i.e copy semantics is applied for = instead of the default move semantics).

Appending to a slice with enough capacity using value receiver

can someone help me understand what happens here?
package main
import (
"fmt"
)
func appendString(slice []string, newString string) {
slice = append(slice, newString)
}
func main() {
slice := make([]string, 0, 1)
appendString(slice, "a")
fmt.Println(slice)
}
I know about the slice header and the need to use a pointer receiver. But here, as the underlying array has enough capacity I would expect append to work anyways (just adding the new value to the underlying array and the original [copied] header working as expected)
What is wrong with my assumptions?
Let's add a final print statement to see the result:
slice := make([]string, 0, 1)
fmt.Println(cap(slice))
appendString(slice, "a")
fmt.Println(slice)
And the output will be (try it on the Go Playground):
1
[]
Which is correct. One could expect the output to be:
1
[a]
The reason why this is not the case is because even though a new backing array will not be allocated, the slice header in the slice variable inside main() is not changed, it will still hold length = 0. Only the slice header stored in the slice local variable inside appendString() (the parameter) is changed, but this variable is independent from main's slice.
If you were to reslice main's slice, you will see that the backing array does contain the new string:
slice := make([]string, 0, 1)
fmt.Println(cap(slice))
appendString(slice, "a")
fmt.Println(slice)
slice = slice[:1]
fmt.Println(slice)
Now output will be (try it on the Go Playground):
1
[]
[a]
This is why the builtin append() has to return the new slice: because even if no new backing array is needed, the slice header (which contains the length) will have to be changed (increased) if more than 0 elements are appended.
This is why appendString() should also return the new slice:
func appendString(slice []string, newString string) []string {
slice = append(slice, newString)
return slice
}
Or short:
func appendString(slice []string, newString string) []string {
return append(slice, newString)
}
Which you have to reassign where you use it:
slice := make([]string, 0, 1)
fmt.Println(cap(slice))
slice = appendString(slice, "a")
fmt.Println(slice)
And then you get the expected outcome right away (try it on the Go Playground):
1
[a]

How do I convert a vector of strings to a vector of integers in a functional way?

I'm trying to convert Vec<&str> to Vec<u16> but I can't figure out a functional way to do it.
let foo: &str = "1,2,3"; // Parsing a string here
let bar: Vec<&str> = foo.split(",").collect(); // Bar is a nice vector of &str's
I need to get bar into a Vec<u16>.
There's an iterator adapter map! You'd use it like this:
let bar: Vec<u16> = foo.split(",").map(|x| x.parse::<u16>().unwrap()).collect();
parse is a library function that relies on the trait FromStr, and it can return an error, so we need to unwrap() the error type. (This is a good idea for a short example, but in real code, you will want to handle the error properly - if you have a value that's not a u16 there, your program will just crash).
map takes a closure that takes it's parameter by value and then returns the iterator obtained by lazily applying that function. You're collecting all of the values here, but if you only take(5) of them, you would only parse 5 of the strings.
You haven't fully specified your problem. Specifically, what should happen when one of the strings cannot be parsed into a number? When you parse a number from a string using parse, it can fail. That is why the function returns a Result:
fn parse<F>(&self) -> Result<F, F::Err>
where
F: FromStr,
Here's a solution that takes the vector, gets an iterator with iter, changes each item using map and ultimately returns a Result using collect. If the parsing was a success, you get an Ok. If any failed, you get an Err:
fn main() {
let input = "1,2,3";
let strings: Vec<_> = input.split(",").collect();
let numbers: Result<Vec<u16>, _> = strings.iter().map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
Or you could remove failed conversions by filtering out Err values with flat_map:
fn main() {
let input = "1,2,3";
let strings: Vec<_> = input.split(",").collect();
let numbers: Vec<u16> = strings.iter().flat_map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
Of course, it's a bit silly to convert the string into a vector of strings and then convert it again to a vector of integers. If you actually have a comma-separated string and want numbers, do it in one go:
fn main() {
let input = "1,2,3";
let numbers: Result<Vec<u16>, _> = input.split(",").map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
See also:
Why does `Option` support `IntoIterator`?
My take as someone not really experienced in Rust yet.
fn main() {
let foo: &str = "1,2,3"; // Parsing a string here
let bar: Vec<&str> = foo.split(",").collect(); // Bar is a nice vector of &str's
// here the magic happens
let baz = bar.iter().map(|x| x.parse::<i64>());
for x in baz {
match x {
Ok(i) => println!("{}", i),
Err(_) => println!("parse failed"),
}
}
}
Note that since parse returns a Result, you have to extract the value from each parsed element. You might want to behave in a different way, e.g. filter only the succeeded results.

Resources