How do I convert a chrono `DateTime<UTC>` instance to `DateTime<Local>`? - datetime

My goal is to convert utc into loc:
use chrono::{Local, UTC, TimeZone};
let utc = chrono::UTC::now();
let loc = chrono::Local::now();
println!("{:?}", utc);
println!("{:?}", loc);
println!("{:?}", utc.with_timezone(&Local));
println!("{:?}", Local.from_utc_datetime(&utc.naive_local()));
... which produced the following output:
2015-02-26T16:22:27.873593Z
2015-02-26T17:22:27.873663+01:00
2015-02-26T15:22:27.873593+00:00
2015-02-26T15:22:27.873593+00:00
The loc time shown in the second row is what I want to see when converting utc.
How do I properly convert a DateTime<UTC> instance to DateTime<Local>?
Meta
I am using chrono 0.2.2. In the DateTime.from_utc method it's even telling me I should use the TimeZone trait. However, I am missing something.

Starting with chrono 0.4.7 you can convert them between with using from trait in a simpler way:
use chrono::prelude::*;
fn main() {
let utc = Utc::now();
let local = Local::now();
let converted: DateTime<Local> = DateTime::from(utc);
}

Oops, thank you for reporting. This is a bug and registered as the issue #26. This should be fixed in Chrono 0.2.3.
Besides from the bug, utc.with_timezone(&Local) is indeed a correct way to convert to the local time. There is an important identity that utc.with_timezone(&Local).with_timezone(&UTC) should be equal to utc (except for the exceptional case, where the local time zone has been changed).

Related

How can I display chrono DateTime without fractional seconds?

If I print the current time directly, it includes many trailing decimals:
println!("{:?}", chrono::offset::Utc::now());
2022-12-01T07:56:54.242352517Z
How can I get it to print like this?
2022-12-01T07:56:54Z
You can use to_rfc3339_opts. It accepts arguments for the format of the seconds and if the Z should be present.
let time = chrono::offset::Utc::now();
let formatted = time.to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
println!("{:?}", time); // 2022-12-01T08:32:20.580242150Z
println!("{}", formatted); // 2022-12-01T08:32:20Z
Rust Playground

Chrono DateTime from u64 unix timestamp in Rust

How does one convert a u64 unix timestamp into a DateTime<Utc>?
let timestamp_u64 = 1657113606;
let date_time = ...
There are many options.
Assuming we want a chrono::DateTime. The offset page suggests:
Using the TimeZone methods on the UTC struct is the preferred way to construct DateTime instances.
There is a TimeZone method timestamp_millis_opt we can use.
use chrono::{TimeZone, Utc};
let timestamp_i64 = 1657113606;
let date_time = Utc.timestamp_millis_opt(timestamp_i64).unwrap();
Another option uses the appropriately named from_timestamp_millis method, but needs more code to do it if you want DateTime instead of NaiveDateTime.
use chrono::{DateTime, NaiveDateTime, Utc};
let timestamp_i64 = 1657113606;
let naive_date_time = NaiveDateTime::from_timestamp_millis(timestamp_i64).unwrap();
let date_time = DateTime::<Utc>::from_utc(naive_date_time, Utc);

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);

How can I round a chrono::Datetime to the nearest second?

I want to get the current time rounded to the nearest second using the chrono crate but I don't know how to strip or round the result of
chrono::UTC.now().
It doesn't seem like there are any operations to modify an existing `DateTime.
chrono::UTC.now()
Returns: 2019-05-22T20:07:59.250194427Z
I want to get: 2019-05-22T20:07:59.000000000Z
How would I go about doing that in the most efficient way without breaking up the DateTime value into its components and recreating it?
Use the round_subsecs method with 0 as an argument.
use chrono::prelude::*;
fn main() {
let utc: DateTime<Utc> = Utc::now().round_subsecs(0);
println!("{}", utc);
}
The result is:
2019-05-22 20:50:46 UTC

Why is time in Go printed differently in a struct?

I'm just starting out with Go, and in the first program I wrote I printed out a struct, which also showed
{wall:0 ext:63533980800 loc:<nil>}
Being puzzled over what that was it seemed to be a type time.Time(), and a google search brought me to this part of the Go source code in which the difference between the "wall clock" and the "monotonic clock" is explained in the comments.
So to test it in isolation I created a new minimalistic program:
package main
import (
"fmt"
"time"
)
type TheStruct struct {
the_time time.Time
}
func main() {
the_struct := TheStruct{time.Now()}
fmt.Println(the_struct)
fmt.Printf("%+v\n", the_struct)
fmt.Println(the_struct.the_time)
fmt.Println()
the_struct_2 := TheStruct{time.Unix(1505099248, 200)}
fmt.Println(the_struct_2)
fmt.Printf("%+v\n", the_struct_2)
fmt.Println(the_struct_2.the_time)
}
which prints out the following:
{{13719544904843884912 534246 0x1140680}}
{the_time:{wall:13719544904843884912 ext:534246 loc:0x1140680}}
2017-09-11 05:08:11.35635032 +0200 CEST m=+0.000534246
{{200 63640696048 0x1140680}}
{the_time:{wall:200 ext:63640696048 loc:0x1140680}}
2017-09-11 05:07:28 +0200 CEST
So I wonder about two things here:
Why is the time if part of a struct printed as wall clock as compared to the more usual datetime notation when printed out separately (using the_struct.the_time)?
Is it a problem that the code in my other program prints out <nil> for the loc? How would I be able to solve that?
The reason why it's not printing the formatted time when in your struct is that String method is not invoked on the unexported fields (refer https://golang.org/pkg/fmt/):
When printing a struct, fmt cannot and therefore does not invoke
formatting methods such as Error or String on unexported fields.
Changing your structure to export fields (capitalizing the first letter) makes it invoke the String method:
package main
import (
"fmt"
"time"
)
type TheStruct struct {
The_time time.Time
}
func main() {
the_struct := TheStruct{time.Now()}
fmt.Println(the_struct)
fmt.Printf("%+v\n", the_struct)
fmt.Println(the_struct.The_time)
fmt.Println()
the_struct_2 := TheStruct{time.Unix(1505099248, 200)}
fmt.Println(the_struct_2)
fmt.Printf("%+v\n", the_struct_2)
fmt.Println(the_struct_2.The_time)
}
Output:
{2009-11-10 23:00:00 +0000 UTC m=+0.000000000}
{The_time:2009-11-10 23:00:00 +0000 UTC m=+0.000000000}
2009-11-10 23:00:00 +0000 UTC m=+0.000000000
{2017-09-11 03:07:28.0000002 +0000 UTC}
{The_time:2017-09-11 03:07:28.0000002 +0000 UTC}
2017-09-11 03:07:28.0000002 +0000 UTC
On playground : https://play.golang.org/p/r0rQKBlpWc
The other answer covers the first part of your question quite well, so I will only cover the second part here.
To put it simply, no, a nil location is not a problem, as acording to the source code for time.Time, a nil location means UTC.
// loc specifies the Location that should be used to
// determine the minute, hour, month, day, and year
// that correspond to this Time.
// The nil location means UTC.
// All UTC times are represented with loc==nil, never loc==&utcLoc.
loc *Location

Resources