chronotope / chrono-tz Goto Github PK
View Code? Open in Web Editor NEWTimeZone implementations for rust-chrono from the IANA database
License: Other
TimeZone implementations for rust-chrono from the IANA database
License: Other
Hi.
chrono-tz contains the Olson TZ data (at least, AFAICT, it does on crates.io, although it's not in git). No doubt this is good for Windows where the OS does not provide sensible timezone data.
But on Unix, the OS provides the Olson TZ database directly, generally in /usr/share/zoneinfo. OS updates update it. On Unix it is not right that Rust programs should end up with the timezone data embedded into the program, because if governments change the clocks (which they have been known to do at very short notice) this should be handled by an OS update, not by having to give everyone rebuilt Rust binaries.
So it seems to me that on Unix, chrono-tz should (by default at least) only use data from the OS installed timezone database. Would you be amenable to something like this? It seems to me that the default behaviour should be controlled by a feature flag.
I think implementing this needs an impl of TimeZone
for &[parse_zoneinfo::ZoneInfo]
, or something along those lines.
Ran into an issue in bspeice/dtparse#18 where I can't retrieve a FixedOffset
even after parsing a Tz
because TzOffset
isn't exported in the public API (despite itself being marked public). Is there a better way for me to build a FixedOffset
struct given a Tz
? Or should I refactor my methods to take impl Timezone
or similar?
Hi,
I have been investigating how to use this crate in the context of jorgecarleitao/arrow2#23, but have faced the challenge whereby our crate declares timezones as strings, while this one uses compile time timezones.
A simple exercise I am trying to achieve is to write the following function:
fn add_days(timestamps: Vec<i64>, timezone: &str, days: i64) -> Vec<i64>
where i64
is a timestamp represented in timezone
. Do I need to match
timezone to perform this calculation?
When I try to use chrono-tz on Windows I get the following error:
Compiling datetime v0.4.4
error[E0432]: unresolved import `system::sys_time`
--> C:\Users\TWB\.cargo\registry\src\github.com-1ecc6299db9ec823\datetime-0.4.4\src\cal\datetime.rs:15:5
|
15 | use system::sys_time;
| ^^^^^^^^^^^^^^^^ no `sys_time` in `system`
error[E0432]: unresolved import `system::sys_time`
--> C:\Users\TWB\.cargo\registry\src\github.com-1ecc6299db9ec823\datetime-0.4.4\src\instant.rs:6:5
|
6 | use system::sys_time;
| ^^^^^^^^^^^^^^^^ no `sys_time` in `system`
error: aborting due to 2 previous errors
error: Could not compile `datetime`.
Investigation on the #rust-beginners channel revealed:
<@mbrubeck> Indeed, it seems to be missing that function on Windows: https://docs.rs/crate/datetime/0.4.4/source/src/system.rs
<@mbrubeck> There's one for macOS+iOS, and one for everything except (macOS, iOS, Windows).
right, so what should I do to get it to build?
<@mbrubeck> It looks like it would need a non-trivial patch to implement sys_time on Windows, though I think you could use https://github.com/rust-lang/rust/blob/master/src/libstd/sys/windows/time.rs for example code if you want to do that...
<@mbrubeck> Alternately you could try to patch https://github.com/rust-datetime/zoneinfo-compiled to work with types from std::time or chrono, instead of the datetime crate
We're deserializing some data and encountered the PST
timezone, which it doesn't appear that chrono-tz
has, although it has EST
. Does it still need to be added?
I have some code that looks like:
use chrono_tz::OffsetComponents;
...
let offset = chrono::TimeZone::offset_from_utc_datetime(&my_timezone, &utc_now);
let total_offset: chrono::Duration = offset.base_utc_offset() + offset.dst_offset();
Upon updating to 0.7, this code now breaks with:
|
151 | let total_offset: chrono::Duration = offset.base_utc_offset() + offset.dst_offset();
| ^^^^^^^^^^ method not found in `chrono_tz::timezone_impl::TzOffset`
|
::: /home/luke/.cargo/registry/src/github.com-1ecc6299db9ec823/chrono-tz-0.6.3/src/timezone_impl.rs:77:8
|
77 | fn dst_offset(&self) -> Duration;
| ---------- the method is available for `chrono_tz::timezone_impl::TzOffset` here
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
3 | use chrono_tz::timezone_impl::OffsetComponents;
|
I can't use chrono_tz::timezone_impl::OffsetComponents
because it's private.
Would detecting system timezone be appropriate addition to chrono-tz
?
The chrono
package has LocalTimezone
, but that only knows current offset and not the daylight-saving rules, so it is not sufficient for many calculations. And detecting the exact timezone is not trivial. I have found a code for it in ICU (uprv_tzname and related functions) and intend to port it to Rust.
Should this be added to chrono-tz
? I think it makes sense there.
Parsing offsets of the form +01:00
can be done with chrono
alone.
Parsing any other timezone must be done with chrono-tz
.
When we want to support the former, and optionally (i.e. via a feature gate) support the latter, it would be very useful to be able to convert chrono_tz::Tz
to chrono::FixedOffset
because it avoids having to write a generic for it.
The example code:
pub fn utf8_to_timestamp_ns(
array: &[&str],
fmt: &str,
timezone: String,
) -> Result<Vec<i64>> {
let tz: Result<chrono::FixedOffset, String> = parse_offset(timezone.as_str());
if let Ok(tz) = tz {
Ok(utf8_to_timestamp_ns_impl(array, fmt, tz))
} else {
chrono_tz_utf_to_timestamp_ns(array, fmt, timezone)
}
where chrono_tz_utf_to_timestamp_ns
:
#[cfg(feature = "chrono-tz")]
fn chrono_tz_utf_to_timestamp_ns(
array: &[&str],
fmt: &str,
timezone: String,
) -> Result<Vec<i64>> {
let tz: Option<chrono_tz::Tz> = timezone.as_str().parse().ok();
if let Some(tz) = tz {
Ok(utf8_to_timestamp_ns_impl(array, fmt, tz))
} else {
Err(ArrowError::InvalidArgumentError(format!(
"timezone \"{}\" cannot be parsed",
timezone
)))
}
}
and
fn utf8_to_timestamp_ns_impl<T: chrono::TimeZone>(
array: &[&str],
fmt: &str,
tz: T,
) -> Vec<i64>;
this code would be much simpler if utf8_to_timestamp_ns_impl
was not a generic. This is a simple example, but I find myself writing more complex examples.
Suggestion, implement Into<chrono::FixedOffset> for chrono_tz::Tz
to bridge both structs, thereby reducing the generic code over chrono::TimeZone
.
2020f is the latest release from IANA
In the Asia/Shanghai timezone, DST starts at 1986-05-04 02:00:00 local time (i.e. the time offset is +08:00 before this time, and +09:00 after this time, and the range 02:00 to 03:00 should be invalid). However, chrono-tz put the transition time at 00:00:00 instead. Demo:
use chrono::offset::TimeZone;
use chrono_tz::Asia::Shanghai;
fn main() {
for i in 0..=4 {
println!("{:02}:39 -> {:?}", i, Shanghai.ymd(1986, 5, 4).and_hms_opt(i, 39, 13));
}
}
Result:
00:39 -> None
01:39 -> Some(1986-05-04T01:39:13CDT)
02:39 -> Some(1986-05-04T02:39:13CDT)
03:39 -> Some(1986-05-04T03:39:13CDT)
04:39 -> Some(1986-05-04T04:39:13CDT)
while the expected result should be:
00:39 -> Some(1986-05-04T00:39:13CST)
01:39 -> Some(1986-05-04T01:39:13CST)
02:39 -> None
03:39 -> Some(1986-05-04T03:39:13CDT)
04:39 -> Some(1986-05-04T04:39:13CDT)
Compare with:
package main
import (
"fmt"
"time"
)
func main() {
loc, _ := time.LoadLocation("Asia/Shanghai")
for i := 0; i <= 4; i++ {
fmt.Println(i, "=>", time.Date(1986, 5, 4, i, 39, 13, 0, loc))
}
}
0 => 1986-05-04 00:39:13 +0800 CST
1 => 1986-05-04 01:39:13 +0800 CST
2 => 1986-05-04 03:39:13 +0900 CDT
3 => 1986-05-04 03:39:13 +0900 CDT
4 => 1986-05-04 04:39:13 +0900 CDT
import datetime
import dateutil.tz
tzinfo = dateutil.tz.gettz('Asia/Shanghai')
for i in range(5):
print(i, '=>', datetime.datetime(1986, 5, 4, i, 39, 13, 0, tzinfo))
0 => 1986-05-04 00:39:13+08:00
1 => 1986-05-04 01:39:13+08:00
2 => 1986-05-04 02:39:13+09:00
3 => 1986-05-04 03:39:13+09:00
4 => 1986-05-04 04:39:13+09:00
ENV['TZ'] = 'Asia/Shanghai'
0.upto(4) do |i|
puts "#{i} => #{Time.new(1986, 5, 4, i, 39, 13)}"
end
0 => 1986-05-04 00:39:13 +0800
1 => 1986-05-04 01:39:13 +0800
2 => 1986-05-04 03:39:13 +0900
3 => 1986-05-04 03:39:13 +0900
4 => 1986-05-04 04:39:13 +0900
import Foundation
let tz = TimeZone(identifier: "Asia/Shanghai")!
for i in 0...4 {
let dc = DateComponents(
calendar: .current,
timeZone: tz,
year: 1986,
month: 5,
day: 4,
hour: i,
minute: 39,
second: 13)
print("\(i) => \(dc), \(dc.isValidDate)")
}
0 => calendar: gregorian (fixed) timeZone: Asia/Shanghai (fixed) year: 1986 month: 5 day: 4 hour: 0 minute: 39 second: 13 isLeapMonth: false , true
1 => calendar: gregorian (fixed) timeZone: Asia/Shanghai (fixed) year: 1986 month: 5 day: 4 hour: 1 minute: 39 second: 13 isLeapMonth: false , true
2 => calendar: gregorian (fixed) timeZone: Asia/Shanghai (fixed) year: 1986 month: 5 day: 4 hour: 2 minute: 39 second: 13 isLeapMonth: false , false
3 => calendar: gregorian (fixed) timeZone: Asia/Shanghai (fixed) year: 1986 month: 5 day: 4 hour: 3 minute: 39 second: 13 isLeapMonth: false , true
4 => calendar: gregorian (fixed) timeZone: Asia/Shanghai (fixed) year: 1986 month: 5 day: 4 hour: 4 minute: 39 second: 13 isLeapMonth: false , true
closed.
use chrono::prelude::*;
use chrono_tz::US::Pacific;
let pacific_time = Pacific.ymd(1990, 5, 6).and_hms(12, 30, 45);
println!("size_of date time with tz = {}", ::std::mem::size_of_val(&pacific_time));
let dt = Utc.ymd(2014, 7, 8).and_hms(9, 10, 11);
println!("size_of date time = {}", ::std::mem::size_of_val(&dt));
let fixed_dt = FixedOffset::east(9 * 3600).ymd(2014, 7, 8).and_hms_milli(18, 10, 11, 12);
println!("size_of date time with fixed offset = {}", ::std::mem::size_of_val(&fixed_dt));
gives output:
size_of date time with tz = 48
size_of date time = 12
size_of date time with fixed offset = 16
As you can see, DateTime carrying chrono-tz's TimeZone is a very expansive structure, occupying 48 bytes. This is bad for cache utilization and is expansive when copying the structure around.
Printing the TimeZone in debug mode (i.e. using {:?}
formatter) shows a correct name of the zone but that does not seem like a kosher way of arriving at the names.
I couldn't find another way. Since the Tz
is an enum
, it cannot provide an attribute like .name
(re: #1). Also, providing a .to_string()
(i.e. implementing a Display
trait), is tricky because a time-zone can have several names depending on the context, e.g. both Asia/Kolkata
and IST
can be seen as expected outputs of .to_string()
.
Perhaps the Debug
implementation can be moved to a function get_name
which returns a String
and then implementation of Debug
could be:
impl Debug for Tz {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}", get_name(self))
}
}
What do you think?
Right now I can serialize a DateTime<Tz>
, but I cannot Deserialize it.
serde_json::to_string(&local_time);
produces "2020-05-01T04:45:00MDT"
but
let undo: DateTime<chrono_tz::Tz> =
serde_json::from_str("\"2020-05-01T04:45:00MDT\"").expect("it all to work");
gives a compile error
error[E0277]: the trait bound `chrono::datetime::DateTime<chrono_tz::timezones::Tz>: serde::Deserialize<'_>` is not satisfied
--> src/lib.rs:670:17
|
670 | serde_json::from_str("\"2020-05-01T04:45:00MDT\"").expect("it all to work");
| ^^^^^^^^^^^^^^^^^^^^ the trait `serde::Deserialize<'_>` is not implemented for `chrono::datetime::DateTime<chrono_tz::timezones::Tz>`
|
::: /root/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_json-1.0.45/src/de.rs:2375:8
|
2375 | T: de::Deserialize<'a>,
| ------------------- required by this bound in `serde_json::de::from_str`
|
= help: the following implementations were found:
<chrono::datetime::DateTime<chrono::offset::fixed::FixedOffset> as serde::Deserialize<'de>>
<chrono::datetime::DateTime<chrono::offset::local::Local> as serde::Deserialize<'de>>
<chrono::datetime::DateTime<chrono::offset::utc::Utc> as serde::Deserialize<'de>>
Is there any way for me to keep the Tz
information when passing from server to frontend(WASM) in one value? or do I have to pass the Tz
separate with a NaiveDateTime
?
Consider 06 November, 2011 01:59:59 AM in America/Los_Angeles:
let tz: chrono_tz::Tz = "America/Los_Angeles".parse().unwrap();
let dt = tz.ymd_opt(2011, 11, 6).and_hms_opt(1, 59, 59);
println!("{:?}", dt);
According to time zone information:
After Sunday, 06 November, 2011 01:59:59 AM:
Clocks were moved backward to become Sunday, 06 November, 2011 01:00:00 AM
So 06 November, 2011 01:59:59
is ambiguous, but the output is None
.
Would it make sense to try to add this crate in the https://github.com/chronotope organization?
Some tests are failing after updating the tz submodule to eggert/tz@b61a7ac, because more pre-1970 information was removed. The announcement mentions that you can use make PACKRATDATA=backzone PACKRATLIST=zone.tab
to keep the pre-1970 information, but I am not sure if you want that, or how to replicate this command with the build system.
I want to create a DateTime object from a different Tz, but this doesn't seem possible, or documentation around it seems lacking.
For example, I'd like to be able to do DateTime<GMT>
. Or, at the very least, convert a GMT timestamp such as 1636156740
to a DateTime
object. Is this possible?
fn date_time_example(date: &str) {
let location_date_time = date.to_string();
let vector = location_date_time.split(';').collect::<Vec<&str>>();
let (date, timezone) = (vector[0], vector[1]);
println!("pre date: {}", date);
let date_string = format!("{}", vector[0]);
println!("get_date_time_from : {} - {}", date_string, timezone);
let date_time = NaiveDateTime::parse_from_str(date_string.as_str(),"%FT%X%.3f").unwrap();
let timezone: Tz = timezone.parse().unwrap();
let result = timezone.from_local_datetime(&date_time).unwrap();
println!("{}", result.to_rfc3339());
}
fn main() {
//"2023-04-01T23:00:00.000;America/Santiago"
//"2022-11-06T01:29:00.000;America/Los_Angeles"
let vec = vec![
"2022-11-06T01:29:00.000;America/Los_Angeles"];
for date in vec {
date_time_example(date);
}
}
output:
pre date: 2022-11-06T01:29:00.000
get_date_time_from : 2022-11-06T01:29:00.000 - America/Los_Angeles
thread 'main' panicked at 'Ambiguous local time, ranging from 2022-11-06T01:29:00PDT to 2022-11-06T01:29:00PST', /home/fede/.cargo/registry/src/github
Someone??
IANA databases are provided in two formats, human readable format and machine readable binary format (tzfile). Currently chrono-tz parse time zone from a human readable format. It would be better to parse from a tzfile, so that time zone info can be also loaded from a local tzfile like /etc/localtime
.
Support abbreviated time zones. e.g. BST
, IST
We've been on a forked branch for quite a while, and my colleague opened this PR months ago. #14
If y'all are lacking maintainers for this particular repo, we're happy to sign on and help. We rely on this internally, and would prefer not to continue forking if we find issues or reasonable improvements.
Thanks!
Currently it's just a String
, this is unidiomatic for various reasons:
std::error::Error
, meaning ?
or any kind of error coercion isn't possible (i.e with anyhow)Currently, there does not seem to be a way of iterating over all the time-zones if I wanted to show such a list to users.
Would you mind if I add such a method?
When I use this code to process raw time string
match chrono::naive::NaiveDateTime::parse_from_str(&raw_timestring.trim(),&format{
Err(e)=>(),
Ok(t)=>created_time=Some(GMTPlus1.from_local_datetime(&t).unwrap().with_timezone(&Utc))
}
I found that the GMTPlus1.from_local_datetime(&t).unwrap()
is returning timezone -01
.
So am I misunderstanding doc or there's something wrong with your code?
This makes it so that you can't choose the timezone dynamically based on user input. Why do this? Why isn't an enum over all of them at least provided? Having it like this makes the library unusable for me, and probably many other prospective users.
The following code gives the following output.
let new_year = NaiveDate::from_ymd(2023, 1, 1)
.and_hms(0, 0, 0)
.and_local_timezone(Oslo)
.unwrap();
println!("{}", new_year - Days::new(1));
println!("{}", new_year - Duration::days(1));
2022-12-30 23:00:00 CET
2022-12-31 00:00:00 CET
Is this correct behaviour? This happens for any choice of date and time.
When using Utc or London time, the outputs are equal to each other (expected behaviour in my mind).
Hello,
I find very strange how whenever I try to make a date, whether with Pacific, Central or Eastern (those are the ones I have tried) I get a panic 'invalid time'
Here is my main.rs
and the backtrace output.
I already looked in chrono-0.4.0/src/date.rs:78
but I'm not sure if it's a chrono or a chrono_tz issue.
I'd appreciate any pointer or where to look next. Thanks!
main.rs
extern crate chrono;
extern crate chrono_tz;
use self::chrono::prelude::*;
use self::chrono_tz::US::Central;
fn main() {
let time = Central.ymd(2017, 11, 5).and_hms(1, 0, 0);
print!("{:?}", time);
}
backtrace:
thread 'main' panicked at 'invalid time', src/libcore/option.rs:874:4
stack backtrace:
0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:68
2: std::panicking::default_hook::{{closure}}
at src/libstd/sys_common/backtrace.rs:57
at src/libstd/panicking.rs:381
3: std::panicking::default_hook
at src/libstd/panicking.rs:397
4: std::panicking::begin_panic
at src/libstd/panicking.rs:577
5: std::panicking::begin_panic
at src/libstd/panicking.rs:538
6: std::panicking::try::do_call
at src/libstd/panicking.rs:522
7: std::panicking::try::do_call
at src/libstd/panicking.rs:498
8: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
at src/libcore/panicking.rs:71
9: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
at src/libcore/option.rs:874
10: <core::option::Option<T>>::expect
at /Users/travis/build/rust-lang/rust/src/libcore/option.rs:302
11: <chrono::date::Date<Tz>>::and_hms
at /Users/benj/.cargo/registry/src/github.com-1ecc6299db9ec823/chrono-0.4.0/src/date.rs:78
12: chrono_tz_crash::main
at src/main.rs:8
13: panic_unwind::dwarf::eh::read_encoded_pointer
at src/libpanic_unwind/lib.rs:101
14: rust_panic
at src/libstd/panicking.rs:459
at src/libstd/panic.rs:365
at src/libstd/rt.rs:58
15: chrono_tz_crash::main
println!'s messages like "Finding offset for 1477176398".
Despite being optional in chrono-tz
, the case-insensitive
feature is not disabled in chrono-tz-build
.
chrono-tz-build
unconditionally pulls in uncased
even if chrono-tz
is built without the feature enabled.
Using Tz
in structs makes it impossible to derive Default
since it is not implemented.
Current options I see:
MyTz(Tz)
wrapper and implement Default
for that.chrono-tz
.Would you consider a PR that implements Tz::default()
(would return Tz::UTC
)?
I am getting a fixed offset timezone with the type chrono::FixedOffset
. I also have a timezone based on chrono_tz::Tz
. I am trying to unify these types to reduce code duplication.
Is there a way to have a variable that is a FixedOffset or a Tz? I have tried a couple of things with no real success.
With the goal of keeping the crate's packed tz data up to date, we should consider setting up an automated system that will publish a new version (possibly using the build metadata field instead of incrementing the patch version) whenever the tz repository is updated.
i am willing to work on writing up a job that can make this functional and/or doing the initial manual upkeep.
I'm using chrono-tz to convert from London times to UTC, for which it is great. (Spent several hours googling and was not able to figure out how to do this using just chrono). However, this is the only thing I need to do, it's literally one line in my app. I noticed that adding chrono-tz
to my Cargo.toml
doubled the size of the exe (I'm on Windows).
This is the Cargo.toml
chrono = { version = "0.4", features = ["serde"] }
chrono-tz = "0.5"
encoding = "0.2"
env_logger = "0.7"
log = "0.4"
logging_timer = "0.9.2"
num-traits = "0.2"
num-derive = "0.3"
once_cell = "1.2"
prettytable-rs = "0.8.0"
regex = "1.3"
rust_decimal = "1.1"
EXE size without chrono-tz is 1,121,280 bytes.
WITH chrono-tz and it rises to 2,281,984 bytes.
I haven't delved into how chrono-tz works but this seems like a large hit for one line of code. Is it including the entire TZ database?
It would be nice (and I stress nice, this is obviously by no means a show-stopper issue) to have some way of slimming this down...perhaps by restructuring so that the compiler can do a better job of eliminating unused code, or if it's down to the database perhaps some way of indicating which timezones one is interested in?
To Whom This May Concern:
I am still a pretty newbie Rust dev and trying to implement this to convert a UTC time to PST.
I am following the examples but the timezone modules do not show for me.
I am apparently doing something wrong.
Here is my Cargo.toml entries:
chrono = { version = "0.4.19", default-features = false }
chrono-tz = { version = "0.5.3", default-features = false }
I am "externing" the crates chrono and chrono_tz in my main and also implementing:
use chrono::{TimeZone, UTC};
And when I try to implement chrono_tz::US::Pacific all I get is the ability to do the following:
use chrono_tz::{OffsetComponents, OffsetName};
What the heck am I missing?
TIA,
B
Hey guys, thanks for making such an awesome crate!
I think it would be quite useful to expose the info currently captured in the private FixedTimespan
struct. I recognize this may require some collaboration with the chrono crate maintainers, but the general idea would be to either expose the info as a method invocable either on the DateTime<Tz>
directly or on the Tz
itself (given a UTC datetime / timestamp) that returns the appropriate FixedTimespan
so we can get the detailed daylight time or similar offset as well as the display abbreviation at a point in time.
Attempting with a minimal example fails:
crate init
chrono = "0.4.19"
and chrono-tz = "0.6.1"
to Cargo.toml
dependenciesContents of main.rs:
extern crate chrono;
extern crate chrono_tz;
use chrono::TimeZone;
use chrono_tz::Europe::Brussels;
fn main() {
let now = Brussels::now();
println!("It's now {} in Brussels", now);
}
Attempting a cargo run
or cargo build
results in the following error:
error[E0433]: failed to resolve: use of undeclared type `Brussels`
--> src\main.rs:8:15
|
5 | use chrono_tz::Europe::Brussels;
| --------------------------- help: `Brussels` is defined here, but is not a type
...
8 | let now = Brussels::now();
| ^^^^^^^^ use of undeclared type `Brussels`
Tested both with stable 1.59.0 and nightly 1.61.0.
Did I miss something or did this break in recent versions of Rust?
In the docs, there is a name method.
I was wondering if there was a reason Into
trait for string isn't implemented.
Sadly, the other day, I called into
to convert the Tz
to a String
(or &str
) but got an error.
I missed the name
method because I was looking for the implementation of either the Display
or Into
trait.
Would you like some help with this PR?
copying over from chronotope/chrono#340 opened by @sparky8251
This sample code will help demonstrate the problem:
use chrono::TimeZone;
use chrono::{DateTime, Duration};
use chrono_tz::US::Eastern;
use chrono_tz::Tz;
fn main() {
let mut dt: DateTime<Tz> = Eastern.ymd(2019,11,1).and_hms(0,0,0);
println!("Initial datetime: {}", dt);
// Increment to the day of daylight savings
// but not PAST the daylight savings "border"
dt = dt + Duration::days(3);
println!("Day of daylight savings change: {}", dt);
// Increment past the daylight savings "border"
dt = dt + Duration::hours(3);
println!("After daylight savings change: {}", dt);
}
When run, the output is:
Initial datetime: 2019-11-01 00:00:00 EDT
Day of daylight savings change: 2019-11-03 23:00:00 EST // this is wrong
After daylight savings change: 2019-11-04 02:00:00 EST // this is right but for the wrong reason
At first blush, this seems correct. It is not... US Eastern ends DST this year on 2019-11-3 t 2am, not midnight.
Adding 3 days should not have tripped a DST change causing a loss of time. It should only have changed DST in the 3rd print statement.
I know the rules for start/stop of DST change by timezone and country (sometimes even more granularly, like how 2 states in the US don't respect DST), so I am unsure how to really address this... I just know it will need addressing at some point. I think the TZ support already handles countries, so it's likely down to finding and following the rules presented for each TZ down to the time it changes and not just the day. Hard saying though.
I just upgraded from chrono_tz 0.5.3 to 0.6.0 and in the process, a whole bunch of new dependencies appeared in my Cargo.lock
: chrono-tz-build, phf, phf_codegen, phf_codegen, phf_generator, phf_shared, siphasher and uncased. These seem to be required in 0.6.0 even if I disable the default features. #84 seems to have introduced most of these.
Please consider restructuring things so that this stuff can be disabled. My project really only wants chrono_tz::America::Los_Angeles
, and it would be a pity if pulling in all this other stuff was mandatory.
This feature was removed in #1. While I understand the reason for needing a single type that can dynamically represent different time zones, a project I'm currently working on needs to statically mark a value as being in a specific timezone:
#[derive(Deserialize)]
pub struct Event {
pub start: DateTime<Europe::Berlin>,
pub end: DateTime<Europe::Berlin>,
// and some irrelevant fields ...
}
This is because the timestamps I'm deserializing are not marked with any timezone but the documentation specifies that they are to be interpreted as local times in Germany (and that no DST-ambiguous timestamps occur).
It would be great if this library could support both use-cases.
it would be nice for this project to keep up. do you accept PRs?
This was recently released (https://data.iana.org/time-zones/tzdb/NEWS) and contains at least one important change to time in Mexico effective Oct 30th as well as some consolidation.
I want to believe I'm just missing something obvious here...
use self::chrono::{DateTime, TimeZone};
use self::chrono_tz::{Tz, UTC};
#[derive(Debug)]
enum LineInfo {
TextInfo {
name: String,
value: Option<String>,
},
DateTimeInfo {
name: String,
value: DateTime<UTC>,
}
}
error[E0412]: type name `UTC` is undefined or not in scope
--> src/client/importcli/mod.rs:21:19
|
21 | value: DateTime<UTC>,
| ^^^ undefined or not in scope
|
= help: you can import several candidates into scope (`use ...;`):
= help: `client::importcli::chrono::UTC`
= help: `client::importcli::chrono::offset::utc::UTC`
= help: `client::importcli::chrono::prelude::UTC`
It can be fixed by removing the whitespace from the regexs defined in line.rs
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.